1
0
Fork 0

* add xmlInitBuffer() for processing of a preallocated buffer

* add xmlErrorGetColumnNo to get the column number of the syntax error
  * pass an error at a higher level to lower levels
  * detect a number of extra syntax errors
This commit is contained in:
ehofman 2009-04-27 16:54:46 +00:00 committed by Tim Moore
parent 1f40ee2366
commit 228c7aaaa0
5 changed files with 165 additions and 59 deletions

View file

@ -1,3 +1,10 @@
27-04-2009
* add xmlInitBuffer() for processing of a preallocated buffer
* add xmlErrorGetColumnNo to get the column number of the syntax error
* pass an error at a higher level to lower levels
* detect a number of extra syntax errors
* fix a buffer overflow
26-04-2009
* add support for comments inside xml-tags, e.g.: <test><!-- --></test>

View file

@ -47,22 +47,23 @@ Overview of the available functions:
# id = xmlOpen("/tmp/file.xml");
# xmlClose(id);
#
void *xmlOpen(const char *);
void xmlClose(const void *);
void *xmlOpen(const char *filename);
void *xmlInitBuffer(const char *buffer, size_t size);
void xmlClose(void *xid);
#
# Get the Id of a node at the specified path
# e.g.
# xnid = xmlNodeGet(id, "/path/to/specified/node");
#
void *xmlNodeGet(const void *, const char *);
void *xmlNodeCopy(void *, const char *);
void *xmlNodeGet(const void *xid, const char *path);
void *xmlNodeCopy(const void *xid, const char *path);
#
# Functions to walk the node tree and process them one by one.
# e.g.
# xmid = xmlMarkId(id);
# num = xmlNodeGetNum(xmid);
# num = xmlNodeGetNum(xmid, "node");
# for (i=0; i<num; i++) {
# if (xmlNodeGetPos(id, xmid, "element", i) != 0) {
# if ((s = xmlGetString(xmid)) != 0) {
@ -73,15 +74,15 @@ void *xmlNodeCopy(void *, const char *);
# }
# free(xmid);
#
void *xmlMarkId(void *);
unsigned int xmlNodeGetNum(void *, const char *);
void *xmlNodeGetPos(const void *, void *, const char *, int);
void *xmlMarkId(const void *xid);
unsigned int xmlNodeGetNum(const void *xid, const char *path);
void *xmlNodeGetPos(const void *pid, void *xid, const char *element, int pos);
#
# Get the name of the current node
#
char *xmlNodeGetName(void *);
size_t xmlNodeCopyName(void *, const char *, size_t);
char *xmlNodeGetName(const void *xid);
size_t xmlNodeCopyName(const void *xid, const char *buffer, size_t size);
#
# These functions work on the current node.
@ -92,11 +93,11 @@ size_t xmlNodeCopyName(void *, const char *, size_t);
# xnid = xmlNodeGet(id, "/path/to/specified/node");
# if (xmlCompareString(xnid, "value") == 0) printf("We have a match!\n");
#
long int xmlGetInt(void *);
double xmlGetDouble(void *);
char *xmlGetString(void *);
size_t xmlCopyString(void *, char *, const size_t);
int xmlCompareString(const void *, const char *);
long int xmlGetInt(const void *xid);
double xmlGetDouble(const void *xid);
char *xmlGetString(const void *xid);
size_t xmlCopyString(const void *xid, char *buffer, const size_t size);
int xmlCompareString(const void *xid, const char *str);
#
# These functions work on a specified node path
@ -106,11 +107,12 @@ int xmlCompareString(const void *, const char *);
# xnid = xmlNodeGet(id, "/path/to");
# i = xmlNodeGetInt(xnid, "node");
#
long int xmlNodeGetInt(void *, const char *);
double xmlNodeGetDouble(void *, const char *);
char *xmlNodeGetString(void *, const char *);
size_t xmlNodeCopyString(void *, const char *, char *, const size_t);
int xmlNodeCompareString(const void *, const char *, const char *);
long int xmlNodeGetInt(const void *xid, const char *path);
double xmlNodeGetDouble(const void *xid, const char *path);
char *xmlNodeGetString(const void *xid, const char *path);
size_t xmlNodeCopyString(const void *xid, const char *path,
char *buffer, const size_t size);
int xmlNodeCompareString(const void *xid, const char *path, const char *str);
#
# These functions work on a specified atribute
@ -118,15 +120,17 @@ int xmlNodeCompareString(const void *, const char *, const char *);
# i = xmlAttributeGetInt(id, "n");
#
# or
# s = xmlNodeGetString(id, "type");
# s = xmlAttributeGetString(id, "type");
# if (s) printf("node is of type '%s'\n", s);
# free(s);
#
long int xmlAttributeGetInt(const void *, const char *);
double xmlAttributeGetDouble(const void *, const char *);
char *xmlAttributeGetString(const void *, const char *);
size_t xmlAttributeCopyString(const void *, const char *, const char *, size_t);
int xmlAttributeCompareString(const void *, const char *, const char *);
long int xmlAttributeGetInt(const void *xid, const char *attr);
double xmlAttributeGetDouble(const void *xid, const char *attr);
char *xmlAttributeGetString(const void *xid, const char *attr);
size_t xmlAttributeCopyString(const void *xid, const char *attr,
const char *buffer, size_t size);
int xmlAttributeCompareString(const void *xid, const char *attr,
const char *str);
#
# Error detection and reporting functions
@ -136,6 +140,7 @@ int xmlAttributeCompareString(const void *, const char *, const char *);
# int err = xmlErrorGetNo(id, 1); /* clear last error */
# if (err) printf("Error #%i at line %u: '%s'\n", err, err_lineno, err_str);
#
int xmlErrorGetNo(const void *, int);
size_t xmlErrorGetLineNo(const void *, int);
const char *xmlErrorGetString(const void *, int);
int xmlErrorGetNo(const void *xid, int clear);
size_t xmlErrorGetLineNo(const void *xid, int clear);
size_t xmlErrorGetColumnNo(const void *xid, int clear);
const char *xmlErrorGetString(const void *xid, int clear);

View file

@ -46,16 +46,16 @@ typedef struct
#endif
#include <stdlib.h> /* free, malloc */
#include <string.h>
#ifndef _MSC_VER
#include <strings.h> /* strncasecmp */
#else
# define strncasecmp strnicmp
#endif
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
#ifndef _MSC_VER
# include <strings.h> /* strncasecmp */
#else
# define strncasecmp strnicmp
#endif
#ifndef XML_NONVALIDATING
#include "xml.h"
@ -172,6 +172,25 @@ xmlOpen(const char *filename)
return (void *)rid;
}
void *
xmlInitBuffer(const char *buffer, size_t size)
{
struct _root_id *rid = 0;
if (buffer && (size>0))
{
rid->fd = 0;
rid->start = (char *)buffer;
rid->len = size;
rid->name = 0;
#ifndef XML_NONVALIDATING
rid->info = 0;
#endif
}
return (void *)rid;
}
void
xmlClose(void *id)
{
@ -180,8 +199,11 @@ xmlClose(void *id)
assert(rid != 0);
assert(rid->name == 0);
munmap(rid->start, rid->len);
close(rid->fd);
if (rid->fd)
{
munmap(rid->start, rid->len);
close(rid->fd);
}
if (rid->info) free(rid->info);
free(rid);
@ -1183,12 +1205,9 @@ xmlErrorGetLineNo(const void *id, int clear)
while (ps<pe)
{
new = memchr(ps, '\n', pe-ps);
if (new)
{
ps = new;
ret++;
}
ps++;
if (new) ret++;
else break;
ps = new+1;
}
if (clear) err->err_no = 0;
@ -1198,6 +1217,45 @@ xmlErrorGetLineNo(const void *id, int clear)
return ret;
}
size_t
xmlErrorGetColumnNo(const void *id, int clear)
{
size_t ret = 0;
if (id)
{
struct _xml_id *xid = (struct _xml_id *)id;
struct _root_id *rid;
if (xid->name) rid = xid->root;
else rid = (struct _root_id *)xid;
assert(rid != 0);
if (rid->info)
{
struct _xml_error *err = rid->info;
char *ps = rid->start;
char *pe = err->pos;
char *new;
while (ps<pe)
{
new = memchr(ps, '\n', pe-ps);
new = memchr(ps, '\n', pe-ps);
if (new) ret++;
else break;
ps = new+1;
}
ret = pe-ps;
if (clear) err->err_no = 0;
}
}
return ret;
}
const char *
xmlErrorGetString(const void *id, int clear)
{
@ -1334,8 +1392,8 @@ __xmlNodeGetPath(const char *start, size_t *len, char **name, size_t *plen)
char *
__xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *nodenum)
{
char *element, *open, *start_tag=0;
char *new, *cur, *ne, *ret = 0;
char *element, *start_tag=0;
size_t restlen, elementlen;
size_t return_len = 0;
int found, num;
@ -1412,6 +1470,7 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
/*
* get element name and a pointer to after the opening tag
*/
open = cur;
element = *name;
elementlen = *rlen;
len_remaining = restlen;
@ -1514,6 +1573,14 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
new = __xmlNodeGet(cur-1, &slen, &node, &nlen, &pos);
if (!new)
{
if (nlen == 0) /* error upstream */
{
*rlen = nlen;
*name = node;
*len = slen;
return 0;
}
if (slen == restlen)
{
*rlen = 0;
@ -1557,24 +1624,31 @@ __xmlNodeGet(const char *start, size_t *len, char **name, size_t *rlen, size_t *
if (found == num)
{
if (start_tag)
{
*len = new-ret-1;
*name = start_tag;
}
else /* report error */
{
*rlen = 0;
*name = new;
*len = XML_ELEMENT_NO_OPENING_TAG;
return 0;
}
if (start_tag)
{
*len = new-ret-1;
*name = start_tag;
}
else /* report error */
{
*rlen = 0;
*name = new;
*len = XML_ELEMENT_NO_OPENING_TAG;
return 0;
}
}
found++;
}
/* else proper closing tag not yet found, continue. */
/* TODO: could be a bad match to the opening tag though */
/* like: <test></teft> */
#ifndef XML_NONVALIDATING
/* strcmp is a heavy operation when not required */
else if (strncmp(open, new+1, elementlen))
{
*rlen = 0;
*name = new+1;
*len = XML_ELEMENT_NO_CLOSING_TAG;
return 0;
}
#endif
new = memchr(cur, '>', restlen);
if (!new)

View file

@ -52,6 +52,16 @@ enum
*/
void *xmlOpen(const char *);
/**
* Process a section of XML code in a preallocated buffer.
* The buffer may not be free'd until xmlClose has been called.
*
* @param buffer pointer to the buffer
* @param size size of the buffer
* @return XML-id which is used for further processing
*/
void *xmlInitBuffer(const char *, size_t);
/**
* Close the XML file after which no further processing is possible.
*
@ -329,6 +339,15 @@ int xmlErrorGetNo(const void *, int);
*/
size_t xmlErrorGetLineNo(const void *, int);
/**
* Get the column number of the last detected syntax error in the xml file.
*
* @param xid XML-id
* @param clear clear the error state if non zero
* @return the line number of the detected syntax error.
*/
size_t xmlErrorGetColumnNo(const void *, int);
/**
* Get a string that explains the last error.
*

View file

@ -323,8 +323,9 @@ void grep_file(unsigned num)
if (r)
{
size_t n = xmlErrorGetLineNo(xrid, 0);
size_t c = xmlErrorGetColumnNo(xrid, 0);
char *s = xmlErrorGetString(xrid, 1); /* clear the error */
printf("%s: at line %u: '%s'\n",_filenames[num], n, s);
printf("%s: at line %u, column %u: '%s'\n",_filenames[num], n,c, s);
}
free(xrid);