]> git.mxchange.org Git - flightgear.git/commitdiff
* add xmlInitBuffer() for processing of a preallocated buffer
authorehofman <ehofman>
Mon, 27 Apr 2009 16:54:46 +0000 (16:54 +0000)
committerTim Moore <timoore@redhat.com>
Fri, 1 May 2009 22:44:21 +0000 (00:44 +0200)
  * 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

utils/xmlgrep/ChangeLog
utils/xmlgrep/README
utils/xmlgrep/xml.c
utils/xmlgrep/xml.h
utils/xmlgrep/xmlgrep.c

index 9d10d5f9d277deeff4c5a613609ebd5781d82c87..47dd69e4f5b45a904eae534a9a8dc38a04be2272 100644 (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>
 
index 5d2fde2e9c7b95c7ad1a4004dda559920f2c14f1..33294ffbd19c639ade5cfd71396839fe802c2e64 100644 (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);
index 051a270dee9f1954dabbfda79eecfbf0a6bc88c3..c41cd4f7b616e463956df95b2fa5cddac45c1619 100644 (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)
index 5602f50b9b0e594fddae341af159cbbba9afd089..88b233df789f78c5a2793465432af7677d5b47e7 100644 (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.
  *
index f163620e1692bd86f397047b7366b2981a0fb626..b428504b204d28fe03519fb7736a1504af0362dc 100644 (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);