Skip to content

Commit 968a03a

Browse files
committed
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
1 parent 264cee6 commit 968a03a

File tree

6 files changed

+64
-16
lines changed

6 files changed

+64
-16
lines changed

SAX2.c

+13-4
Original file line numberDiff line numberDiff line change
@@ -1817,7 +1817,7 @@ xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
18171817
* @str: the input string
18181818
* @len: the string length
18191819
*
1820-
* Remove the entities from an attribute value
1820+
* Callback for a text node
18211821
*
18221822
* Returns the newly allocated string or NULL if not needed or error
18231823
*/
@@ -1850,7 +1850,7 @@ xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
18501850

18511851
if ((len < (int) (2 * sizeof(void *))) &&
18521852
(ctxt->options & XML_PARSE_COMPACT)) {
1853-
/* store the string in the node overrithing properties and nsDef */
1853+
/* store the string in the node overriding properties and nsDef */
18541854
xmlChar *tmp = (xmlChar *) &(ret->properties);
18551855
memcpy(tmp, str, len);
18561856
tmp[len] = 0;
@@ -1882,8 +1882,17 @@ xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
18821882
} else
18831883
ret->content = (xmlChar *) intern;
18841884

1885-
if (ctxt->input != NULL)
1886-
ret->line = ctxt->input->line;
1885+
if (ctxt->linenumbers) {
1886+
if (ctxt->input != NULL) {
1887+
if (ctxt->input->line < 65535)
1888+
ret->line = (short) ctxt->input->line;
1889+
else {
1890+
ret->line = 65535;
1891+
if (ctxt->options & XML_PARSE_BIG_LINES)
1892+
ret->psvi = (void *) ctxt->input->line;
1893+
}
1894+
}
1895+
}
18871896

18881897
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
18891898
xmlRegisterNodeDefaultValue(ret);

error.c

+2
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,8 @@ __xmlRaiseError(xmlStructuredErrorFunc schannel,
530530

531531
if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
532532
line = node->line;
533+
if ((line == 0) || (line == 65535))
534+
line = xmlGetLineNo(node);
533535
}
534536

535537
/*

include/libxml/parser.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,8 @@ typedef enum {
11091109
XML_PARSE_NOBASEFIX = 1<<18,/* do not fixup XINCLUDE xml:base uris */
11101110
XML_PARSE_HUGE = 1<<19,/* relax any hardcoded limit from the parser */
11111111
XML_PARSE_OLDSAX = 1<<20,/* parse using SAX2 interface before 2.7.0 */
1112-
XML_PARSE_IGNORE_ENC= 1<<21 /* ignore internal document encoding hint */
1112+
XML_PARSE_IGNORE_ENC= 1<<21,/* ignore internal document encoding hint */
1113+
XML_PARSE_BIG_LINES = 1<<22 /* Store big lines numbers in text PSVI field */
11131114
} xmlParserOption;
11141115

11151116
XMLPUBFUN void XMLCALL

parser.c

+4
Original file line numberDiff line numberDiff line change
@@ -14965,6 +14965,10 @@ xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encodi
1496514965
ctxt->options |= XML_PARSE_IGNORE_ENC;
1496614966
options -= XML_PARSE_IGNORE_ENC;
1496714967
}
14968+
if (options & XML_PARSE_BIG_LINES) {
14969+
ctxt->options |= XML_PARSE_BIG_LINES;
14970+
options -= XML_PARSE_BIG_LINES;
14971+
}
1496814972
ctxt->linenumbers = 1;
1496914973
return (options);
1497014974
}

tree.c

+42-10
Original file line numberDiff line numberDiff line change
@@ -4528,39 +4528,71 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) {
45284528
************************************************************************/
45294529

45304530
/**
4531-
* xmlGetLineNo:
4531+
* xmlGetLineNoInternal:
45324532
* @node: valid node
4533+
* @depth: used to limit any risk of recursion
45334534
*
4534-
* Get line number of @node. This requires activation of this option
4535-
* before invoking the parser by calling xmlLineNumbersDefault(1)
4535+
* Get line number of @node.
4536+
* Try to override the limitation of lines being store in 16 bits ints
45364537
*
45374538
* Returns the line number if successful, -1 otherwise
45384539
*/
4539-
long
4540-
xmlGetLineNo(xmlNodePtr node)
4540+
static long
4541+
xmlGetLineNoInternal(xmlNodePtr node, int depth)
45414542
{
45424543
long result = -1;
45434544

4545+
if (depth >= 5)
4546+
return(-1);
4547+
45444548
if (!node)
45454549
return result;
45464550
if ((node->type == XML_ELEMENT_NODE) ||
45474551
(node->type == XML_TEXT_NODE) ||
45484552
(node->type == XML_COMMENT_NODE) ||
4549-
(node->type == XML_PI_NODE))
4550-
result = (long) node->line;
4551-
else if ((node->prev != NULL) &&
4553+
(node->type == XML_PI_NODE)) {
4554+
if (node->line == 65535) {
4555+
if ((node->type == XML_TEXT_NODE) && (node->psvi != NULL))
4556+
result = (long) node->psvi;
4557+
else if ((node->type == XML_ELEMENT_NODE) &&
4558+
(node->children != NULL))
4559+
result = xmlGetLineNoInternal(node->children, depth + 1);
4560+
else if (node->next != NULL)
4561+
result = xmlGetLineNoInternal(node->next, depth + 1);
4562+
else if (node->prev != NULL)
4563+
result = xmlGetLineNoInternal(node->prev, depth + 1);
4564+
}
4565+
if ((result == -1) || (result == 65535))
4566+
result = (long) node->line;
4567+
} else if ((node->prev != NULL) &&
45524568
((node->prev->type == XML_ELEMENT_NODE) ||
45534569
(node->prev->type == XML_TEXT_NODE) ||
45544570
(node->prev->type == XML_COMMENT_NODE) ||
45554571
(node->prev->type == XML_PI_NODE)))
4556-
result = xmlGetLineNo(node->prev);
4572+
result = xmlGetLineNoInternal(node->prev, depth + 1);
45574573
else if ((node->parent != NULL) &&
45584574
(node->parent->type == XML_ELEMENT_NODE))
4559-
result = xmlGetLineNo(node->parent);
4575+
result = xmlGetLineNoInternal(node->parent, depth + 1);
45604576

45614577
return result;
45624578
}
45634579

4580+
/**
4581+
* xmlGetLineNo:
4582+
* @node: valid node
4583+
*
4584+
* Get line number of @node.
4585+
* Try to override the limitation of lines being store in 16 bits ints
4586+
* if XML_PARSE_BIG_LINES parser option was used
4587+
*
4588+
* Returns the line number if successful, -1 otherwise
4589+
*/
4590+
long
4591+
xmlGetLineNo(xmlNodePtr node)
4592+
{
4593+
return(xmlGetLineNoInternal(node, 0));
4594+
}
4595+
45644596
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
45654597
/**
45664598
* xmlGetNodePath:

xmllint.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ static xmlStreamCtxtPtr patstream = NULL;
209209
#ifdef LIBXML_XPATH_ENABLED
210210
static const char *xpathquery = NULL;
211211
#endif
212-
static int options = XML_PARSE_COMPACT;
212+
static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
213213
static int sax = 0;
214214
static int oldxml10 = 0;
215215

0 commit comments

Comments
 (0)