mirror of
https://github.com/darlinghq/darling-libxml2.git
synced 2025-02-28 22:48:10 +00:00
Borland C fix from Moritz Both regenerate, workaround a problem for buffer
* trionan.c: Borland C fix from Moritz Both * testapi.c: regenerate, workaround a problem for buffer testing * xmlIO.c HTMLtree.c: new internal entry point to hide even better xmlAllocOutputBufferInternal * tree.c: harden the code around buffer allocation schemes * parser.c: restore the warning when namespace names are not absolute URIs * runxmlconf.c: continue regression tests if we get the expected number of errors * Makefile.am: run the python tests on make check * xmlsave.c: handle the HTML documents and trees * python/libxml.c: convert python serialization to the xmlSave APIs and avoid some horrible hacks Daniel svn path=/trunk/; revision=3790
This commit is contained in:
parent
1572425c27
commit
da3fee406d
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
||||
Mon Sep 1 15:02:05 CEST 2008 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* trionan.c: Borland C fix from Moritz Both
|
||||
* testapi.c: regenerate, workaround a problem for buffer testing
|
||||
* xmlIO.c HTMLtree.c: new internal entry point to hide even better
|
||||
xmlAllocOutputBufferInternal
|
||||
* tree.c: harden the code around buffer allocation schemes
|
||||
* parser.c: restore the warning when namespace names are not absolute
|
||||
URIs
|
||||
* runxmlconf.c: continue regression tests if we get the expected
|
||||
number of errors
|
||||
* Makefile.am: run the python tests on make check
|
||||
* xmlsave.c: handle the HTML documents and trees
|
||||
* python/libxml.c: convert python serialization to the xmlSave APIs
|
||||
and avoid some horrible hacks
|
||||
|
||||
Sat Aug 30 16:58:40 CEST 2008 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* configure.in, doc/*: preparing 2.7.0 release
|
||||
|
@ -316,6 +316,11 @@ htmlIsBooleanAttr(const xmlChar *name)
|
||||
}
|
||||
|
||||
#ifdef LIBXML_OUTPUT_ENABLED
|
||||
/*
|
||||
* private routine exported from xmlIO.c
|
||||
*/
|
||||
xmlOutputBufferPtr
|
||||
xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
|
||||
/************************************************************************
|
||||
* *
|
||||
* Output error handlers *
|
||||
@ -566,7 +571,7 @@ htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
|
||||
if (handler == NULL)
|
||||
handler = xmlFindCharEncodingHandler("ascii");
|
||||
|
||||
buf = xmlAllocOutputBuffer(handler);
|
||||
buf = xmlAllocOutputBufferInternal(handler);
|
||||
if (buf == NULL) {
|
||||
*mem = NULL;
|
||||
*size = 0;
|
||||
|
@ -157,7 +157,7 @@ rebuild_testapi:
|
||||
|
||||
# that one is just to make sure it is rebuilt if missing
|
||||
# but adding the dependances generate mess
|
||||
testapi.c:
|
||||
testapi.c: $(srcdir)/gentest.py
|
||||
-@(if [ "$(PYTHON)" != "" ] ; then \
|
||||
$(PYTHON) $(srcdir)/gentest.py $(srcdir) ; fi )
|
||||
|
||||
@ -178,6 +178,8 @@ runxmlconf_LDADD= $(LDADDS)
|
||||
|
||||
runtests:
|
||||
$(CHECKER) ./runtest$(EXEEXT) && $(CHECKER) ./testrecurse$(EXEEXT) &&$(CHECKER) ./testapi$(EXEEXT) && $(CHECKER) ./testchar$(EXEEXT)&& $(CHECKER) ./testdict$(EXEEXT) && $(CHECKER) ./runxmlconf$(EXEEXT)
|
||||
@(if [ "@PYTHON_SUBDIR@" != "" ] ; then cd python ; \
|
||||
$(MAKE) MAKEFLAGS+=--silent tests ; fi)
|
||||
|
||||
check: all runtests
|
||||
|
||||
|
27
NEWS
27
NEWS
@ -15,6 +15,33 @@ ChangeLog.html
|
||||
to the SVN at
|
||||
http://svn.gnome.org/viewcvs/libxml2/trunk/
|
||||
code base.Here is the list of public releases:
|
||||
2.7.0: Aug 30 2008:
|
||||
- Documentation: switch ChangeLog to UTF-8, improve mutithreads and
|
||||
xmlParserCleanup docs
|
||||
- Portability fixes: Older Win32 platforms (Rob Richards), MSVC
|
||||
porting fix (Rob Richards), Mac OS X regression tests (Sven Herzberg),
|
||||
non GNUCC builds (Rob Richards), compilation on Haiku (Andreas Färber)
|
||||
|
||||
- Bug fixes: various realloc problems (Ashwin), potential double-free
|
||||
(Ashwin), regexp crash, icrash with invalid whitespace facets (Rob
|
||||
Richards), pattern fix when streaming (William Brack), various XML
|
||||
parsing and validation fixes based on the W3C regression tests, reader
|
||||
tree skipping function fix (Ashwin), Schemas regexps escaping fix
|
||||
(Volker Grabsch), handling of entity push errors (Ashwin), fix a slowdown
|
||||
when encoder cant serialize characters on output
|
||||
- Code cleanup: compilation fix without the reader, without the output
|
||||
(Robert Schwebel), python whitespace (Martin), many space/tabs cleanups,
|
||||
serious cleanup of the entity handling code
|
||||
- Improvement: switch parser to XML-1.0 5th edition, add parsing flags
|
||||
for old versions, switch URI parsing to RFC 3986,
|
||||
add xmlSchemaValidCtxtGetParserCtxt (Holger Kaelberer),
|
||||
new hashing functions for dictionnaries (based on Stefan Behnel work),
|
||||
improve handling of misplaced html/head/body in HTML parser, better
|
||||
regression test tools and code coverage display, better algorithms
|
||||
to detect various versions of the billion laughts attacks, make
|
||||
arbitrary parser limits avoidable as a parser option
|
||||
|
||||
|
||||
2.6.32: Apr 8 2008:
|
||||
- Documentation: returning heap memory to kernel (Wolfram Sang),
|
||||
trying to clarify xmlCleanupParser() use, xmlXPathContext improvement
|
||||
|
@ -260,6 +260,7 @@ extra_post_call = {
|
||||
"xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
|
||||
"xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
|
||||
"xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
|
||||
"xmlBufferSetAllocationScheme": "if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}"
|
||||
}
|
||||
|
||||
modules = []
|
||||
|
2
parser.c
2
parser.c
@ -8694,7 +8694,7 @@ reparse:
|
||||
"xmlns: '%s' is not a valid URI\n",
|
||||
URL, NULL, NULL);
|
||||
} else {
|
||||
if ((ctxt->pedantic) && (uri->scheme == NULL)) {
|
||||
if (uri->scheme == NULL) {
|
||||
xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
|
||||
"xmlns: URI %s is not absolute\n",
|
||||
URL, NULL, NULL);
|
||||
|
147
python/libxml.c
147
python/libxml.c
@ -24,6 +24,7 @@
|
||||
#include <libxml/xmlIO.h>
|
||||
#include <libxml/c14n.h>
|
||||
#include <libxml/xmlreader.h>
|
||||
#include <libxml/xmlsave.h>
|
||||
#include "libxml_wrap.h"
|
||||
#include "libxml2-py.h"
|
||||
|
||||
@ -2761,6 +2762,9 @@ libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
|
||||
const char *encoding;
|
||||
int format;
|
||||
int len;
|
||||
xmlSaveCtxtPtr ctxt;
|
||||
xmlBufferPtr buf;
|
||||
int options = 0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
|
||||
&encoding, &format))
|
||||
@ -2773,137 +2777,52 @@ libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
|
||||
}
|
||||
if (node->type == XML_DOCUMENT_NODE) {
|
||||
doc = (xmlDocPtr) node;
|
||||
xmlDocDumpFormatMemoryEnc(doc, &c_retval, &len,
|
||||
(const char *) encoding, format);
|
||||
py_retval = libxml_charPtrWrap((char *) c_retval);
|
||||
node = NULL;
|
||||
#ifdef LIBXML_HTML_ENABLED
|
||||
} else if (node->type == XML_HTML_DOCUMENT_NODE) {
|
||||
xmlOutputBufferPtr buf;
|
||||
xmlCharEncodingHandlerPtr handler = NULL;
|
||||
|
||||
doc = (xmlDocPtr) node;
|
||||
if (encoding != NULL)
|
||||
htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
|
||||
encoding = (const char *) htmlGetMetaEncoding(doc);
|
||||
|
||||
if (encoding != NULL) {
|
||||
handler = xmlFindCharEncodingHandler(encoding);
|
||||
if (handler == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fallback to HTML or ASCII when the encoding is unspecified
|
||||
*/
|
||||
if (handler == NULL)
|
||||
handler = xmlFindCharEncodingHandler("HTML");
|
||||
if (handler == NULL)
|
||||
handler = xmlFindCharEncodingHandler("ascii");
|
||||
|
||||
buf = xmlAllocOutputBuffer(handler);
|
||||
if (buf == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
|
||||
xmlOutputBufferFlush(buf);
|
||||
if (buf->conv != NULL) {
|
||||
len = buf->conv->use;
|
||||
c_retval = buf->conv->content;
|
||||
buf->conv->content = NULL;
|
||||
} else {
|
||||
len = buf->buffer->use;
|
||||
c_retval = buf->buffer->content;
|
||||
buf->buffer->content = NULL;
|
||||
}
|
||||
(void) xmlOutputBufferClose(buf);
|
||||
py_retval = libxml_charPtrWrap((char *) c_retval);
|
||||
#endif /* LIBXML_HTML_ENABLED */
|
||||
node = NULL;
|
||||
#endif
|
||||
} else {
|
||||
if (node->type == XML_NAMESPACE_DECL)
|
||||
doc = NULL;
|
||||
else
|
||||
doc = node->doc;
|
||||
if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
|
||||
xmlOutputBufferPtr buf;
|
||||
xmlCharEncodingHandlerPtr handler = NULL;
|
||||
|
||||
if (encoding != NULL) {
|
||||
handler = xmlFindCharEncodingHandler(encoding);
|
||||
if (handler == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
}
|
||||
|
||||
buf = xmlAllocOutputBuffer(handler);
|
||||
if (buf == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
|
||||
xmlOutputBufferFlush(buf);
|
||||
if (buf->conv != NULL) {
|
||||
len = buf->conv->use;
|
||||
c_retval = buf->conv->content;
|
||||
buf->conv->content = NULL;
|
||||
} else {
|
||||
len = buf->buffer->use;
|
||||
c_retval = buf->buffer->content;
|
||||
buf->buffer->content = NULL;
|
||||
}
|
||||
(void) xmlOutputBufferClose(buf);
|
||||
py_retval = libxml_charPtrWrap((char *) c_retval);
|
||||
#ifdef LIBXML_HTML_ENABLED
|
||||
} else if (doc->type == XML_HTML_DOCUMENT_NODE) {
|
||||
xmlOutputBufferPtr buf;
|
||||
xmlCharEncodingHandlerPtr handler = NULL;
|
||||
|
||||
if (encoding != NULL)
|
||||
htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
|
||||
encoding = (const char *) htmlGetMetaEncoding(doc);
|
||||
if (encoding != NULL) {
|
||||
handler = xmlFindCharEncodingHandler(encoding);
|
||||
if (handler == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fallback to HTML or ASCII when the encoding is unspecified
|
||||
*/
|
||||
if (handler == NULL)
|
||||
handler = xmlFindCharEncodingHandler("HTML");
|
||||
if (handler == NULL)
|
||||
handler = xmlFindCharEncodingHandler("ascii");
|
||||
|
||||
buf = xmlAllocOutputBuffer(handler);
|
||||
if (buf == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
|
||||
xmlOutputBufferFlush(buf);
|
||||
if (buf->conv != NULL) {
|
||||
len = buf->conv->use;
|
||||
c_retval = buf->conv->content;
|
||||
buf->conv->content = NULL;
|
||||
} else {
|
||||
len = buf->buffer->use;
|
||||
c_retval = buf->buffer->content;
|
||||
buf->buffer->content = NULL;
|
||||
}
|
||||
(void) xmlOutputBufferClose(buf);
|
||||
py_retval = libxml_charPtrWrap((char *) c_retval);
|
||||
#endif /* LIBXML_HTML_ENABLED */
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buf = xmlBufferCreate();
|
||||
if (buf == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
if (format) options |= XML_SAVE_FORMAT;
|
||||
ctxt = xmlSaveToBuffer(buf, encoding, options);
|
||||
if (ctxt == NULL) {
|
||||
xmlBufferFree(buf);
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
if (node == NULL)
|
||||
xmlSaveDoc(ctxt, doc);
|
||||
else
|
||||
xmlSaveTree(ctxt, node);
|
||||
xmlSaveClose(ctxt);
|
||||
|
||||
c_retval = buf->content;
|
||||
buf->content = NULL;
|
||||
|
||||
xmlBufferFree(buf);
|
||||
py_retval = libxml_charPtrWrap((char *) c_retval);
|
||||
|
||||
return (py_retval);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
static FILE *logfile = NULL;
|
||||
static int verbose = 0;
|
||||
|
||||
|
||||
#define NB_EXPECTED_ERRORS 15
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
|
||||
@ -588,10 +588,14 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
|
||||
printf("Total %d tests, no errors\n",
|
||||
nb_tests);
|
||||
} else {
|
||||
ret = 1;
|
||||
ret = 1;
|
||||
printf("Total %d tests, %d errors, %d leaks\n",
|
||||
nb_tests, nb_errors, nb_leaks);
|
||||
printf("See %s for detailed output\n", LOGFILE);
|
||||
if ((nb_leaks == 0) && (nb_errors == NB_EXPECTED_ERRORS)) {
|
||||
printf("%d errors were expected\n", nb_errors);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
xmlXPathFreeContext(ctxtXPath);
|
||||
xmlCleanupParser();
|
||||
|
@ -599,9 +599,10 @@ static void des_xmlTextReaderPtr(int no ATTRIBUTE_UNUSED, xmlTextReaderPtr val,
|
||||
#endif
|
||||
|
||||
#define gen_nb_xmlBufferPtr 3
|
||||
static const char *static_buf_content = "a static buffer";
|
||||
static xmlBufferPtr gen_xmlBufferPtr(int no, int nr ATTRIBUTE_UNUSED) {
|
||||
if (no == 0) return(xmlBufferCreate());
|
||||
if (no == 1) return(xmlBufferCreateStatic((void *)"a static buffer", 13));
|
||||
if (no == 1) return(xmlBufferCreateStatic((void *)static_buf_content, 13));
|
||||
return(NULL);
|
||||
}
|
||||
static void des_xmlBufferPtr(int no ATTRIBUTE_UNUSED, xmlBufferPtr val, int nr ATTRIBUTE_UNUSED) {
|
||||
@ -18827,6 +18828,7 @@ test_xmlBufferSetAllocationScheme(void) {
|
||||
scheme = gen_xmlBufferAllocationScheme(n_scheme, 1);
|
||||
|
||||
xmlBufferSetAllocationScheme(buf, scheme);
|
||||
if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}
|
||||
call_tests++;
|
||||
des_xmlBufferPtr(n_buf, buf, 0);
|
||||
des_xmlBufferAllocationScheme(n_scheme, scheme, 1);
|
||||
|
13
tree.c
13
tree.c
@ -680,7 +680,9 @@ try_complex:
|
||||
*/
|
||||
void
|
||||
xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
|
||||
xmlBufferAllocScheme = scheme;
|
||||
if ((scheme == XML_BUFFER_ALLOC_EXACT) ||
|
||||
(scheme == XML_BUFFER_ALLOC_DOUBLEIT))
|
||||
xmlBufferAllocScheme = scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -6736,9 +6738,12 @@ xmlBufferSetAllocationScheme(xmlBufferPtr buf,
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return;
|
||||
|
||||
buf->alloc = scheme;
|
||||
if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) ||
|
||||
(buf->alloc == XML_BUFFER_ALLOC_IO)) return;
|
||||
if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
|
||||
(scheme == XML_BUFFER_ALLOC_EXACT) ||
|
||||
(scheme == XML_BUFFER_ALLOC_IMMUTABLE))
|
||||
buf->alloc = scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,7 +129,11 @@ static TRIO_CONST char rcsid[] = "@(#)$Id$";
|
||||
*/
|
||||
#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
|
||||
|
||||
#if (defined(__BORLANDC__) && __BORLANDC__ >= 0x0590)
|
||||
static TRIO_CONST double internalEndianMagic = 7.949928895127362e-275;
|
||||
#else
|
||||
static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
|
||||
#endif
|
||||
|
||||
/* Mask for the exponent */
|
||||
static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
|
||||
|
69
xmlIO.c
69
xmlIO.c
@ -135,6 +135,9 @@ typedef struct _xmlOutputCallback {
|
||||
static xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK];
|
||||
static int xmlOutputCallbackNr = 0;
|
||||
static int xmlOutputCallbackInitialized = 0;
|
||||
|
||||
xmlOutputBufferPtr
|
||||
xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
|
||||
#endif /* LIBXML_OUTPUT_ENABLED */
|
||||
|
||||
/************************************************************************
|
||||
@ -1720,7 +1723,7 @@ xmlIOHTTPOpenW(const char *post_uri, int compression)
|
||||
{
|
||||
/* Any character conversions should have been done before this */
|
||||
|
||||
ctxt->doc_buff = xmlAllocOutputBuffer(NULL);
|
||||
ctxt->doc_buff = xmlAllocOutputBufferInternal(NULL);
|
||||
}
|
||||
|
||||
if (ctxt->doc_buff == NULL) {
|
||||
@ -1731,7 +1734,7 @@ xmlIOHTTPOpenW(const char *post_uri, int compression)
|
||||
return (ctxt);
|
||||
}
|
||||
#endif /* LIBXML_OUTPUT_ENABLED */
|
||||
|
||||
|
||||
#ifdef LIBXML_OUTPUT_ENABLED
|
||||
/**
|
||||
* xmlIOHTTPDfltOpenW
|
||||
@ -2275,8 +2278,57 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
ret->encoder = encoder;
|
||||
if (encoder != NULL) {
|
||||
ret->conv = xmlBufferCreateSize(4000);
|
||||
if (ret->conv == NULL) {
|
||||
xmlFree(ret);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* This call is designed to initiate the encoder state
|
||||
*/
|
||||
xmlCharEncOutFunc(encoder, ret->conv, NULL);
|
||||
} else
|
||||
ret->conv = NULL;
|
||||
ret->writecallback = NULL;
|
||||
ret->closecallback = NULL;
|
||||
ret->context = NULL;
|
||||
ret->written = 0;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlAllocOutputBufferInternal:
|
||||
* @encoder: the encoding converter or NULL
|
||||
*
|
||||
* Create a buffered parser output
|
||||
*
|
||||
* Returns the new parser output or NULL
|
||||
*/
|
||||
xmlOutputBufferPtr
|
||||
xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder) {
|
||||
xmlOutputBufferPtr ret;
|
||||
|
||||
ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
|
||||
if (ret == NULL) {
|
||||
xmlIOErrMemory("creating output buffer");
|
||||
return(NULL);
|
||||
}
|
||||
memset(ret, 0, (size_t) sizeof(xmlOutputBuffer));
|
||||
ret->buffer = xmlBufferCreate();
|
||||
if (ret->buffer == NULL) {
|
||||
xmlFree(ret);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* For conversion buffers we use the special IO handling
|
||||
* We don't do that from the exported API to avoid confusing
|
||||
* user's code.
|
||||
*/
|
||||
ret->buffer->alloc = XML_BUFFER_ALLOC_IO;
|
||||
ret->buffer->contentIO = ret->buffer->content;
|
||||
@ -2302,6 +2354,7 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#endif /* LIBXML_OUTPUT_ENABLED */
|
||||
|
||||
/**
|
||||
@ -2502,7 +2555,7 @@ __xmlOutputBufferCreateFilename(const char *URI,
|
||||
if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) {
|
||||
context = xmlGzfileOpenW(unescaped, compression);
|
||||
if (context != NULL) {
|
||||
ret = xmlAllocOutputBuffer(encoder);
|
||||
ret = xmlAllocOutputBufferInternal(encoder);
|
||||
if (ret != NULL) {
|
||||
ret->context = context;
|
||||
ret->writecallback = xmlGzfileWrite;
|
||||
@ -2539,7 +2592,7 @@ __xmlOutputBufferCreateFilename(const char *URI,
|
||||
if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) {
|
||||
context = xmlGzfileOpenW(URI, compression);
|
||||
if (context != NULL) {
|
||||
ret = xmlAllocOutputBuffer(encoder);
|
||||
ret = xmlAllocOutputBufferInternal(encoder);
|
||||
if (ret != NULL) {
|
||||
ret->context = context;
|
||||
ret->writecallback = xmlGzfileWrite;
|
||||
@ -2572,7 +2625,7 @@ __xmlOutputBufferCreateFilename(const char *URI,
|
||||
/*
|
||||
* Allocate the Output buffer front-end.
|
||||
*/
|
||||
ret = xmlAllocOutputBuffer(encoder);
|
||||
ret = xmlAllocOutputBufferInternal(encoder);
|
||||
if (ret != NULL) {
|
||||
ret->context = context;
|
||||
ret->writecallback = xmlOutputCallbackTable[i].writecallback;
|
||||
@ -2656,7 +2709,7 @@ xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) {
|
||||
|
||||
if (file == NULL) return(NULL);
|
||||
|
||||
ret = xmlAllocOutputBuffer(encoder);
|
||||
ret = xmlAllocOutputBufferInternal(encoder);
|
||||
if (ret != NULL) {
|
||||
ret->context = file;
|
||||
ret->writecallback = xmlFileWrite;
|
||||
@ -2814,7 +2867,7 @@ xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) {
|
||||
|
||||
if (fd < 0) return(NULL);
|
||||
|
||||
ret = xmlAllocOutputBuffer(encoder);
|
||||
ret = xmlAllocOutputBufferInternal(encoder);
|
||||
if (ret != NULL) {
|
||||
ret->context = (void *) (long) fd;
|
||||
ret->writecallback = xmlFdWrite;
|
||||
@ -2875,7 +2928,7 @@ xmlOutputBufferCreateIO(xmlOutputWriteCallback iowrite,
|
||||
|
||||
if (iowrite == NULL) return(NULL);
|
||||
|
||||
ret = xmlAllocOutputBuffer(encoder);
|
||||
ret = xmlAllocOutputBufferInternal(encoder);
|
||||
if (ret != NULL) {
|
||||
ret->context = (void *) ioctx;
|
||||
ret->writecallback = iowrite;
|
||||
|
291
xmlsave.c
291
xmlsave.c
@ -457,6 +457,40 @@ xmlAttrSerializeContent(xmlOutputBufferPtr buf, xmlAttrPtr attr)
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
static int xmlSaveSwitchEncoding(xmlSaveCtxtPtr ctxt, const char *encoding) {
|
||||
xmlOutputBufferPtr buf = ctxt->buf;
|
||||
|
||||
if ((encoding != NULL) && (buf->encoder == NULL) && (buf->conv == NULL)) {
|
||||
buf->encoder = xmlFindCharEncodingHandler((const char *)encoding);
|
||||
if (buf->encoder == NULL) {
|
||||
xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL,
|
||||
(const char *)encoding);
|
||||
return(-1);
|
||||
}
|
||||
buf->conv = xmlBufferCreate();
|
||||
if (buf->conv == NULL) {
|
||||
xmlCharEncCloseFunc(buf->encoder);
|
||||
xmlSaveErrMemory("creating encoding buffer");
|
||||
return(-1);
|
||||
}
|
||||
/*
|
||||
* initialize the state, e.g. if outputting a BOM
|
||||
*/
|
||||
xmlCharEncOutFunc(buf->encoder, buf->conv, NULL);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int xmlSaveClearEncoding(xmlSaveCtxtPtr ctxt) {
|
||||
xmlOutputBufferPtr buf = ctxt->buf;
|
||||
xmlOutputBufferFlush(buf);
|
||||
xmlCharEncCloseFunc(buf->encoder);
|
||||
xmlBufferFree(buf->conv);
|
||||
buf->encoder = NULL;
|
||||
buf->conv = NULL;
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef LIBXML_HTML_ENABLED
|
||||
static void
|
||||
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
|
||||
@ -638,6 +672,66 @@ xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LIBXML_HTML_ENABLED
|
||||
/**
|
||||
* xmlNodeDumpOutputInternal:
|
||||
* @cur: the current node
|
||||
*
|
||||
* Dump an HTML node, recursive behaviour, children are printed too.
|
||||
*/
|
||||
static int
|
||||
htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
const xmlChar *oldenc = NULL;
|
||||
const xmlChar *oldctxtenc = ctxt->encoding;
|
||||
const xmlChar *encoding = ctxt->encoding;
|
||||
xmlOutputBufferPtr buf = ctxt->buf;
|
||||
int switched_encoding = 0;
|
||||
xmlDocPtr doc;
|
||||
|
||||
xmlInitParser();
|
||||
|
||||
doc = cur->doc; {
|
||||
if (doc != NULL)
|
||||
oldenc = doc->encoding;
|
||||
if (ctxt->encoding != NULL) {
|
||||
doc->encoding = BAD_CAST ctxt->encoding;
|
||||
} else if (doc->encoding != NULL) {
|
||||
encoding = doc->encoding;
|
||||
}
|
||||
}
|
||||
|
||||
if ((encoding != NULL) && (doc != NULL))
|
||||
htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
|
||||
if ((encoding == NULL) && (doc != NULL))
|
||||
encoding = htmlGetMetaEncoding(doc);
|
||||
if (encoding == NULL)
|
||||
encoding = BAD_CAST "HTML";
|
||||
if ((encoding != NULL) && (oldctxtenc == NULL) &&
|
||||
(buf->encoder == NULL) && (buf->conv == NULL)) {
|
||||
if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
|
||||
doc->encoding = oldenc;
|
||||
return(-1);
|
||||
}
|
||||
switched_encoding = 1;
|
||||
}
|
||||
if (ctxt->options & XML_SAVE_FORMAT)
|
||||
htmlNodeDumpFormatOutput(buf, doc, cur,
|
||||
(const char *)encoding, 1);
|
||||
else
|
||||
htmlNodeDumpFormatOutput(buf, doc, cur,
|
||||
(const char *)encoding, 0);
|
||||
/*
|
||||
* Restore the state of the saving context at the end of the document
|
||||
*/
|
||||
if ((switched_encoding) && (oldctxtenc == NULL)) {
|
||||
xmlSaveClearEncoding(ctxt);
|
||||
}
|
||||
if (doc != NULL)
|
||||
doc->encoding = oldenc;
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* xmlNodeDumpOutputInternal:
|
||||
* @cur: the current node
|
||||
@ -662,6 +756,13 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
|
||||
return;
|
||||
}
|
||||
#ifdef LIBXML_HTML_ENABLED
|
||||
if ((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL) &&
|
||||
(cur->doc->type == XML_HTML_DOCUMENT_NODE)) {
|
||||
htmlNodeDumpOutputInternal(ctxt, cur);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (cur->type == XML_DTD_NODE) {
|
||||
xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
|
||||
return;
|
||||
@ -835,9 +936,14 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {
|
||||
xmlCharEncodingOutputFunc oldescapeAttr = ctxt->escapeAttr;
|
||||
xmlOutputBufferPtr buf = ctxt->buf;
|
||||
xmlCharEncoding enc;
|
||||
int switched_encoding = 0;
|
||||
|
||||
xmlInitParser();
|
||||
|
||||
if ((cur->type != XML_HTML_DOCUMENT_NODE) &&
|
||||
(cur->type != XML_DOCUMENT_NODE))
|
||||
return(-1);
|
||||
|
||||
if (ctxt->encoding != NULL) {
|
||||
cur->encoding = BAD_CAST ctxt->encoding;
|
||||
} else if (cur->encoding != NULL) {
|
||||
@ -847,110 +953,119 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {
|
||||
xmlGetCharEncodingName((xmlCharEncoding) cur->charset);
|
||||
}
|
||||
|
||||
enc = xmlParseCharEncoding((const char*) encoding);
|
||||
if ((encoding != NULL) && (oldctxtenc == NULL) &&
|
||||
(buf->encoder == NULL) && (buf->conv == NULL) &&
|
||||
((ctxt->options & XML_SAVE_NO_DECL) == 0)) {
|
||||
if ((enc != XML_CHAR_ENCODING_UTF8) &&
|
||||
(enc != XML_CHAR_ENCODING_NONE) &&
|
||||
(enc != XML_CHAR_ENCODING_ASCII)) {
|
||||
/*
|
||||
* we need to switch to this encoding but just for this document
|
||||
* since we output the XMLDecl the conversion must be done to not
|
||||
* generate not well formed documents.
|
||||
*/
|
||||
buf->encoder = xmlFindCharEncodingHandler((const char *)encoding);
|
||||
if (buf->encoder == NULL) {
|
||||
xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL,
|
||||
(const char *)encoding);
|
||||
if (cur->type == XML_HTML_DOCUMENT_NODE) {
|
||||
#ifdef LIBXML_HTML_ENABLED
|
||||
if (encoding != NULL)
|
||||
htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
|
||||
if (encoding == NULL)
|
||||
encoding = htmlGetMetaEncoding(cur);
|
||||
if (encoding == NULL)
|
||||
encoding = BAD_CAST "HTML";
|
||||
if ((encoding != NULL) && (oldctxtenc == NULL) &&
|
||||
(buf->encoder == NULL) && (buf->conv == NULL)) {
|
||||
if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
|
||||
cur->encoding = oldenc;
|
||||
return(-1);
|
||||
}
|
||||
buf->conv = xmlBufferCreate();
|
||||
if (buf->conv == NULL) {
|
||||
xmlCharEncCloseFunc(buf->encoder);
|
||||
xmlSaveErrMemory("creating encoding buffer");
|
||||
return(-1);
|
||||
}
|
||||
/*
|
||||
* initialize the state, e.g. if outputting a BOM
|
||||
*/
|
||||
xmlCharEncOutFunc(buf->encoder, buf->conv, NULL);
|
||||
switched_encoding = 1;
|
||||
}
|
||||
if (ctxt->escape == xmlEscapeEntities)
|
||||
ctxt->escape = NULL;
|
||||
if (ctxt->escapeAttr == xmlEscapeEntities)
|
||||
ctxt->escapeAttr = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Save the XML declaration
|
||||
*/
|
||||
if ((ctxt->options & XML_SAVE_NO_DECL) == 0) {
|
||||
xmlOutputBufferWrite(buf, 14, "<?xml version=");
|
||||
if (cur->version != NULL)
|
||||
xmlBufferWriteQuotedString(buf->buffer, cur->version);
|
||||
if (ctxt->options & XML_SAVE_FORMAT)
|
||||
htmlDocContentDumpFormatOutput(buf, cur,
|
||||
(const char *)encoding, 1);
|
||||
else
|
||||
xmlOutputBufferWrite(buf, 5, "\"1.0\"");
|
||||
if (encoding != NULL) {
|
||||
xmlOutputBufferWrite(buf, 10, " encoding=");
|
||||
xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding);
|
||||
}
|
||||
switch (cur->standalone) {
|
||||
case 0:
|
||||
xmlOutputBufferWrite(buf, 16, " standalone=\"no\"");
|
||||
break;
|
||||
case 1:
|
||||
xmlOutputBufferWrite(buf, 17, " standalone=\"yes\"");
|
||||
break;
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 3, "?>\n");
|
||||
}
|
||||
|
||||
#ifdef LIBXML_HTML_ENABLED
|
||||
if ((ctxt->options & XML_SAVE_NO_XHTML) == 0) {
|
||||
dtd = xmlGetIntSubset(cur);
|
||||
if (dtd != NULL) {
|
||||
is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
|
||||
if (is_xhtml < 0) is_xhtml = 0;
|
||||
}
|
||||
}
|
||||
htmlDocContentDumpFormatOutput(buf, cur,
|
||||
(const char *)encoding, 0);
|
||||
if (ctxt->encoding != NULL)
|
||||
cur->encoding = oldenc;
|
||||
return(0);
|
||||
#else
|
||||
return(-1);
|
||||
#endif
|
||||
if (cur->children != NULL) {
|
||||
xmlNodePtr child = cur->children;
|
||||
} else if (cur->type == XML_DOCUMENT_NODE) {
|
||||
enc = xmlParseCharEncoding((const char*) encoding);
|
||||
if ((encoding != NULL) && (oldctxtenc == NULL) &&
|
||||
(buf->encoder == NULL) && (buf->conv == NULL) &&
|
||||
((ctxt->options & XML_SAVE_NO_DECL) == 0)) {
|
||||
if ((enc != XML_CHAR_ENCODING_UTF8) &&
|
||||
(enc != XML_CHAR_ENCODING_NONE) &&
|
||||
(enc != XML_CHAR_ENCODING_ASCII)) {
|
||||
/*
|
||||
* we need to switch to this encoding but just for this
|
||||
* document since we output the XMLDecl the conversion
|
||||
* must be done to not generate not well formed documents.
|
||||
*/
|
||||
if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
|
||||
cur->encoding = oldenc;
|
||||
return(-1);
|
||||
}
|
||||
switched_encoding = 1;
|
||||
}
|
||||
if (ctxt->escape == xmlEscapeEntities)
|
||||
ctxt->escape = NULL;
|
||||
if (ctxt->escapeAttr == xmlEscapeEntities)
|
||||
ctxt->escapeAttr = NULL;
|
||||
}
|
||||
|
||||
while (child != NULL) {
|
||||
ctxt->level = 0;
|
||||
#ifdef LIBXML_HTML_ENABLED
|
||||
if (is_xhtml)
|
||||
xhtmlNodeDumpOutput(ctxt, child);
|
||||
|
||||
/*
|
||||
* Save the XML declaration
|
||||
*/
|
||||
if ((ctxt->options & XML_SAVE_NO_DECL) == 0) {
|
||||
xmlOutputBufferWrite(buf, 14, "<?xml version=");
|
||||
if (cur->version != NULL)
|
||||
xmlBufferWriteQuotedString(buf->buffer, cur->version);
|
||||
else
|
||||
xmlOutputBufferWrite(buf, 5, "\"1.0\"");
|
||||
if (encoding != NULL) {
|
||||
xmlOutputBufferWrite(buf, 10, " encoding=");
|
||||
xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding);
|
||||
}
|
||||
switch (cur->standalone) {
|
||||
case 0:
|
||||
xmlOutputBufferWrite(buf, 16, " standalone=\"no\"");
|
||||
break;
|
||||
case 1:
|
||||
xmlOutputBufferWrite(buf, 17, " standalone=\"yes\"");
|
||||
break;
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 3, "?>\n");
|
||||
}
|
||||
|
||||
#ifdef LIBXML_HTML_ENABLED
|
||||
if ((ctxt->options & XML_SAVE_NO_XHTML) == 0) {
|
||||
dtd = xmlGetIntSubset(cur);
|
||||
if (dtd != NULL) {
|
||||
is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
|
||||
if (is_xhtml < 0) is_xhtml = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
xmlNodeDumpOutputInternal(ctxt, child);
|
||||
xmlOutputBufferWrite(buf, 1, "\n");
|
||||
child = child->next;
|
||||
if (cur->children != NULL) {
|
||||
xmlNodePtr child = cur->children;
|
||||
|
||||
while (child != NULL) {
|
||||
ctxt->level = 0;
|
||||
#ifdef LIBXML_HTML_ENABLED
|
||||
if (is_xhtml)
|
||||
xhtmlNodeDumpOutput(ctxt, child);
|
||||
else
|
||||
#endif
|
||||
xmlNodeDumpOutputInternal(ctxt, child);
|
||||
xmlOutputBufferWrite(buf, 1, "\n");
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ctxt->encoding != NULL)
|
||||
cur->encoding = oldenc;
|
||||
|
||||
|
||||
/*
|
||||
* Restore the state of the saving context at the end of the document
|
||||
*/
|
||||
if ((encoding != NULL) && (oldctxtenc == NULL) &&
|
||||
((ctxt->options & XML_SAVE_NO_DECL) == 0)) {
|
||||
if ((enc != XML_CHAR_ENCODING_UTF8) &&
|
||||
(enc != XML_CHAR_ENCODING_NONE) &&
|
||||
(enc != XML_CHAR_ENCODING_ASCII)) {
|
||||
xmlOutputBufferFlush(buf);
|
||||
xmlCharEncCloseFunc(buf->encoder);
|
||||
xmlBufferFree(buf->conv);
|
||||
buf->encoder = NULL;
|
||||
buf->conv = NULL;
|
||||
}
|
||||
if ((switched_encoding) && (oldctxtenc == NULL)) {
|
||||
xmlSaveClearEncoding(ctxt);
|
||||
ctxt->escape = oldescape;
|
||||
ctxt->escapeAttr = oldescapeAttr;
|
||||
}
|
||||
cur->encoding = oldenc;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user