[libxml2] Add support for big line numbers in error reporting



commit 968a03a2e54f5bcf53089f5e3c8f790dbe0bf824
Author: Daniel Veillard <veillard redhat com>
Date:   Mon Aug 13 12:41:33 2012 +0800

    Add support for big line numbers in error reporting
    
    Fix the lack of line number as reported by Johan Corveleyn <jcorvel gmail com>
    
    * parser.c include/libxml/parser.h: add an XML_PARSE_BIG_LINES parser
      option not switch on by default, it's an opt-in
    * SAX2.c: if XML_PARSE_BIG_LINES is set store the long line numbers
      in the psvi field of text nodes
    * tree.c: expand xmlGetLineNo to extract those informations, also
      make sure we can't fail on recursive behaviour
    * error.c: in __xmlRaiseError, if a node is provided, call
      xmlGetLineNo() if we can't get a valid line number.
    * xmllint.c: switch on XML_PARSE_BIG_LINES in xmllint

 SAX2.c                  |   17 +++++++++++---
 error.c                 |    2 +
 include/libxml/parser.h |    3 +-
 parser.c                |    4 +++
 tree.c                  |   52 +++++++++++++++++++++++++++++++++++++---------
 xmllint.c               |    2 +-
 6 files changed, 64 insertions(+), 16 deletions(-)
---
diff --git a/SAX2.c b/SAX2.c
index 62ddcb2..94db7da 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -1817,7 +1817,7 @@ xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
  * @str:  the input string
  * @len: the string length
  * 
- * Remove the entities from an attribute value
+ * Callback for a text node
  *
  * Returns the newly allocated string or NULL if not needed or error
  */
@@ -1850,7 +1850,7 @@ xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
 
 	if ((len < (int) (2 * sizeof(void *))) &&
 	    (ctxt->options & XML_PARSE_COMPACT)) {
-	    /* store the string in the node overrithing properties and nsDef */
+	    /* store the string in the node overriding properties and nsDef */
 	    xmlChar *tmp = (xmlChar *) &(ret->properties);
 	    memcpy(tmp, str, len);
 	    tmp[len] = 0;
@@ -1882,8 +1882,17 @@ skip:
     } else
 	ret->content = (xmlChar *) intern;
 
-    if (ctxt->input != NULL)
-        ret->line = ctxt->input->line;
+    if (ctxt->linenumbers) {
+	if (ctxt->input != NULL) {
+	    if (ctxt->input->line < 65535)
+		ret->line = (short) ctxt->input->line;
+	    else {
+	        ret->line = 65535;
+		if (ctxt->options & XML_PARSE_BIG_LINES)
+		    ret->psvi = (void *) ctxt->input->line;
+	    }
+	}
+    }
 
     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
 	xmlRegisterNodeDefaultValue(ret);
diff --git a/error.c b/error.c
index cd48cb5..b5e4c28 100644
--- a/error.c
+++ b/error.c
@@ -530,6 +530,8 @@ __xmlRaiseError(xmlStructuredErrorFunc schannel,
 
 	if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
 	    line = node->line;
+	if ((line == 0) || (line == 65535))
+	    line = xmlGetLineNo(node);
     }
 
     /*
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index 04edb9d..1f11fd9 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -1109,7 +1109,8 @@ typedef enum {
     XML_PARSE_NOBASEFIX = 1<<18,/* do not fixup XINCLUDE xml:base uris */
     XML_PARSE_HUGE      = 1<<19,/* relax any hardcoded limit from the parser */
     XML_PARSE_OLDSAX    = 1<<20,/* parse using SAX2 interface before 2.7.0 */
-    XML_PARSE_IGNORE_ENC= 1<<21 /* ignore internal document encoding hint */
+    XML_PARSE_IGNORE_ENC= 1<<21,/* ignore internal document encoding hint */
+    XML_PARSE_BIG_LINES = 1<<22 /* Store big lines numbers in text PSVI field */
 } xmlParserOption;
 
 XMLPUBFUN void XMLCALL
diff --git a/parser.c b/parser.c
index 3d44dc1..5b075ce 100644
--- a/parser.c
+++ b/parser.c
@@ -14965,6 +14965,10 @@ xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encodi
 	ctxt->options |= XML_PARSE_IGNORE_ENC;
         options -= XML_PARSE_IGNORE_ENC;
     }
+    if (options & XML_PARSE_BIG_LINES) {
+	ctxt->options |= XML_PARSE_BIG_LINES;
+        options -= XML_PARSE_BIG_LINES;
+    }
     ctxt->linenumbers = 1;
     return (options);
 }
diff --git a/tree.c b/tree.c
index be9b55a..df6f608 100644
--- a/tree.c
+++ b/tree.c
@@ -4528,39 +4528,71 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) {
  ************************************************************************/
 
 /**
- * xmlGetLineNo:
+ * xmlGetLineNoInternal:
  * @node: valid node
+ * @depth: used to limit any risk of recursion
  *
- * Get line number of @node. This requires activation of this option
- * before invoking the parser by calling xmlLineNumbersDefault(1)
+ * Get line number of @node.
+ * Try to override the limitation of lines being store in 16 bits ints
  *
  * Returns the line number if successful, -1 otherwise
  */
-long
-xmlGetLineNo(xmlNodePtr node)
+static long
+xmlGetLineNoInternal(xmlNodePtr node, int depth)
 {
     long result = -1;
 
+    if (depth >= 5)
+        return(-1);
+
     if (!node)
         return result;
     if ((node->type == XML_ELEMENT_NODE) ||
         (node->type == XML_TEXT_NODE) ||
 	(node->type == XML_COMMENT_NODE) ||
-	(node->type == XML_PI_NODE))
-        result = (long) node->line;
-    else if ((node->prev != NULL) &&
+	(node->type == XML_PI_NODE)) {
+	if (node->line == 65535) {
+	    if ((node->type == XML_TEXT_NODE) && (node->psvi != NULL))
+	        result = (long) node->psvi;
+	    else if ((node->type == XML_ELEMENT_NODE) &&
+	             (node->children != NULL))
+	        result = xmlGetLineNoInternal(node->children, depth + 1);
+	    else if (node->next != NULL)
+	        result = xmlGetLineNoInternal(node->next, depth + 1);
+	    else if (node->prev != NULL)
+	        result = xmlGetLineNoInternal(node->prev, depth + 1);
+	}
+	if ((result == -1) || (result == 65535))
+	    result = (long) node->line;
+    } else if ((node->prev != NULL) &&
              ((node->prev->type == XML_ELEMENT_NODE) ||
 	      (node->prev->type == XML_TEXT_NODE) ||
 	      (node->prev->type == XML_COMMENT_NODE) ||
 	      (node->prev->type == XML_PI_NODE)))
-        result = xmlGetLineNo(node->prev);
+        result = xmlGetLineNoInternal(node->prev, depth + 1);
     else if ((node->parent != NULL) &&
              (node->parent->type == XML_ELEMENT_NODE))
-        result = xmlGetLineNo(node->parent);
+        result = xmlGetLineNoInternal(node->parent, depth + 1);
 
     return result;
 }
 
+/**
+ * xmlGetLineNo:
+ * @node: valid node
+ *
+ * Get line number of @node.
+ * Try to override the limitation of lines being store in 16 bits ints
+ * if XML_PARSE_BIG_LINES parser option was used
+ *
+ * Returns the line number if successful, -1 otherwise
+ */
+long
+xmlGetLineNo(xmlNodePtr node)
+{
+    return(xmlGetLineNoInternal(node, 0));
+}
+
 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
 /**
  * xmlGetNodePath:
diff --git a/xmllint.c b/xmllint.c
index 8c1ca8a..78db222 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -209,7 +209,7 @@ static xmlStreamCtxtPtr patstream = NULL;
 #ifdef LIBXML_XPATH_ENABLED
 static const char *xpathquery = NULL;
 #endif
-static int options = XML_PARSE_COMPACT;
+static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
 static int sax = 0;
 static int oldxml10 = 0;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]