From 3e80560d4bbf2768c90b9a017743ec45f26c3c1c Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Fri, 7 May 2021 10:51:38 +0200 Subject: [PATCH] Fix line numbers in error messages for mismatched tags Commit 62150ed2 introduced a small regression in the error messages for mismatched tags. This typically only affected messages after the first mismatch, but with custom SAX handlers all line numbers would be off. This also fixes line numbers in the SAX push parser which were never handled correctly. --- parser.c | 38 +++++++++++++++++++++++--------------- python/tests/ctxterror.py | 2 +- result/errors/759398.xml.err | 4 ++-- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/parser.c b/parser.c index 73c27ed..c2948ca 100644 --- a/parser.c +++ b/parser.c @@ -1838,6 +1838,8 @@ nodePop(xmlParserCtxtPtr ctxt) * @value: the element name * @prefix: the element prefix * @URI: the element namespace name + * @line: the current line number for error messages + * @nsNr: the number of namespaces pushed on the namespace table * * Pushes a new element name/prefix/URL on top of the name stack * @@ -1845,7 +1847,7 @@ nodePop(xmlParserCtxtPtr ctxt) */ static int nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value, - const xmlChar *prefix, const xmlChar *URI, int nsNr) + const xmlChar *prefix, const xmlChar *URI, int line, int nsNr) { if (ctxt->nameNr >= ctxt->nameMax) { const xmlChar * *tmp; @@ -1860,7 +1862,7 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value, } ctxt->nameTab = tmp; tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab, - ctxt->nameMax * 3 * + ctxt->nameMax * 4 * sizeof(ctxt->pushTab[0])); if (tmp2 == NULL) { ctxt->nameMax /= 2; @@ -1868,16 +1870,17 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value, } ctxt->pushTab = tmp2; } else if (ctxt->pushTab == NULL) { - ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * + ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 4 * sizeof(ctxt->pushTab[0])); if (ctxt->pushTab == NULL) goto mem_error; } ctxt->nameTab[ctxt->nameNr] = value; ctxt->name = value; - ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix; - ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI; - ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (ptrdiff_t) nsNr; + ctxt->pushTab[ctxt->nameNr * 4] = (void *) prefix; + ctxt->pushTab[ctxt->nameNr * 4 + 1] = (void *) URI; + ctxt->pushTab[ctxt->nameNr * 4 + 2] = (void *) (ptrdiff_t) line; + ctxt->pushTab[ctxt->nameNr * 4 + 3] = (void *) (ptrdiff_t) nsNr; return (ctxt->nameNr++); mem_error: xmlErrMemory(ctxt, NULL); @@ -9998,7 +10001,7 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) { return(-1); } if (ctxt->sax2) - nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr); + nameNsPush(ctxt, name, prefix, URI, line, ctxt->nsNr - nsNr); #ifdef LIBXML_SAX1_ENABLED else namePush(ctxt, name); @@ -10095,10 +10098,11 @@ xmlParseElementEnd(xmlParserCtxtPtr ctxt) { * parse the end of tag: 'sax2) { - const xmlChar *prefix = ctxt->pushTab[ctxt->nameNr * 3 - 3]; - const xmlChar *URI = ctxt->pushTab[ctxt->nameNr * 3 - 2]; - int nsNr = (ptrdiff_t) ctxt->pushTab[ctxt->nameNr * 3 - 1]; - xmlParseEndTag2(ctxt, prefix, URI, 0, nsNr, 0); + const xmlChar *prefix = ctxt->pushTab[ctxt->nameNr * 4 - 4]; + const xmlChar *URI = ctxt->pushTab[ctxt->nameNr * 4 - 3]; + int line = (ptrdiff_t) ctxt->pushTab[ctxt->nameNr * 4 - 2]; + int nsNr = (ptrdiff_t) ctxt->pushTab[ctxt->nameNr * 4 - 1]; + xmlParseEndTag2(ctxt, prefix, URI, line, nsNr, 0); namePop(ctxt); } #ifdef LIBXML_SAX1_ENABLED @@ -11373,6 +11377,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { const xmlChar *name; const xmlChar *prefix = NULL; const xmlChar *URI = NULL; + int line = ctxt->input->line; int nsNr = ctxt->nsNr; if ((avail < 2) && (ctxt->inputNr == 1)) @@ -11471,7 +11476,8 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { spacePop(ctxt); } if (ctxt->sax2) - nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr); + nameNsPush(ctxt, name, prefix, URI, line, + ctxt->nsNr - nsNr); #ifdef LIBXML_SAX1_ENABLED else namePush(ctxt, name); @@ -11593,10 +11599,12 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { } if (ctxt->sax2) { xmlParseEndTag2(ctxt, - (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3], - (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0, + (void *) ctxt->pushTab[ctxt->nameNr * 4 - 4], + (void *) ctxt->pushTab[ctxt->nameNr * 4 - 3], + (int) (ptrdiff_t) + ctxt->pushTab[ctxt->nameNr * 4 - 2], (int) (ptrdiff_t) - ctxt->pushTab[ctxt->nameNr * 3 - 1], 0); + ctxt->pushTab[ctxt->nameNr * 4 - 1], 0); nameNsPop(ctxt); } #ifdef LIBXML_SAX1_ENABLED diff --git a/python/tests/ctxterror.py b/python/tests/ctxterror.py index 416e384..ac64624 100755 --- a/python/tests/ctxterror.py +++ b/python/tests/ctxterror.py @@ -10,7 +10,7 @@ import libxml2 libxml2.debugMemory(1) expect="""--> (3) xmlns: URI foo is not absolute ---> (4) Opening and ending tag mismatch: x line 0 and y +--> (4) Opening and ending tag mismatch: x line 1 and y """ err="" diff --git a/result/errors/759398.xml.err b/result/errors/759398.xml.err index bc9e5e0..f6036a3 100644 --- a/result/errors/759398.xml.err +++ b/result/errors/759398.xml.err @@ -1,10 +1,10 @@ ./test/errors/759398.xml:210: parser error : StartTag: invalid element name need to worry about parsers whi ^ ./test/errors/759398.xml:316: parser error : Extra content at the end of the document -- 1.8.3.1