summaryrefslogtreecommitdiff
path: root/encoding.c
diff options
context:
space:
mode:
Diffstat (limited to 'encoding.c')
-rw-r--r--encoding.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/encoding.c b/encoding.c
index 5e50c153..5d28e4f1 100644
--- a/encoding.c
+++ b/encoding.c
@@ -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++;