diff options
Diffstat (limited to 'encoding.c')
-rw-r--r-- | encoding.c | 23 |
1 files changed, 12 insertions, 11 deletions
@@ -527,7 +527,7 @@ UTF16LEToUTF8(unsigned char* out, int *outlen, in++; } if ((c & 0xFC00) == 0xD800) { /* surrogates */ - if (in >= inend) { /* (in > inend) shouldn't happens */ + if (in >= inend) { /* handle split mutli-byte characters */ break; } if (xmlLittleEndian) { @@ -744,38 +744,39 @@ UTF16BEToUTF8(unsigned char* out, int *outlen, { unsigned char* outstart = out; const unsigned char* processed = inb; - unsigned char* outend = out + *outlen; + unsigned char* outend; unsigned short* in = (unsigned short*) inb; unsigned short* inend; unsigned int c, d, inlen; unsigned char *tmp; int bits; + if (*outlen == 0) { + *inlenb = 0; + return(0); + } + outend = out + *outlen; if ((*inlenb % 2) == 1) (*inlenb)--; inlen = *inlenb / 2; inend= in + inlen; - while (in < inend) { + while ((in < inend) && (out - outstart + 5 < *outlen)) { if (xmlLittleEndian) { tmp = (unsigned char *) in; c = *tmp++; - c = c << 8; - c = c | (unsigned int) *tmp; + c = (c << 8) | (unsigned int) *tmp; in++; } else { c= *in++; } if ((c & 0xFC00) == 0xD800) { /* surrogates */ - if (in >= inend) { /* (in > inend) shouldn't happens */ - *outlen = out - outstart; - *inlenb = processed - inb; - return(-2); + if (in >= inend) { /* handle split mutli-byte characters */ + break; } if (xmlLittleEndian) { tmp = (unsigned char *) in; d = *tmp++; - d = d << 8; - d = d | (unsigned int) *tmp; + d = (d << 8) | (unsigned int) *tmp; in++; } else { d= *in++; |