# define strncasecmp strnicmp
#endif
-enum
-{
- XML_NO_ERROR = 0,
- XML_OUT_OF_MEMORY,
- XML_FILE_NOT_FOUND,
- XML_TRUNCATE_RESULT,
- XML_ELEMENT_NO_OPENING_TAG,
- XML_ELEMENT_NO_CLOSING_TAG,
- XML_ATTRIB_NO_OPENING_QUOTE,
- XML_ATTRIB_NO_CLOSING_QUOTE,
- XML_MAX_ERROR
-};
+#ifndef XML_NONVALIDATING
+#include "xml.h"
+
static const char *__xml_error_str[XML_MAX_ERROR];
-#ifndef XML_NONVALIDATING
struct _xml_error
{
char *pos;
#endif
};
-static char *__xmlNodeCopy(const char *, size_t, const char *);
+static char *__xmlNodeCopy(const char *, size_t *, const char **);
static char *__xmlNodeGetPath(const char *, size_t *, char **, size_t *);
static char *__xmlNodeGet(const char *, size_t *, char **, size_t *, size_t *);
static char *__xmlCommentSkip(const char *, size_t);
rid->name = 0;
#ifndef XML_NONVALIDATING
rid->info = 0;
- __xmlErrorSet(rid, 0, 0);
#endif
}
}
munmap(rid->start, rid->len);
close(rid->fd);
- free(id);
+
+ if (rid->info) free(rid->info);
+ free(rid);
id = 0;
}
#endif
}
else
+ {
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
+ }
+ }
+ else if (slen == 0)
+ {
+ xmlErrorSet(xid, node, len);
}
return (void *)xsid;
memcpy(xsid->start, ptr, len);
}
else
+ {
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
- }
+ }
+ }
+ else if (slen == 0)
+ {
+ xmlErrorSet(xid, node, len);
+ }
return (void *)xsid;
}
*(ret + len) = 0;
}
else
+ {
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
+ }
return ret;
}
slen -= pathname-nodename;
node = pathname;
p = __xmlNodeGetPath(xid->start, &len, &node, &slen);
+ if (p == 0 && slen == 0)
+ {
+ xmlErrorSet(xid, node, len);
+ }
}
else
{
if (p)
{
- char *node = nodename;
- __xmlNodeGet(p, &len, &node, &slen, &num);
+ char *ret, *node = nodename;
+
+ ret = __xmlNodeGet(p, &len, &node, &slen, &num);
+ if (ret == 0 && slen == 0)
+ {
+ xmlErrorSet(xid, node, len);
+ num = 0;
+ }
}
}
xid->name_len = slen;
ret = xid;
}
+ else if (slen == 0)
+ {
+ xmlErrorSet(xpid, node, len);
+ }
return ret;
}
*(str+nlen) = 0;
}
else
+ {
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
+ }
}
}
if (xid->len)
{
- str = __xmlNodeCopy(xid->start, xid->len, path);
+ size_t len = xid->len;
+ char *node = (char *)path;
+
+ str = __xmlNodeCopy(xid->start, &len, &path);
if (str)
{
char *ps, *pe, *pend;
if (slen && (ps>str)) memmove(str, ps, slen);
else if (!slen) *str = 0;
}
+ else
+ {
+ xmlErrorSet(xid, node, len);
+ }
}
return str;
*(buffer + nlen) = '\0';
ret = nlen;
}
+ else if (slen == 0)
+ {
+ xmlErrorSet(xid, node, nlen);
+ }
}
return ret;
ret = strncasecmp(ps, s, pe-ps);
}
+ else if (slen == 0)
+ {
+ xmlErrorSet(xid, node, len);
+ }
}
return ret;
char *end = str+len;
li = strtol(str, &end, 10);
}
+ else if (slen == 0)
+ {
+ xmlErrorSet(xid, node, len);
+ }
}
return li;
char *end = str+len;
d = strtod(str, &end);
}
+ else if (slen == 0)
+ {
+ xmlErrorSet(xid, node, len);
+ }
}
return d;
}
else
{
- struct _xml_id *xid = (struct _xml_id *)id;
-
- xmid->name = xid->name;
- xmid->start = xid->start;
- xmid->len = xid->len;
- xmid->name_len = xid->name_len;
-#ifndef XML_NONVALIDATING
- xmid->root = xid->root;
-#endif
+ memcpy(xmid, id, sizeof(struct _xml_id));
}
}
else
+ {
xmlErrorSet(id, 0, XML_OUT_OF_MEMORY);
+ }
return (void *)xmid;
}
if (xid->len && xid->name_len)
{
+ size_t slen = strlen(name);
char *ps, *pe;
assert(xid->start > xid->name);
ps = xid->name + xid->name_len + 1;
pe = xid->start - 1;
-
- while ((ps<pe) && isspace(*ps)) ps++;
while (ps<pe)
{
- size_t slen = strlen(name);
- size_t restlen = pe-ps;
-
- if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
+ while ((ps<pe) && isspace(*ps)) ps++;
+ if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
{
ps += slen;
if ((ps<pe) && (*ps == '='))
start = ps;
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
if (ps<pe)
+ {
ret = strtod(start, &ps);
+ }
else
{
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
return 0;
}
}
+ else
+ {
+ while ((ps<pe) && !isspace(*ps)) ps++;
+ continue;
+ }
+
break;
}
while ((ps<pe) && !isspace(*ps)) ps++;
- if (ps<pe)
- while ((ps<pe) && isspace(*ps)) ps++;
}
}
if (xid->len && xid->name_len)
{
+ size_t slen = strlen(name);
char *ps, *pe;
assert(xid->start > xid->name);
ps = xid->name + xid->name_len + 1;
pe = xid->start - 1;
-
- while ((ps<pe) && isspace(*ps)) ps++;
while (ps<pe)
{
- size_t slen = strlen(name);
- size_t restlen = pe-ps;
-
- if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
+ while ((ps<pe) && isspace(*ps)) ps++;
+ if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
{
ps += slen;
if ((ps<pe) && (*ps == '='))
start = ps;
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
if (ps<pe)
+ {
ret = strtol(start, &ps, 10);
+ }
else
{
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
return 0;
}
}
+ else
+ {
+ while ((ps<pe) && isspace(*ps)) ps++;
+ continue;
+ }
+
break;
}
while ((ps<pe) && !isspace(*ps)) ps++;
- if (ps<pe)
- while ((ps<pe) && isspace(*ps)) ps++;
}
}
if (xid->len && xid->name_len)
{
+ size_t slen = strlen(name);
char *ps, *pe;
assert(xid->start > xid->name);
ps = xid->name + xid->name_len + 1;
pe = xid->start - 1;
-
- while ((ps<pe) && isspace(*ps)) ps++;
while (ps<pe)
{
- size_t slen = strlen(name);
- size_t restlen = pe-ps;
-
- if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
+ while ((ps<pe) && isspace(*ps)) ps++;
+ if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
{
ps += slen;
if ((ps<pe) && (*ps == '='))
*(ret+(ps-start)) = '\0';
}
else
+ {
xmlErrorSet(xid, 0, XML_OUT_OF_MEMORY);
+ }
}
else
{
return 0;
}
}
+ else
+ {
+ while ((ps<pe) && !isspace(*ps)) ps++;
+ continue;
+ }
+
+
break;
}
while ((ps<pe) && !isspace(*ps)) ps++;
- if (ps<pe)
- while ((ps<pe) && isspace(*ps)) ps++;
}
}
if (xid->len && xid->name_len)
{
+ size_t slen = strlen(name);
char *ps, *pe;
assert(xid->start > xid->name);
*buffer = '\0';
ps = xid->name + xid->name_len + 1;
pe = xid->start - 1;
-
- while ((ps<pe) && isspace(*ps)) ps++;
while (ps<pe)
{
- size_t slen = strlen(name);
- size_t restlen = pe-ps;
-
- if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
+ while ((ps<pe) && isspace(*ps)) ps++;
+ if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
{
ps += slen;
if ((ps<pe) && (*ps == '='))
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
if (ps<pe)
{
- restlen = ps-start;
+ size_t restlen = ps-start;
if (restlen >= buflen)
{
restlen = buflen-1;
return 0;
}
}
+ else
+ {
+ while ((ps<pe) && isspace(*ps)) ps++;
+ continue;
+ }
+
break;
}
while ((ps<pe) && !isspace(*ps)) ps++;
- if (ps<pe)
- while ((ps<pe) && isspace(*ps)) ps++;
}
}
if (xid->len && xid->name_len && strlen(s))
{
+ size_t slen = strlen(name);
char *ps, *pe;
assert(xid->start > xid->name);
ps = xid->name + xid->name_len + 1;
pe = xid->start - 1;
-
- while ((ps<pe) && isspace(*ps)) ps++;
while (ps<pe)
{
- size_t slen = strlen(name);
- size_t restlen = pe-ps;
-
- if ((restlen > slen) && (strncasecmp(ps, name, slen) == 0))
+ while ((ps<pe) && isspace(*ps)) ps++;
+ if (((size_t)(pe-ps) > slen) && (strncasecmp(ps, name, slen) == 0))
{
ps += slen;
if ((ps<pe) && (*ps == '='))
start = ps;
while ((ps<pe) && (*ps != '"') && (*ps != '\'')) ps++;
if (ps<pe)
+ {
ret = strncasecmp(start, s, ps-start);
+ }
else
{
xmlErrorSet(xid, ps, XML_ATTRIB_NO_CLOSING_QUOTE);
return 0;
}
}
+ else
+ {
+ while ((ps<pe) && !isspace(*ps)) ps++;
+ continue;
+ }
+
break;
}
while ((ps<pe) && !isspace(*ps)) ps++;
- if (ps<pe)
- while ((ps<pe) && isspace(*ps)) ps++;
}
}
#ifndef XML_NONVALIDATING
int
-xmlErrorGetNo(const void *id)
+xmlErrorGetNo(const void *id, int clear)
{
int ret = 0;
struct _xml_error *err = rid->info;
ret = err->err_no;
- err->err_no = 0;
+ if (clear) err->err_no = 0;
}
}
}
size_t
-xmlErrorGetLineNo(const void *id)
+xmlErrorGetLineNo(const void *id, int clear)
{
size_t ret = 0;
char *pe = err->pos;
char *new;
+ ret++;
while (ps<pe)
{
new = memchr(ps, '\n', pe-ps);
}
ps++;
}
+
+ if (clear) err->err_no = 0;
}
}
}
const char *
-xmlErrorGetString(const void *id)
+xmlErrorGetString(const void *id, int clear)
{
char *ret = 0;
{
struct _xml_error *err = rid->info;
if (XML_NO_ERROR <= err->err_no && err->err_no < XML_MAX_ERROR)
+ {
ret = (char *)__xml_error_str[err->err_no];
+ }
else
+ {
ret = "incorrect error number.";
+ }
+
+ if (clear) err->err_no = 0;
}
}
/* -------------------------------------------------------------------------- */
+#ifndef XML_NONVALIDATING
static const char *__xml_error_str[XML_MAX_ERROR] =
{
"no error.",
"unable to allocate enough memory.",
"unable to open file for reading.",
- "provided buffer us too small to hold the result, truncating.",
+ "buffer us too small to hold the result, truncating.",
+ "incorrect comment section.",
+ "bad information block.",
+ "unexpected end of xml section (maybe a missing end tag?)",
+ "element not found.",
"incompatible opening tag for element.",
"missing or invalid closing tag for element.",
"missing or invalid opening quote for attribute.",
"missing or invalid closing quote for attribute."
};
+#endif
char *
-__xmlNodeCopy(const char *start, size_t len, const char *path)
+__xmlNodeCopy(const char *start, size_t *len, const char **path)
{
- char *node, *p, *ret = 0;
- size_t rlen, slen;
-
- rlen = len;
- slen = strlen(path);
- node = (char *)path;
- p = __xmlNodeGetPath(start, &rlen, &node, &slen);
- if (p && rlen)
- {
- ret = malloc(rlen+1);
- if (ret)
- {
- memcpy(ret, p, rlen);
- *(ret+rlen+1) = '\0';
- }
- else
- xmlErrorSet(0, 0, XML_OUT_OF_MEMORY);
- }
-
- return ret;
+ char *node, *p, *ret = 0;
+ size_t rlen, slen;
+
+ rlen = *len;
+ slen = strlen(*path);
+ node = (char *)*path;
+ p = __xmlNodeGetPath(start, &rlen, &node, &slen);
+ if (p && rlen)
+ {
+ ret = malloc(rlen+1);
+ if (ret)
+ {
+ memcpy(ret, p, rlen);
+ *(ret+rlen+1) = '\0';
+ }
+ else
+ {
+ xmlErrorSet(0, 0, XML_OUT_OF_MEMORY);
+ }
+ }
+ else if (slen == 0)
+ {
+ *path = node;
+ *len = rlen;
+ }
+
+ return ret;
}
char *
char *node;
char *ret = 0;
- assert (start != 0);
- assert (len != 0);
- assert (name != 0);
- assert (*name != 0);
- assert (plen != 0);
+ assert(start != 0);
+ assert(len != 0);
+ assert(name != 0);
+ assert(*name != 0);
+ assert(plen != 0);
+ assert(*plen != 0);
if ((*len == 0) || (*plen == 0) || (*plen > *len))
return 0;
if (!path) plen = slen;
else plen = path++ - node;
- num = 0;
- ret = __xmlNodeGet(start, len, &node, &plen, &num);
- if (ret && path)
+ if (path)
{
- plen = slen - (path - *name);
- ret = __xmlNodeGetPath(ret, len, &path, &plen);
+ num = 0;
+ ret = __xmlNodeGet(start, len, &node, &plen, &num);
+ if (ret)
+ {
+ plen = slen - (path - *name);
+ ret = __xmlNodeGetPath(ret, len, &path, &plen);
+ *name = path;
+ }
+ else if (plen == 0)
+ {
+ *name = node;
+ }
}
-
- *name = path;
}
return ret;
size_t retlen = 0;
int found, num;
- assert (start != 0);
- assert (len != 0);
- assert (name != 0);
- assert (*name != 0);
- assert (rlen != 0);
- assert (nodenum != 0);
+ assert(start != 0);
+ assert(len != 0);
+ assert(*len != 0);
+ assert(name != 0);
+ assert(*name != 0);
+ assert(rlen != 0);
+ assert(*rlen != 0);
+ assert(nodenum != 0);
- if ((*len == 0) || (*rlen == 0) || (*rlen > *len))
+ if (*rlen > *len)
+ {
+ *rlen = 0;
+ *name = start;
+ *len = XML_UNEXPECTED_EOF;
return 0;
+ }
found = 0;
num = *nodenum;
if (*cur == '!')
{
new = __xmlCommentSkip(cur, restlen);
- if (!new) return 0;
+ if (!new)
+ {
+ *rlen = 0;
+ *name = cur;
+ *len = XML_INVALID_COMMENT;
+ return 0;
+ }
restlen -= new-cur;
cur = new;
continue;
else if (*cur == '?')
{
new = __xmlInfoProcess(cur, restlen);
- if (!new) return 0;
+ if (!new)
+ {
+ *rlen = 0;
+ *name = cur;
+ *len = XML_INVALID_INFO_BLOCK;
+ return 0;
+ }
restlen -= new-cur;
cur = new;
if (new)
{
retlen = elementlen;
- if (found == num )
+ if (found == num)
{
- ret = new+1;
- start_tag = element;
+ ret = new+1;
+ start_tag = element;
+ *rlen = elementlen;
}
else start_tag = 0;
}
else
{
new = cur+elementlen;
- if (new >= ne) return 0;
+ if (new >= ne)
+ {
+ *rlen = 0;
+ *name = cur;
+ *len = XML_UNEXPECTED_EOF;
+ return 0;
+ }
element = *name;
}
+ if (*(new-1) == '/') /* e.g. <test/> */
+ {
+ if (found == num)
+ {
+ *len = 0;
+ *name = start_tag;
+ }
+ found++;
+
+ if ((restlen < 1) || (*new != '>'))
+ {
+ *rlen = 0;
+ *name = cur;
+ *len = XML_ELEMENT_NO_CLOSING_TAG;
+ return 0;
+ }
+
+ restlen -= new+1-cur;
+ cur = new+1;
+ continue;
+ }
+
/* restlen -= new-cur; not necessary because of __xml_memncasecmp */
cur = new;
new = memchr(cur, '<', restlen);
- if (!new) return 0;
+ if (!new)
+ {
+ *rlen = 0;
+ *name = cur;
+ *len = XML_ELEMENT_NO_CLOSING_TAG;
+ return 0;
+ }
restlen -= new-cur;
cur = new;
new = __xmlNodeGet(cur, &slen, &node, &nlen, &pos);
if (!new)
{
- if (slen == restlen) return 0;
+ if (slen == restlen)
+ {
+ *rlen = 0;
+ *name = cur;
+ *len = XML_UNEXPECTED_EOF;
+ return 0;
+ }
else new = cur + slen;
}
cur = new;
new = memchr(cur, '<', restlen);
- if (!new) return 0;
+ if (!new)
+ {
+ *rlen = 0;
+ *name = cur;
+ *len = XML_ELEMENT_NO_CLOSING_TAG;
+ return 0;
+ }
restlen -= new-cur;
cur = new;
{
if (!strncasecmp(new+2, element, elementlen))
{
- if (found == num)
+ if (found == num)
{
- assert(start_tag != 0);
- *len = new-ret;
- *name = start_tag;
+ if (start_tag)
+ {
+ *len = new-ret;
+ *name = start_tag;
+ }
+ else /* report error */
+ {
+ *rlen = 0;
+ *name = new;
+ *len = XML_ELEMENT_NO_OPENING_TAG;
+ return 0;
+ }
}
found++;
}
new = memchr(cur, '>', restlen);
- if (!new) return 0;
+ if (!new)
+ {
+ *rlen = 0;
+ *name = cur;
+ *len = XML_ELEMENT_NO_CLOSING_TAG;
+ return 0;
+ }
restlen -= new-cur;
cur = new;
}
- else return 0;
+ else
+ {
+ *rlen = 0;
+ *name = cur;
+ return 0;
+ }
}
- *rlen = retlen;
- *nodenum = found;
+ if ((ret == 0) && (start_tag == 0) && (*rlen > 1))
+ {
+ ret = 0;
+ *rlen = 0;
+ *name = start_tag;
+ *len = XML_ELEMENT_NOT_FOUND;
+ }
+ else
+ {
+ *rlen = retlen;
+ *nodenum = found;
+ }
return ret;
}
if (memcmp(cur, "!--", 3) == 0)
{
- if (len < 6) return 0;
+ if (len < 6) return 0; /* <!-- --> */
cur += 3;
len -= 3;
-
do
{
new = memchr(cur, '-', len);
if (*cur == '?')
{
- if (len < 3) return 0;
+ if (len < 3) return 0; /* <? ?> */
cur++;
len--;
{
char *he = hs + *haystacklen;
- while ((hs < he) && (*hs != ' ') && (*hs != '>')) hs++;
+ while ((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
*needle = (char *)haystack;
*needlelen = hs - haystack;
while ((hs < he) && (*hs != '>')) hs++;
for (i=0; i<nlen; i++)
{
if (NOCASECMP(*hs,*ns) && (*ns != '?')) break;
- if ((*hs == ' ') || (*hs == '>')) break;
+ if (isspace(*hs) || (*hs == '>')) break;
hs++;
ns++;
}
if (i != nlen)
{
- while((hs < he) && (*hs != ' ') && (*hs != '>')) hs++;
+ while((hs < he) && !isspace(*hs) && (*hs != '>')) hs++;
*needle = (char *)haystack;
*needlelen = hs - haystack;
}
else
{
+ int found = (isspace(*hs) || (*hs == '>'));
+
*needle = (char *)haystack;
*needlelen = hs - haystack;
+
while ((hs < he) && (*hs != '>')) hs++;
- rptr = hs;
+
+ if (!found) *needlelen = hs - haystack;
+ else rptr = hs;
}
}
else rid = (struct _root_id *)xid;
assert(rid != 0);
-
if (rid->info == 0)
+ {
rid->info = malloc(sizeof(struct _xml_error));
+ }
if (rid->info)
{