|
@@ -142,7 +142,7 @@ static char *print_number(cJSON *item)
|
|
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
|
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
|
static const char *parse_string(cJSON *item,const char *str)
|
|
static const char *parse_string(cJSON *item,const char *str)
|
|
{
|
|
{
|
|
- const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc;
|
|
|
|
|
|
+ const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
|
|
if (*str!='\"') {ep=str;return 0;} /* not a string! */
|
|
if (*str!='\"') {ep=str;return 0;} /* not a string! */
|
|
|
|
|
|
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
|
|
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
|
|
@@ -164,16 +164,28 @@ static const char *parse_string(cJSON *item,const char *str)
|
|
case 'n': *ptr2++='\n'; break;
|
|
case 'n': *ptr2++='\n'; break;
|
|
case 'r': *ptr2++='\r'; break;
|
|
case 'r': *ptr2++='\r'; break;
|
|
case 't': *ptr2++='\t'; break;
|
|
case 't': *ptr2++='\t'; break;
|
|
- case 'u': /* transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY. */
|
|
|
|
- sscanf(ptr+1,"%4x",&uc); /* get the unicode char. */
|
|
|
|
- len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len;
|
|
|
|
|
|
+ case 'u': /* transcode utf16 to utf8. */
|
|
|
|
+ sscanf(ptr+1,"%4x",&uc);ptr+=4; /* get the unicode char. */
|
|
|
|
+
|
|
|
|
+ if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; // check for invalid.
|
|
|
|
+
|
|
|
|
+ if (uc>=0xD800 && uc<=0xDBFF) // UTF16 surrogate pairs.
|
|
|
|
+ {
|
|
|
|
+ if (ptr[1]!='\\' || ptr[2]!='u') break; // missing second-half of surrogate.
|
|
|
|
+ sscanf(ptr+3,"%4x",&uc2);ptr+=6;
|
|
|
|
+ if (uc2<0xDC00 || uc2>0xDFFF) break; // invalid second-half of surrogate.
|
|
|
|
+ uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
|
|
|
|
|
|
switch (len) {
|
|
switch (len) {
|
|
|
|
+ case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
|
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
|
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
|
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
|
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
|
case 1: *--ptr2 =(uc | firstByteMark[len]);
|
|
case 1: *--ptr2 =(uc | firstByteMark[len]);
|
|
}
|
|
}
|
|
- ptr2+=len;ptr+=4;
|
|
|
|
|
|
+ ptr2+=len;
|
|
break;
|
|
break;
|
|
default: *ptr2++=*ptr; break;
|
|
default: *ptr2++=*ptr; break;
|
|
}
|
|
}
|