Skip to content

Commit

Permalink
Add support for big line numbers in error reporting
Browse files Browse the repository at this point in the history
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
  • Loading branch information
veillard committed Aug 13, 2012
1 parent 264cee6 commit 968a03a
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 16 deletions.
17 changes: 13 additions & 4 deletions SAX2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1882,8 +1882,17 @@ xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
} 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);
Expand Down
2 changes: 2 additions & 0 deletions error.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/*
Expand Down
3 changes: 2 additions & 1 deletion include/libxml/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
52 changes: 42 additions & 10 deletions tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion xmllint.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 968a03a

Please sign in to comment.