Skip to content

Commit 7d97290

Browse files
committed
save: Fix xmlSave with NULL encoding
Regressed with cc45f61.
1 parent 2a4eb6b commit 7d97290

File tree

2 files changed

+71
-22
lines changed

2 files changed

+71
-22
lines changed

testparser.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,50 @@ testNoBlanks(void) {
288288

289289
return err;
290290
}
291+
292+
static int
293+
testSaveNullEncDoc(const char *xml, const char *expect) {
294+
xmlDocPtr doc;
295+
xmlBufferPtr buffer;
296+
xmlSaveCtxtPtr save;
297+
const xmlChar *result;
298+
int err = 0;
299+
300+
doc = xmlReadDoc(BAD_CAST xml, NULL, NULL, 0);
301+
302+
buffer = xmlBufferCreate();
303+
save = xmlSaveToBuffer(buffer, NULL, 0);
304+
xmlSaveDoc(save, doc);
305+
xmlSaveClose(save);
306+
307+
result = xmlBufferContent(buffer);
308+
if (strcmp((char *) result, expect) != 0) {
309+
fprintf(stderr, "xmlSave with NULL encodíng failed\n");
310+
err = 1;
311+
}
312+
313+
xmlBufferFree(buffer);
314+
xmlFreeDoc(doc);
315+
316+
return err;
317+
}
318+
319+
static int
320+
testSaveNullEnc(void) {
321+
int err = 0;
322+
323+
err |= testSaveNullEncDoc(
324+
"<?xml version=\"1.0\"?><doc>\xC3\x98</doc>",
325+
"<?xml version=\"1.0\"?>\n<doc>&#xD8;</doc>\n");
326+
err |= testSaveNullEncDoc(
327+
"<?xml version=\"1.0\" encoding=\"utf-8\"?><doc>\xC3\x98</doc>",
328+
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<doc>\xC3\x98</doc>\n");
329+
err |= testSaveNullEncDoc(
330+
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><doc>\xD8</doc>",
331+
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<doc>\xD8</doc>\n");
332+
333+
return err;
334+
}
291335
#endif /* LIBXML_OUTPUT_ENABLED */
292336

293337
#ifdef LIBXML_SAX1_ENABLED
@@ -1157,6 +1201,7 @@ main(void) {
11571201
#ifdef LIBXML_OUTPUT_ENABLED
11581202
err |= testCtxtParseContent();
11591203
err |= testNoBlanks();
1204+
err |= testSaveNullEnc();
11601205
#endif
11611206
#ifdef LIBXML_SAX1_ENABLED
11621207
err |= testBalancedChunk();

xmlsave.c

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -778,13 +778,19 @@ static int xmlSaveSwitchEncoding(xmlSaveCtxtPtr ctxt, const char *encoding) {
778778
xmlSaveErr(buf, res, NULL, encoding);
779779
return(-1);
780780
}
781-
buf->conv = xmlBufCreate(4000 /* MINLEN */);
782-
if (buf->conv == NULL) {
783-
xmlCharEncCloseFunc(handler);
784-
xmlSaveErrMemory(buf);
785-
return(-1);
786-
}
787-
buf->encoder = handler;
781+
782+
if (handler != NULL) {
783+
buf->conv = xmlBufCreate(4000 /* MINLEN */);
784+
if (buf->conv == NULL) {
785+
xmlCharEncCloseFunc(handler);
786+
xmlSaveErrMemory(buf);
787+
return(-1);
788+
}
789+
buf->encoder = handler;
790+
}
791+
792+
ctxt->encoding = (const xmlChar *) encoding;
793+
788794
/*
789795
* initialize the state, e.g. if outputting a BOM
790796
*/
@@ -795,11 +801,15 @@ static int xmlSaveSwitchEncoding(xmlSaveCtxtPtr ctxt, const char *encoding) {
795801

796802
static int xmlSaveClearEncoding(xmlSaveCtxtPtr ctxt) {
797803
xmlOutputBufferPtr buf = ctxt->buf;
804+
798805
xmlOutputBufferFlush(buf);
799806
xmlCharEncCloseFunc(buf->encoder);
800807
xmlBufFree(buf->conv);
801808
buf->encoder = NULL;
802809
buf->conv = NULL;
810+
811+
ctxt->encoding = NULL;
812+
803813
return(0);
804814
}
805815

@@ -1342,7 +1352,6 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {
13421352
const xmlChar *oldctxtenc = ctxt->encoding;
13431353
const xmlChar *encoding = ctxt->encoding;
13441354
xmlOutputBufferPtr buf = ctxt->buf;
1345-
xmlCharEncoding enc;
13461355
int switched_encoding = 0;
13471356

13481357
xmlInitParser();
@@ -1370,36 +1379,31 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {
13701379
if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
13711380
return(-1);
13721381
}
1382+
switched_encoding = 1;
13731383
}
13741384
if (ctxt->options & XML_SAVE_FORMAT)
13751385
htmlDocContentDumpFormatOutput(buf, cur,
13761386
(const char *)encoding, 1);
13771387
else
13781388
htmlDocContentDumpFormatOutput(buf, cur,
13791389
(const char *)encoding, 0);
1380-
return(0);
13811390
#else
13821391
return(-1);
13831392
#endif
13841393
} else if ((cur->type == XML_DOCUMENT_NODE) ||
13851394
(ctxt->options & XML_SAVE_AS_XML) ||
13861395
(ctxt->options & XML_SAVE_XHTML)) {
1387-
enc = xmlParseCharEncoding((const char*) encoding);
13881396
if ((encoding != NULL) && (oldctxtenc == NULL) &&
13891397
(buf->encoder == NULL) && (buf->conv == NULL) &&
13901398
((ctxt->options & XML_SAVE_NO_DECL) == 0)) {
1391-
if ((enc != XML_CHAR_ENCODING_UTF8) &&
1392-
(enc != XML_CHAR_ENCODING_NONE) &&
1393-
(enc != XML_CHAR_ENCODING_ASCII)) {
1394-
/*
1395-
* we need to switch to this encoding but just for this
1396-
* document since we output the XMLDecl the conversion
1397-
* must be done to not generate not well formed documents.
1398-
*/
1399-
if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0)
1400-
return(-1);
1401-
switched_encoding = 1;
1402-
}
1399+
/*
1400+
* we need to switch to this encoding but just for this
1401+
* document since we output the XMLDecl the conversion
1402+
* must be done to not generate not well formed documents.
1403+
*/
1404+
if (xmlSaveSwitchEncoding(ctxt, (const char *) encoding) < 0)
1405+
return(-1);
1406+
switched_encoding = 1;
14031407
}
14041408

14051409

0 commit comments

Comments
 (0)