summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiltjo Posthuma <hiltjo@codemadness.org>2018-03-11 16:22:52 +0100
committerHiltjo Posthuma <hiltjo@codemadness.org>2018-03-11 16:22:52 +0100
commit07785ee64d1e750235d0ae47241049b64ed66528 (patch)
tree057b86dab054c50a493c0f217876ac4ed8a280cf
parent875d1b0305f0dc404909907574242ac1740f6426 (diff)
xml: improve CDATA parsing
thanks Svyatoslav Mishyn for the feedback!
-rw-r--r--xml.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/xml.c b/xml.c
index 0e86d34..33c2fef 100644
--- a/xml.c
+++ b/xml.c
@@ -151,36 +151,39 @@ xml_parsecomment(XMLParser *x)
static void
xml_parsecdata(XMLParser *x)
{
- static const char *end = "]]>";
size_t datalen = 0, i = 0;
- char tmp[4];
int c;
if (x->xmlcdatastart)
x->xmlcdatastart(x);
while ((c = x->getnext()) != EOF) {
- if (c == end[i]) {
- if (end[++i] == '\0') { /* end */
+ if (c == ']' || c == '>') {
+ if (x->xmlcdata) {
x->data[datalen] = '\0';
+ x->xmlcdata(x, x->data, datalen);
+ datalen = 0;
+ }
+ }
+
+ if (c == ']') {
+ if (++i > 2) {
if (x->xmlcdata)
- x->xmlcdata(x, x->data, datalen);
- if (x->xmlcdataend)
- x->xmlcdataend(x);
- return;
+ for (; i > 2; i--)
+ x->xmlcdata(x, "]", 1);
+ i = 2;
}
+ continue;
+ } else if (c == '>' && i == 2) {
+ if (x->xmlcdataend)
+ x->xmlcdataend(x);
+ return;
} else if (i) {
- x->data[datalen] = '\0';
- if (x->xmlcdata) {
- if (datalen)
- x->xmlcdata(x, x->data, datalen);
- memcpy(tmp, end, i);
- tmp[i] = '\0';
- x->xmlcdata(x, tmp, i);
- }
- i = 0;
- x->data[0] = c;
- datalen = 1;
- } else if (datalen < sizeof(x->data) - 1) {
+ if (x->xmlcdata)
+ for (; i > 0; i--)
+ x->xmlcdata(x, "]", 1);
+ }
+
+ if (datalen < sizeof(x->data) - 1) {
x->data[datalen++] = c;
} else {
x->data[datalen] = '\0';