summaryrefslogtreecommitdiffstats
path: root/src/sax.c
diff options
context:
space:
mode:
authorunknown <unknown@unknown>2009-10-23 04:30:00 +0000
committerunknown <unknown@unknown>2009-10-23 04:30:00 +0000
commit1bd02c3f58179927245376d9f0762d19a351df23 (patch)
treeef00b2976f8e4e9a20277f1aa883c406e4935ebe /src/sax.c
parentddf5c42f67757000d6ec7686b92a667c2a252dca (diff)
downloadiksemel-1bd02c3f58179927245376d9f0762d19a351df23.tar.gz
iksemel-1bd02c3f58179927245376d9f0762d19a351df23.tar.xz
iksemel-1bd02c3f58179927245376d9f0762d19a351df23.zip
Imported from iksemel-1.4.tar.gz.vendor
Diffstat (limited to 'src/sax.c')
-rw-r--r--src/sax.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/src/sax.c b/src/sax.c
index cb3caef..66b964d 100644
--- a/src/sax.c
+++ b/src/sax.c
@@ -1,5 +1,5 @@
/* iksemel (XML parser for Jabber)
-** Copyright (C) 2000-2004 Gurer Ozen <madcat@e-kolay.net>
+** Copyright (C) 2000-2004 Gurer Ozen
** This code is free software; you can redistribute it and/or
** modify it under the terms of GNU Lesser General Public License.
*/
@@ -70,6 +70,7 @@ struct iksparser_struct {
int uni_max;
int uni_len;
+ unsigned int uni_char;
};
iksparser *
@@ -208,8 +209,24 @@ sax_core (iksparser *prs, char *buf, int len)
if (0 == c || 0xFE == c || 0xFF == c) return IKS_BADXML;
if (prs->uni_max) {
if ((c & 0xC0) != 0x80) return IKS_BADXML;
+ prs->uni_char <<= 6;
+ prs->uni_char += (c & 0x3f);
prs->uni_len++;
- if (prs->uni_len == prs->uni_max) prs->uni_max = 0;
+ if (prs->uni_len == prs->uni_max) {
+ /* Security check: avoid overlong sequences */
+ if (prs->uni_max == 2 && prs->uni_char < 0x80)
+ return IKS_BADXML;
+ if (prs->uni_max == 3 && prs->uni_char < 0x7FF)
+ return IKS_BADXML;
+ if (prs->uni_max == 4 && prs->uni_char < 0xffff)
+ return IKS_BADXML;
+ if (prs->uni_max == 5 && prs->uni_char < 0x1fffff)
+ return IKS_BADXML;
+ if (prs->uni_max == 6 && prs->uni_char < 0x3ffffff)
+ return IKS_BADXML;
+ prs->uni_max = 0;
+ prs->uni_char = 0;
+ }
goto cont;
} else {
if (c & 0x80) {
@@ -232,7 +249,7 @@ sax_core (iksparser *prs, char *buf, int len)
} else {
return IKS_BADXML;
}
- if ((c & mask) == 0) return IKS_BADXML;
+ prs->uni_char = c & mask;
prs->uni_len = 1;
if (stack_old == -1
&& (prs->context == C_TAG
@@ -350,7 +367,7 @@ sax_core (iksparser *prs, char *buf, int len)
memset (prs->atts, 0, sizeof(char *) * 2 * 12);
prs->attcur = 0;
} else {
- if (prs->attcur >= (prs->attmax * 2)) {
+ if (prs->attcur >= ((prs->attmax - 1) * 2)) {
void *tmp;
prs->attmax += 12;
tmp = iks_malloc (sizeof(char *) * 2 * prs->attmax);
@@ -375,6 +392,14 @@ sax_core (iksparser *prs, char *buf, int len)
prs->context = C_VALUE;
break;
}
+ if (IS_WHITESPACE(c)) {
+ if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
+ stack_old = -1;
+ STACK_PUSH_END;
+ prs->oldcontext = C_ATTRIBUTE_1;
+ prs->context = C_WHITESPACE;
+ break;
+ }
if (stack_old == -1) stack_old = pos;
break;
@@ -396,6 +421,7 @@ sax_core (iksparser *prs, char *buf, int len)
break;
case C_VALUE:
+ if (IS_WHITESPACE(c)) break;
prs->atts[prs->attcur + 1] = STACK_PUSH_START;
if ('\'' == c) {
prs->context = C_VALUE_APOS;
@@ -622,6 +648,7 @@ iks_parser_reset (iksparser *prs)
prs->nr_lines = 0;
prs->uni_max = 0;
prs->uni_len = 0;
+ prs->uni_char = 0;
}
void