diff --git a/encoding.c b/encoding.c index aa516ede..bc2772da 100644 --- a/encoding.c +++ b/encoding.c @@ -1989,9 +1989,22 @@ xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out, int ret; if (handler->input != NULL) { + int oldinlen = *inlen; + ret = handler->input(out, outlen, in, inlen); - if (ret > 0) - ret = XML_ENC_ERR_SUCCESS; + if (ret >= 0) { + /* + * The built-in converters don't signal XML_ENC_ERR_SPACE. + */ + if (*inlen < oldinlen) { + if (*outlen > 0) + ret = XML_ENC_ERR_SPACE; + else + ret = XML_ENC_ERR_PARTIAL; + } else { + ret = XML_ENC_ERR_SUCCESS; + } + } } #ifdef LIBXML_ICONV_ENABLED else if (handler->iconv_in != NULL) { @@ -2036,9 +2049,22 @@ xmlEncOutputChunk(xmlCharEncodingHandler *handler, unsigned char *out, int ret; if (handler->output != NULL) { + int oldinlen = *inlen; + ret = handler->output(out, outlen, in, inlen); - if (ret > 0) - ret = XML_ENC_ERR_SUCCESS; + if (ret >= 0) { + /* + * The built-in converters don't signal XML_ENC_ERR_SPACE. + */ + if (*inlen < oldinlen) { + if (*outlen > 0) + ret = XML_ENC_ERR_SPACE; + else + ret = XML_ENC_ERR_PARTIAL; + } else { + ret = XML_ENC_ERR_SUCCESS; + } + } } #ifdef LIBXML_ICONV_ENABLED else if (handler->iconv_out != NULL) { diff --git a/testparser.c b/testparser.c index 9b956017..625ba100 100644 --- a/testparser.c +++ b/testparser.c @@ -30,6 +30,40 @@ testHugePush(void) { return err; } + +static int +testHugeEncodedChunk(void) { + xmlBufferPtr buf; + xmlChar *chunk; + xmlParserCtxtPtr ctxt; + int err, i; + + /* + * Test the push parser with a built-in encoding handler like ISO-8859-1 + * and a chunk larger than the initial decoded buffer (currently 4 KB). + */ + buf = xmlBufferCreate(); + xmlBufferCat(buf, + BAD_CAST "\n"); + xmlBufferCat(buf, BAD_CAST ""); + chunk = xmlBufferDetach(buf); + xmlBufferFree(buf); + + ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); + + xmlParseChunk(ctxt, (char *) chunk, xmlStrlen(chunk), 0); + xmlParseChunk(ctxt, NULL, 0, 1); + + err = ctxt->wellFormed ? 0 : 1; + xmlFreeDoc(ctxt->myDoc); + xmlFreeParserCtxt(ctxt); + xmlFree(chunk); + + return err; +} #endif int @@ -38,6 +72,7 @@ main(void) { #ifdef LIBXML_PUSH_ENABLED err |= testHugePush(); + err |= testHugeEncodedChunk(); #endif return err;