bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

mbrtowc: support GB18030 locales


From: Bruno Haible
Subject: mbrtowc: support GB18030 locales
Date: Sun, 25 Jan 2009 22:42:39 +0100
User-agent: KMail/1.9.9

On OSF/1 5.1, in the zh_CN.GB18030 locale, the test-mbsstr3.sh test fails.
The reason is that
  1) lib/mbrtowc.c has no particular code for the GB18030 encoding,
  2) for an unknown encoding, it runs into an abort().

This fixes it.


2009-01-25  Bruno Haible  <address@hidden>

        * lib/mbrtowc.c (mbrtowc): Distinguish invalid and incomplete
        multibyte characters also for the GB18030 encoding. Don't crash when
        the encoding is unknown and nstate = 0. Needed on OSF/1 5.1.

--- lib/mbrtowc.c.orig  2009-01-25 22:37:05.000000000 +0100
+++ lib/mbrtowc.c       2009-01-25 22:21:51.000000000 +0100
@@ -1,5 +1,5 @@
 /* Convert multibyte character to wide character.
-   Copyright (C) 1999-2002, 2005-2008 Free Software Foundation, Inc.
+   Copyright (C) 1999-2002, 2005-2009 Free Software Foundation, Inc.
    Written by Bruno Haible <address@hidden>, 2008.
 
    This program is free software: you can redistribute it and/or modify
@@ -118,7 +118,7 @@
         lack mbrtowc(), we use the second approach.
         The possible encodings are:
           - 8-bit encodings,
-          - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, SJIS,
+          - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS,
           - UTF-8.
         Use specialized code for each.  */
       if (m >= 4 || m >= MB_CUR_MAX)
@@ -238,6 +238,39 @@
              }
            goto invalid;
          }
+       if (STREQ (encoding, "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 
0))
+         {
+           if (m == 1)
+             {
+               unsigned char c = (unsigned char) p[0];
+
+               if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe))
+                 goto incomplete;
+             }
+           else /* m == 2 || m == 3 */
+             {
+               unsigned char c = (unsigned char) p[0];
+
+               if (c >= 0x90 && c <= 0xe3)
+                 {
+                   unsigned char c2 = (unsigned char) p[1];
+
+                   if (c2 >= 0x30 && c2 <= 0x39)
+                     {
+                       if (m == 2)
+                         goto incomplete;
+                       else /* m == 3 */
+                         {
+                           unsigned char c3 = (unsigned char) p[2];
+
+                           if (c3 >= 0x81 && c3 <= 0xfe)
+                             goto incomplete;
+                         }
+                     }
+                 }
+             }
+           goto invalid;
+         }
        if (STREQ (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0))
          {
            if (m == 1)
@@ -258,10 +291,14 @@
      incomplete:
       {
        size_t k = nstate;
-       /* Here 0 < k < m < 4.  */
+       /* Here 0 <= k < m < 4.  */
        pstate[++k] = s[0];
        if (k < m)
-         pstate[++k] = s[1];
+         {
+           pstate[++k] = s[1];
+           if (k < m)
+             pstate[++k] = s[2];
+         }
        if (k != m)
          abort ();
       }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]