~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to gd/gdkanji.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* gdkanji.c (Kanji code converter)                            */
 
3
/*                 written by Masahito Yamaga (ma@yama-ga.com) */
 
4
 
 
5
#include <stdio.h>
 
6
#include <stdlib.h>
 
7
#include <string.h>
 
8
#include "gd.h"
 
9
#include "gdhelpers.h"
 
10
 
 
11
#include <stdarg.h>
 
12
#if defined(HAVE_ICONV_H) || defined(HAVE_ICONV)
 
13
#include <iconv.h>
 
14
#ifdef HAVE_ERRNO_H
 
15
#include <errno.h>
 
16
#endif
 
17
#endif
 
18
 
 
19
#if defined(HAVE_ICONV_H) && !defined(HAVE_ICONV)
 
20
#define HAVE_ICONV 1
 
21
#endif
 
22
 
 
23
#define LIBNAME "any2eucjp()"
 
24
 
 
25
#if defined(__MSC__) || defined(__BORLANDC__) || defined(__TURBOC__) || defined(_Windows) || defined(MSDOS)
 
26
#ifndef SJISPRE
 
27
#define SJISPRE 1
 
28
#endif
 
29
#endif
 
30
 
 
31
#ifdef TRUE
 
32
#undef TRUE
 
33
#endif
 
34
#ifdef FALSE
 
35
#undef FALSE
 
36
#endif
 
37
 
 
38
#define TRUE  1
 
39
#define FALSE 0
 
40
 
 
41
#define NEW 1
 
42
#define OLD 2
 
43
#define ESCI 3
 
44
#define NEC 4
 
45
#define EUC 5
 
46
#define SJIS 6
 
47
#define EUCORSJIS 7
 
48
#define ASCII 8
 
49
 
 
50
#define NEWJISSTR "JIS7"
 
51
#define OLDJISSTR "jis"
 
52
#define EUCSTR    "eucJP"
 
53
#define SJISSTR   "SJIS"
 
54
 
 
55
#define ESC 27
 
56
#define SS2 142
 
57
 
 
58
static void
 
59
debug (const char *format,...)
 
60
{
 
61
#ifdef DEBUG
 
62
  va_list args;
 
63
 
 
64
  va_start (args, format);
 
65
  fprintf (stdout, "%s: ", LIBNAME);
 
66
  vfprintf (stdout, format, args);
 
67
  fprintf (stdout, "\n");
 
68
  va_end (args);
 
69
#endif
 
70
}
 
71
 
 
72
static void
 
73
error (const char *format,...)
 
74
{
 
75
  va_list args;
 
76
 
 
77
  va_start (args, format);
 
78
  fprintf (stderr, "%s: ", LIBNAME);
 
79
  vfprintf (stderr, format, args);
 
80
  fprintf (stderr, "\n");
 
81
  va_end (args);
 
82
}
 
83
 
 
84
/* DetectKanjiCode() derived from DetectCodeType() by Ken Lunde. */
 
85
 
 
86
static int
 
87
DetectKanjiCode (unsigned char *str)
 
88
{
 
89
  static int whatcode = ASCII;
 
90
  int oldcode = ASCII;
 
91
  int c, i;
 
92
  char *lang = NULL;
 
93
 
 
94
  c = '\1';
 
95
  i = 0;
 
96
 
 
97
  if (whatcode != EUCORSJIS && whatcode != ASCII)
 
98
    {
 
99
      oldcode = whatcode;
 
100
      whatcode = ASCII;
 
101
    }
 
102
 
 
103
  while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0')
 
104
    {
 
105
      if ((c = str[i++]) != '\0')
 
106
        {
 
107
          if (c == ESC)
 
108
            {
 
109
              c = str[i++];
 
110
              if (c == '$')
 
111
                {
 
112
                  c = str[i++];
 
113
                  if (c == 'B')
 
114
                    whatcode = NEW;
 
115
                  else if (c == '@')
 
116
                    whatcode = OLD;
 
117
                }
 
118
              else if (c == '(')
 
119
                {
 
120
                  c = str[i++];
 
121
                  if (c == 'I')
 
122
                    whatcode = ESCI;
 
123
                }
 
124
              else if (c == 'K')
 
125
                whatcode = NEC;
 
126
            }
 
127
          else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159))
 
128
            whatcode = SJIS;
 
129
          else if (c == SS2)
 
130
            {
 
131
              c = str[i++];
 
132
              if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252))
 
133
                whatcode = SJIS;
 
134
              else if (c >= 161 && c <= 223)
 
135
                whatcode = EUCORSJIS;
 
136
            }
 
137
          else if (c >= 161 && c <= 223)
 
138
            {
 
139
              c = str[i++];
 
140
              if (c >= 240 && c <= 254)
 
141
                whatcode = EUC;
 
142
              else if (c >= 161 && c <= 223)
 
143
                whatcode = EUCORSJIS;
 
144
              else if (c >= 224 && c <= 239)
 
145
                {
 
146
                  whatcode = EUCORSJIS;
 
147
                  while (c >= 64 && c != '\0' && whatcode == EUCORSJIS)
 
148
                    {
 
149
                      if (c >= 129)
 
150
                        {
 
151
                          if (c <= 141 || (c >= 143 && c <= 159))
 
152
                            whatcode = SJIS;
 
153
                          else if (c >= 253 && c <= 254)
 
154
                            whatcode = EUC;
 
155
                        }
 
156
                      c = str[i++];
 
157
                    }
 
158
                }
 
159
              else if (c <= 159)
 
160
                whatcode = SJIS;
 
161
            }
 
162
          else if (c >= 240 && c <= 254)
 
163
            whatcode = EUC;
 
164
          else if (c >= 224 && c <= 239)
 
165
            {
 
166
              c = str[i++];
 
167
              if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160))
 
168
                whatcode = SJIS;
 
169
              else if (c >= 253 && c <= 254)
 
170
                whatcode = EUC;
 
171
              else if (c >= 161 && c <= 252)
 
172
                whatcode = EUCORSJIS;
 
173
            }
 
174
        }
 
175
    }
 
176
 
 
177
#ifdef DEBUG
 
178
  if (whatcode == ASCII)
 
179
    debug ("Kanji code not included.");
 
180
  else if (whatcode == EUCORSJIS)
 
181
    debug ("Kanji code not detected.");
 
182
  else
 
183
    debug ("Kanji code detected at %d byte.", i);
 
184
#endif
 
185
 
 
186
  if (whatcode == EUCORSJIS && oldcode != ASCII)
 
187
    whatcode = oldcode;
 
188
 
 
189
  if (whatcode == EUCORSJIS)
 
190
    {
 
191
      if (getenv ("LC_ALL"))
 
192
        lang = getenv ("LC_ALL");
 
193
      else if (getenv ("LC_CTYPE"))
 
194
        lang = getenv ("LC_CTYPE");
 
195
      else if (getenv ("LANG"))
 
196
        lang = getenv ("LANG");
 
197
 
 
198
      if (lang)
 
199
        {
 
200
          if (strcmp (lang, "ja_JP.SJIS") == 0 ||
 
201
#ifdef hpux
 
202
              strcmp (lang, "japanese") == 0 ||
 
203
#endif
 
204
              strcmp (lang, "ja_JP.mscode") == 0 ||
 
205
              strcmp (lang, "ja_JP.PCK") == 0)
 
206
            whatcode = SJIS;
 
207
          else if (strncmp (lang, "ja", 2) == 0)
 
208
#ifdef SJISPRE
 
209
            whatcode = SJIS;
 
210
#else
 
211
            whatcode = EUC;
 
212
#endif
 
213
        }
 
214
    }
 
215
 
 
216
  if (whatcode == EUCORSJIS)
 
217
#ifdef SJISPRE
 
218
    whatcode = SJIS;
 
219
#else
 
220
    whatcode = EUC;
 
221
#endif
 
222
 
 
223
  return whatcode;
 
224
}
 
225
 
 
226
/* SJIStoJIS() is sjis2jis() by Ken Lunde. */
 
227
 
 
228
static void
 
229
SJIStoJIS (int *p1, int *p2)
 
230
{
 
231
  register unsigned char c1 = *p1;
 
232
  register unsigned char c2 = *p2;
 
233
  register int adjust = c2 < 159;
 
234
  register int rowOffset = c1 < 160 ? 112 : 176;
 
235
  register int cellOffset = adjust ? (31 + (c2 > 127)) : 126;
 
236
 
 
237
  *p1 = ((c1 - rowOffset) << 1) - adjust;
 
238
  *p2 -= cellOffset;
 
239
}
 
240
 
 
241
/* han2zen() was derived from han2zen() written by Ken Lunde. */
 
242
 
 
243
#define IS_DAKU(c) ((c >= 182 && c <= 196) || (c >= 202 && c <= 206) || (c == 179))
 
244
#define IS_HANDAKU(c) (c >= 202 && c <= 206)
 
245
 
 
246
static void
 
247
han2zen (int *p1, int *p2)
 
248
{
 
249
  int c = *p1;
 
250
  int daku = FALSE;
 
251
  int handaku = FALSE;
 
252
  int mtable[][2] =
 
253
  {
 
254
    {129, 66},
 
255
    {129, 117},
 
256
    {129, 118},
 
257
    {129, 65},
 
258
    {129, 69},
 
259
    {131, 146},
 
260
    {131, 64},
 
261
    {131, 66},
 
262
    {131, 68},
 
263
    {131, 70},
 
264
    {131, 72},
 
265
    {131, 131},
 
266
    {131, 133},
 
267
    {131, 135},
 
268
    {131, 98},
 
269
    {129, 91},
 
270
    {131, 65},
 
271
    {131, 67},
 
272
    {131, 69},
 
273
    {131, 71},
 
274
    {131, 73},
 
275
    {131, 74},
 
276
    {131, 76},
 
277
    {131, 78},
 
278
    {131, 80},
 
279
    {131, 82},
 
280
    {131, 84},
 
281
    {131, 86},
 
282
    {131, 88},
 
283
    {131, 90},
 
284
    {131, 92},
 
285
    {131, 94},
 
286
    {131, 96},
 
287
    {131, 99},
 
288
    {131, 101},
 
289
    {131, 103},
 
290
    {131, 105},
 
291
    {131, 106},
 
292
    {131, 107},
 
293
    {131, 108},
 
294
    {131, 109},
 
295
    {131, 110},
 
296
    {131, 113},
 
297
    {131, 116},
 
298
    {131, 119},
 
299
    {131, 122},
 
300
    {131, 125},
 
301
    {131, 126},
 
302
    {131, 128},
 
303
    {131, 129},
 
304
    {131, 130},
 
305
    {131, 132},
 
306
    {131, 134},
 
307
    {131, 136},
 
308
    {131, 137},
 
309
    {131, 138},
 
310
    {131, 139},
 
311
    {131, 140},
 
312
    {131, 141},
 
313
    {131, 143},
 
314
    {131, 147},
 
315
    {129, 74},
 
316
    {129, 75}
 
317
  };
 
318
 
 
319
  if (*p2 == 222 && IS_DAKU (*p1))
 
320
    daku = TRUE;                /* Daku-ten */
 
321
  else if (*p2 == 223 && IS_HANDAKU (*p1))
 
322
    handaku = TRUE;             /* Han-daku-ten */
 
323
 
 
324
  *p1 = mtable[c - 161][0];
 
325
  *p2 = mtable[c - 161][1];
 
326
 
 
327
  if (daku)
 
328
    {
 
329
      if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122))
 
330
        (*p2)++;
 
331
      else if (*p2 == 131 && *p2 == 69)
 
332
        *p2 = 148;
 
333
    }
 
334
  else if (handaku && *p2 >= 110 && *p2 <= 122)
 
335
    (*p2) += 2;
 
336
}
 
337
 
 
338
/* Recast strcpy to handle unsigned chars used below. */
 
339
#define ustrcpy(A,B) (strcpy((char*)(A),(const char*)(B)))
 
340
 
 
341
static void
 
342
do_convert (unsigned char *to, unsigned char *from, const char *code)
 
343
{
 
344
#ifdef HAVE_ICONV
 
345
  iconv_t cd;
 
346
  size_t from_len, to_len;
 
347
 
 
348
  if ((cd = iconv_open (EUCSTR, code)) == (iconv_t) - 1)
 
349
    {
 
350
      error ("iconv_open() error");
 
351
#ifdef HAVE_ERRNO_H
 
352
      if (errno == EINVAL)
 
353
        error ("invalid code specification: \"%s\" or \"%s\"",
 
354
               EUCSTR, code);
 
355
#endif
 
356
      strcpy ((char *) to, (const char *) from);
 
357
      return;
 
358
    }
 
359
 
 
360
  from_len = strlen ((const char *) from) + 1;
 
361
  to_len = BUFSIZ;
 
362
 
 
363
  if (iconv (cd, (const char **) &from, &from_len,
 
364
             (char **) &to, &to_len) == -1)
 
365
    {
 
366
#ifdef HAVE_ERRNO_H
 
367
      if (errno == EINVAL)
 
368
        error ("invalid end of input string");
 
369
      else if (errno == EILSEQ)
 
370
        error ("invalid code in input string");
 
371
      else if (errno == E2BIG)
 
372
        error ("output buffer overflow at do_convert()");
 
373
      else
 
374
#endif
 
375
        error ("something happen");
 
376
      strcpy ((char *) to, (const char *) from);
 
377
      return;
 
378
    }
 
379
 
 
380
  if (iconv_close (cd) != 0)
 
381
    {
 
382
      error ("iconv_close() error");
 
383
    }
 
384
#else
 
385
  int p1, p2, i, j;
 
386
  int jisx0208 = FALSE;
 
387
  int hankaku = FALSE;
 
388
 
 
389
  j = 0;
 
390
  if (strcmp (code, NEWJISSTR) == 0 || strcmp (code, OLDJISSTR) == 0)
 
391
    {
 
392
      for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
 
393
        {
 
394
          if (from[i] == ESC)
 
395
            {
 
396
              i++;
 
397
              if (from[i] == '$')
 
398
                {
 
399
                  jisx0208 = TRUE;
 
400
                  hankaku = FALSE;
 
401
                  i++;
 
402
                }
 
403
              else if (from[i] == '(')
 
404
                {
 
405
                  jisx0208 = FALSE;
 
406
                  i++;
 
407
                  if (from[i] == 'I')   /* Hankaku Kana */
 
408
                    hankaku = TRUE;
 
409
                  else
 
410
                    hankaku = FALSE;
 
411
                }
 
412
            }
 
413
          else
 
414
            {
 
415
              if (jisx0208)
 
416
                to[j++] = from[i] + 128;
 
417
              else if (hankaku)
 
418
                {
 
419
                  to[j++] = SS2;
 
420
                  to[j++] = from[i] + 128;
 
421
                }
 
422
              else
 
423
                to[j++] = from[i];
 
424
            }
 
425
        }
 
426
    }
 
427
  else if (strcmp (code, SJISSTR) == 0)
 
428
    {
 
429
      for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
 
430
        {
 
431
          p1 = from[i];
 
432
          if (p1 < 127)
 
433
            to[j++] = p1;
 
434
          else if ((p1 >= 161) && (p1 <= 223))
 
435
            {                   /* Hankaku Kana */
 
436
              to[j++] = SS2;
 
437
              to[j++] = p1;
 
438
            }
 
439
          else
 
440
            {
 
441
              p2 = from[++i];
 
442
              SJIStoJIS (&p1, &p2);
 
443
              to[j++] = p1 + 128;
 
444
              to[j++] = p2 + 128;
 
445
            }
 
446
        }
 
447
    }
 
448
  else
 
449
    {
 
450
      error ("invalid code specification: \"%s\"", code);
 
451
      return;
 
452
    }
 
453
 
 
454
  if (j >= BUFSIZ)
 
455
    {
 
456
      error ("output buffer overflow at do_convert()");
 
457
      ustrcpy (to, from);
 
458
    }
 
459
  else
 
460
    to[j] = '\0';
 
461
#endif /* HAVE_ICONV */
 
462
}
 
463
 
 
464
static int
 
465
do_check_and_conv (unsigned char *to, unsigned char *from)
 
466
{
 
467
  static unsigned char tmp[BUFSIZ];
 
468
  int p1, p2, i, j;
 
469
  int kanji = TRUE;
 
470
 
 
471
  switch (DetectKanjiCode (from))
 
472
    {
 
473
    case NEW:
 
474
      debug ("Kanji code is New JIS.");
 
475
      do_convert (tmp, from, NEWJISSTR);
 
476
      break;
 
477
    case OLD:
 
478
      debug ("Kanji code is Old JIS.");
 
479
      do_convert (tmp, from, OLDJISSTR);
 
480
      break;
 
481
    case ESCI:
 
482
      debug ("This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I.");
 
483
      do_convert (tmp, from, NEWJISSTR);
 
484
      break;
 
485
    case NEC:
 
486
      debug ("Kanji code is NEC Kanji.");
 
487
      error ("cannot convert NEC Kanji.");
 
488
      ustrcpy (tmp, from);
 
489
      kanji = FALSE;
 
490
      break;
 
491
    case EUC:
 
492
      debug ("Kanji code is EUC.");
 
493
      ustrcpy (tmp, from);
 
494
      break;
 
495
    case SJIS:
 
496
      debug ("Kanji code is SJIS.");
 
497
      do_convert (tmp, from, SJISSTR);
 
498
      break;
 
499
    case EUCORSJIS:
 
500
      debug ("Kanji code is EUC or SJIS.");
 
501
      ustrcpy (tmp, from);
 
502
      kanji = FALSE;
 
503
      break;
 
504
    case ASCII:
 
505
      debug ("This is ASCII string.");
 
506
      ustrcpy (tmp, from);
 
507
      kanji = FALSE;
 
508
      break;
 
509
    default:
 
510
      debug ("This string includes unknown code.");
 
511
      ustrcpy (tmp, from);
 
512
      kanji = FALSE;
 
513
      break;
 
514
    }
 
515
 
 
516
  /* Hankaku Kana ---> Zenkaku Kana */
 
517
  if (kanji)
 
518
    {
 
519
      j = 0;
 
520
      for (i = 0; tmp[i] != '\0' && j < BUFSIZ; i++)
 
521
        {
 
522
          if (tmp[i] == SS2)
 
523
            {
 
524
              p1 = tmp[++i];
 
525
              if (tmp[i + 1] == SS2)
 
526
                {
 
527
                  p2 = tmp[i + 2];
 
528
                  if (p2 == 222 || p2 == 223)
 
529
                    i += 2;
 
530
                  else
 
531
                    p2 = 0;
 
532
                }
 
533
              else
 
534
                p2 = 0;
 
535
              han2zen (&p1, &p2);
 
536
              SJIStoJIS (&p1, &p2);
 
537
              to[j++] = p1 + 128;
 
538
              to[j++] = p2 + 128;
 
539
            }
 
540
          else
 
541
            to[j++] = tmp[i];
 
542
        }
 
543
 
 
544
      if (j >= BUFSIZ)
 
545
        {
 
546
          error ("output buffer overflow at Hankaku --> Zenkaku");
 
547
          ustrcpy (to, tmp);
 
548
        }
 
549
      else
 
550
        to[j] = '\0';
 
551
    }
 
552
  else
 
553
    ustrcpy (to, tmp);
 
554
 
 
555
  return kanji;
 
556
}
 
557
 
 
558
int
 
559
any2eucjp (unsigned char *dest, unsigned char *src, unsigned int dest_max)
 
560
{
 
561
  static unsigned char tmp_dest[BUFSIZ];
 
562
  int ret;
 
563
 
 
564
  if (strlen ((const char *) src) >= BUFSIZ)
 
565
    {
 
566
      error ("input string too large");
 
567
      return -1;
 
568
    }
 
569
  if (dest_max > BUFSIZ)
 
570
    {
 
571
      error ("invalid maximum size of destination\nit should be less than %d.", BUFSIZ);
 
572
      return -1;
 
573
    }
 
574
  ret = do_check_and_conv (tmp_dest, src);
 
575
  if (strlen ((const char *) tmp_dest) >= dest_max)
 
576
    {
 
577
      error ("output buffer overflow");
 
578
      ustrcpy (dest, src);
 
579
      return -1;
 
580
    }
 
581
  ustrcpy (dest, tmp_dest);
 
582
  return ret;
 
583
}
 
584
 
 
585
#if 0
 
586
unsigned int
 
587
strwidth (unsigned char *s)
 
588
{
 
589
  unsigned char *t;
 
590
  unsigned int i;
 
591
 
 
592
  t = (unsigned char *) gdMalloc (BUFSIZ);
 
593
  any2eucjp (t, s, BUFSIZ);
 
594
  i = strlen (t);
 
595
  gdFree (t);
 
596
  return i;
 
597
}
 
598
 
 
599
#ifdef DEBUG
 
600
int
 
601
main ()
 
602
{
 
603
  unsigned char input[BUFSIZ];
 
604
  unsigned char *output;
 
605
  unsigned char *str;
 
606
  int c, i = 0;
 
607
 
 
608
  while ((c = fgetc (stdin)) != '\n' && i < BUFSIZ)
 
609
    input[i++] = c;
 
610
  input[i] = '\0';
 
611
 
 
612
  printf ("input : %d bytes\n", strlen ((const char *) input));
 
613
  printf ("output: %d bytes\n", strwidth (input));
 
614
 
 
615
  output = (unsigned char *) gdMalloc (BUFSIZ);
 
616
  any2eucjp (output, input, BUFSIZ);
 
617
  str = output;
 
618
  while (*str != '\0')
 
619
    putchar (*(str++));
 
620
  putchar ('\n');
 
621
  gdFree (output);
 
622
 
 
623
  return 0;
 
624
}
 
625
#endif
 
626
#endif