diff --git a/ChangeLog b/ChangeLog index 5ee25ec8..f3d4ccdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Sun Feb 1 01:48:14 PST 2004 William Brack <wbrack@mmm.com.hk> + + * tree.c, include/libxml/tree.h: moved serialization of + attribute text data (xmlSerializeContent) into a separate + routine (xmlSerializeTxtContent) so it can be used by xmlwriter.c + * xmlwriter.c: changed handling of attribute string to use the + routine above (fixed bug 131548) + Sat Jan 31 08:22:02 MST 2004 John Fleck <jfleck@inkstain.net * doc/examples/reader1.c, reader2.c, reader3.c diff --git a/include/libxml/tree.h b/include/libxml/tree.h index 954b2c18..bc4dbe36 100644 --- a/include/libxml/tree.h +++ b/include/libxml/tree.h @@ -966,6 +966,11 @@ XMLPUBFUN void XMLCALL xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar *string); +XMLPUBFUN void xmlAttrSerializeTxtContent(xmlBufferPtr buf, + xmlDocPtr doc, + xmlAttrPtr attr, + const xmlChar *string); + /* * Namespace handling. */ diff --git a/tree.c b/tree.c index b804a98b..620768b1 100644 --- a/tree.c +++ b/tree.c @@ -7002,6 +7002,142 @@ xmlSaveErr(int code, xmlNodePtr node, const char *extra) * Dumping XML tree content to a simple buffer * * * ************************************************************************/ +/** + * xmlAttrSerializeTxtContent: + * @buf: the XML buffer output + * @doc: the document + * @attr: the attribute node + * @value: the text content + * + * Serialize text attribute values to an xml simple buffer + */ +void +xmlAttrSerializeTxtContent(xmlBufferPtr buf, xmlDocPtr doc, + xmlAttrPtr attr, const xmlChar *string) { + xmlChar *base, *cur; + + base = cur = (xmlChar *)string; + while (*cur != 0) { + if (*cur == '\n') { + if (base != cur) + xmlBufferAdd(buf, base, cur - base); + xmlBufferAdd(buf, BAD_CAST " ", 5); + cur++; + base = cur; + } else if (*cur == '\r') { + if (base != cur) + xmlBufferAdd(buf, base, cur - base); + xmlBufferAdd(buf, BAD_CAST " ", 5); + cur++; + base = cur; + } else if (*cur == '\t') { + if (base != cur) + xmlBufferAdd(buf, base, cur - base); + xmlBufferAdd(buf, BAD_CAST "	", 4); + cur++; + base = cur; +#if 0 + base = cur = children->content; + } else if (*cur == '\'') { + if (base != cur) + xmlBufferAdd(buf, base, cur - base); + xmlBufferAdd(buf, BAD_CAST "'", 6); + cur++; + base = cur; +#endif + } else if (*cur == '"') { + if (base != cur) + xmlBufferAdd(buf, base, cur - base); + xmlBufferAdd(buf, BAD_CAST """, 6); + cur++; + base = cur; + } else if (*cur == '<') { + if (base != cur) + xmlBufferAdd(buf, base, cur - base); + xmlBufferAdd(buf, BAD_CAST "<", 4); + cur++; + base = cur; + } else if (*cur == '>') { + if (base != cur) + xmlBufferAdd(buf, base, cur - base); + xmlBufferAdd(buf, BAD_CAST ">", 4); + cur++; + base = cur; + } else if (*cur == '&') { + if (base != cur) + xmlBufferAdd(buf, base, cur - base); + xmlBufferAdd(buf, BAD_CAST "&", 5); + cur++; + base = cur; + } else if ((*cur >= 0x80) && ((doc == NULL) || + (doc->encoding == NULL))) { + /* + * We assume we have UTF-8 content. + */ + char tmp[10]; + int val = 0, l = 1; + + if (base != cur) + xmlBufferAdd(buf, base, cur - base); + if (*cur < 0xC0) { + xmlSaveErr(XML_SAVE_NOT_UTF8, (xmlNodePtr) attr, NULL); + if (doc != NULL) + doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); + snprintf(tmp, sizeof(tmp), "&#%d;", *cur); + tmp[sizeof(tmp) - 1] = 0; + xmlBufferAdd(buf, (xmlChar *) tmp, -1); + cur++; + base = cur; + continue; + } else if (*cur < 0xE0) { + val = (cur[0]) & 0x1F; + val <<= 6; + val |= (cur[1]) & 0x3F; + l = 2; + } else if (*cur < 0xF0) { + val = (cur[0]) & 0x0F; + val <<= 6; + val |= (cur[1]) & 0x3F; + val <<= 6; + val |= (cur[2]) & 0x3F; + l = 3; + } else if (*cur < 0xF8) { + val = (cur[0]) & 0x07; + val <<= 6; + val |= (cur[1]) & 0x3F; + val <<= 6; + val |= (cur[2]) & 0x3F; + val <<= 6; + val |= (cur[3]) & 0x3F; + l = 4; + } + if ((l == 1) || (!IS_CHAR(val))) { + xmlSaveErr(XML_SAVE_CHAR_INVALID, (xmlNodePtr) attr, NULL); + if (doc != NULL) + doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); + snprintf(tmp, sizeof(tmp), "&#%d;", *cur); + tmp[sizeof(tmp) - 1] = 0; + xmlBufferAdd(buf, (xmlChar *) tmp, -1); + cur++; + base = cur; + continue; + } + /* + * We could do multiple things here. Just save + * as a char ref + */ + snprintf(tmp, sizeof(tmp), "&#x%X;", val); + tmp[sizeof(tmp) - 1] = 0; + xmlBufferAdd(buf, (xmlChar *) tmp, -1); + cur += l; + base = cur; + } else { + cur++; + } + } + if (base != cur) + xmlBufferAdd(buf, base, cur - base); +} /** * xmlAttrSerializeContent: @@ -7014,139 +7150,14 @@ xmlSaveErr(int code, xmlNodePtr node, const char *extra) static void xmlAttrSerializeContent(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr attr) { - const xmlChar *cur, *base; xmlNodePtr children; children = attr->children; while (children != NULL) { switch (children->type) { case XML_TEXT_NODE: - base = cur = children->content; - while (*cur != 0) { - if (*cur == '\n') { - if (base != cur) - xmlBufferAdd(buf, base, cur - base); - xmlBufferAdd(buf, BAD_CAST " ", 5); - cur++; - base = cur; - } else if (*cur == '\r') { - if (base != cur) - xmlBufferAdd(buf, base, cur - base); - xmlBufferAdd(buf, BAD_CAST " ", 5); - cur++; - base = cur; - } else if (*cur == '\t') { - if (base != cur) - xmlBufferAdd(buf, base, cur - base); - xmlBufferAdd(buf, BAD_CAST "	", 4); - cur++; - base = cur; -#if 0 - } else if (*cur == '\'') { - if (base != cur) - xmlBufferAdd(buf, base, cur - base); - xmlBufferAdd(buf, BAD_CAST "'", 6); - cur++; - base = cur; -#endif - } else if (*cur == '"') { - if (base != cur) - xmlBufferAdd(buf, base, cur - base); - xmlBufferAdd(buf, BAD_CAST """, 6); - cur++; - base = cur; - } else if (*cur == '<') { - if (base != cur) - xmlBufferAdd(buf, base, cur - base); - xmlBufferAdd(buf, BAD_CAST "<", 4); - cur++; - base = cur; - } else if (*cur == '>') { - if (base != cur) - xmlBufferAdd(buf, base, cur - base); - xmlBufferAdd(buf, BAD_CAST ">", 4); - cur++; - base = cur; - } else if (*cur == '&') { - if (base != cur) - xmlBufferAdd(buf, base, cur - base); - xmlBufferAdd(buf, BAD_CAST "&", 5); - cur++; - base = cur; - } else if ((*cur >= 0x80) && ((doc == NULL) || - (doc->encoding == - NULL))) { - /* - * We assume we have UTF-8 content. - */ - char tmp[10]; - int val = 0, l = 1; - - if (base != cur) - xmlBufferAdd(buf, base, cur - base); - if (*cur < 0xC0) { - xmlSaveErr(XML_SAVE_NOT_UTF8, (xmlNodePtr) attr, - NULL); - if (doc != NULL) - doc->encoding = - xmlStrdup(BAD_CAST "ISO-8859-1"); - snprintf(tmp, sizeof(tmp), "&#%d;", *cur); - tmp[sizeof(tmp) - 1] = 0; - xmlBufferAdd(buf, (xmlChar *) tmp, -1); - cur++; - base = cur; - continue; - } else if (*cur < 0xE0) { - val = (cur[0]) & 0x1F; - val <<= 6; - val |= (cur[1]) & 0x3F; - l = 2; - } else if (*cur < 0xF0) { - val = (cur[0]) & 0x0F; - val <<= 6; - val |= (cur[1]) & 0x3F; - val <<= 6; - val |= (cur[2]) & 0x3F; - l = 3; - } else if (*cur < 0xF8) { - val = (cur[0]) & 0x07; - val <<= 6; - val |= (cur[1]) & 0x3F; - val <<= 6; - val |= (cur[2]) & 0x3F; - val <<= 6; - val |= (cur[3]) & 0x3F; - l = 4; - } - if ((l == 1) || (!IS_CHAR(val))) { - xmlSaveErr(XML_SAVE_CHAR_INVALID, (xmlNodePtr) attr, - NULL); - if (doc != NULL) - doc->encoding = - xmlStrdup(BAD_CAST "ISO-8859-1"); - snprintf(tmp, sizeof(tmp), "&#%d;", *cur); - tmp[sizeof(tmp) - 1] = 0; - xmlBufferAdd(buf, (xmlChar *) tmp, -1); - cur++; - base = cur; - continue; - } - /* - * We could do multiple things here. Just save - * as a char ref - */ - snprintf(tmp, sizeof(tmp), "&#x%X;", val); - tmp[sizeof(tmp) - 1] = 0; - xmlBufferAdd(buf, (xmlChar *) tmp, -1); - cur += l; - base = cur; - } else { - cur++; - } - } - if (base != cur) - xmlBufferAdd(buf, base, cur - base); - break; + xmlAttrSerializeTxtContent(buf, doc, attr, children->content); + break; case XML_ENTITY_REF_NODE: xmlBufferAdd(buf, BAD_CAST "&", 1); xmlBufferAdd(buf, children->name, diff --git a/xmlwriter.c b/xmlwriter.c index 3cda897a..c6df6f29 100644 --- a/xmlwriter.c +++ b/xmlwriter.c @@ -1175,11 +1175,11 @@ xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer, int xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content) { - int count; + int count=0; int sum; xmlLinkPtr lk; xmlTextWriterStackEntry *p; - xmlChar *buf = NULL; + xmlChar *buf=NULL; if (writer == NULL) return -1; @@ -1212,10 +1212,15 @@ xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content) /* fallthrough */ case XML_TEXTWRITER_PI_TEXT: case XML_TEXTWRITER_TEXT: - case XML_TEXTWRITER_ATTRIBUTE: encode: buf = xmlEncodeSpecialChars(NULL, content); + if (buf == NULL) + count = -1; break; + case XML_TEXTWRITER_ATTRIBUTE: + xmlAttrSerializeTxtContent(writer->out->buffer, NULL, + NULL, content); + break; case XML_TEXTWRITER_DTD: count = xmlOutputBufferWriteString(writer->out, " ["); if (count < 0) @@ -1227,6 +1232,8 @@ xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content) case XML_TEXTWRITER_DTD_ELEM: case XML_TEXTWRITER_CDATA: buf = xmlStrdup(content); + if (buf == NULL) + count = -1; break; default: break; @@ -1239,8 +1246,7 @@ xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content) count = xmlOutputBufferWriteString(writer->out, (const char *) buf); xmlFree(buf); - } else - count = -1; + } if (count < 0) return -1; sum += count;