| Index: third_party/libxml/HTMLtree.c
|
| diff --git a/third_party/libxml/HTMLtree.c b/third_party/libxml/HTMLtree.c
|
| index e79d1180f3d4c5936444b0b0119e8d909bf4af81..b5085836b900af69b90eab1d68bd71ed3ba55559 100644
|
| --- a/third_party/libxml/HTMLtree.c
|
| +++ b/third_party/libxml/HTMLtree.c
|
| @@ -160,14 +160,18 @@ found_content:
|
| */
|
| int
|
| htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
|
| - htmlNodePtr cur, meta;
|
| - const xmlChar *content;
|
| + htmlNodePtr cur, meta = NULL, head = NULL;
|
| + const xmlChar *content = NULL;
|
| char newcontent[100];
|
|
|
|
|
| if (doc == NULL)
|
| return(-1);
|
|
|
| + /* html isn't a real encoding it's just libxml2 way to get entities */
|
| + if (!xmlStrcasecmp(encoding, BAD_CAST "html"))
|
| + return(-1);
|
| +
|
| if (encoding != NULL) {
|
| snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s",
|
| (char *)encoding);
|
| @@ -201,39 +205,24 @@ htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
|
| if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
|
| if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
|
| break;
|
| - if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0)
|
| + if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
|
| + head = cur->parent;
|
| goto found_meta;
|
| + }
|
| }
|
| cur = cur->next;
|
| }
|
| if (cur == NULL)
|
| return(-1);
|
| found_head:
|
| - if (cur->children == NULL) {
|
| - if (encoding == NULL)
|
| - return(0);
|
| - meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
|
| - xmlAddChild(cur, meta);
|
| - xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
|
| - xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
|
| - return(0);
|
| - }
|
| + head = cur;
|
| + if (cur->children == NULL)
|
| + goto create;
|
| cur = cur->children;
|
|
|
| found_meta:
|
| - if (encoding != NULL) {
|
| - /*
|
| - * Create a new Meta element with the right attributes
|
| - */
|
| -
|
| - meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
|
| - xmlAddPrevSibling(cur, meta);
|
| - xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
|
| - xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
|
| - }
|
| -
|
| /*
|
| - * Search and destroy all the remaining the meta elements carrying
|
| + * Search and update all the remaining the meta elements carrying
|
| * encoding informations
|
| */
|
| while (cur != NULL) {
|
| @@ -253,11 +242,11 @@ found_meta:
|
| if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
|
| && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
|
| http = 1;
|
| - else
|
| + else
|
| {
|
| if ((value != NULL) &&
|
| - (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
|
| - content = value;
|
| + (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
|
| + content = value;
|
| }
|
| if ((http != 0) && (content != NULL))
|
| break;
|
| @@ -266,16 +255,36 @@ found_meta:
|
| }
|
| if ((http != 0) && (content != NULL)) {
|
| meta = cur;
|
| - cur = cur->next;
|
| - xmlUnlinkNode(meta);
|
| - xmlFreeNode(meta);
|
| - continue;
|
| + break;
|
| }
|
|
|
| }
|
| }
|
| cur = cur->next;
|
| }
|
| +create:
|
| + if (meta == NULL) {
|
| + if ((encoding != NULL) && (head != NULL)) {
|
| + /*
|
| + * Create a new Meta element with the right attributes
|
| + */
|
| +
|
| + meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
|
| + if (head->children == NULL)
|
| + xmlAddChild(head, meta);
|
| + else
|
| + xmlAddPrevSibling(head->children, meta);
|
| + xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
|
| + xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
|
| + }
|
| + } else {
|
| + /* change the document only if there is a real encoding change */
|
| + if (xmlStrcasestr(content, encoding) == NULL) {
|
| + xmlSetProp(meta, BAD_CAST"content", BAD_CAST newcontent);
|
| + }
|
| + }
|
| +
|
| +
|
| return(0);
|
| }
|
|
|
| @@ -316,6 +325,11 @@ htmlIsBooleanAttr(const xmlChar *name)
|
| }
|
|
|
| #ifdef LIBXML_OUTPUT_ENABLED
|
| +/*
|
| + * private routine exported from xmlIO.c
|
| + */
|
| +xmlOutputBufferPtr
|
| +xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
|
| /************************************************************************
|
| * *
|
| * Output error handlers *
|
| @@ -566,7 +580,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;
|
| @@ -1150,7 +1164,7 @@ htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
|
|
|
| if ((cur == NULL) || (filename == NULL))
|
| return(-1);
|
| -
|
| +
|
| xmlInitParser();
|
|
|
| if (encoding != NULL) {
|
| @@ -1168,8 +1182,8 @@ htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
|
| handler = xmlFindCharEncodingHandler(encoding);
|
| if (handler == NULL)
|
| return(-1);
|
| - htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
|
| }
|
| + htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
|
| } else {
|
| htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
|
| }
|
|
|