changeset 11087:05091c173f76

Add support for the GB18030 encoding.
author Bruno Haible <bruno@clisp.org>
date Sun, 25 Jan 2009 22:39:28 +0100
parents 77f9dee073d2
children c8d99e7b214a
files ChangeLog lib/mbrtowc.c
diffstat 2 files changed, 47 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-01-25  Bruno Haible  <bruno@clisp.org>
+
+	* 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.
+
 2009-01-25  Bruno Haible  <bruno@clisp.org>
 
 	Avoid redefining 'struct random_data' on OSF/1 5.1.
--- a/lib/mbrtowc.c
+++ b/lib/mbrtowc.c
@@ -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 <bruno@clisp.org>, 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 ();
       }