After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 787941 - Evaluating an XPath expression with an variable after variables were unregistered does not report error
Evaluating an XPath expression with an variable after variables were unregist...
Status: RESOLVED FIXED
Product: libxml2
Classification: Platform
Component: xpath
git master
Other Linux
: Normal normal
: ---
Assigned To: Nick Wellnhofer
https://rt.cpan.org/Public/Bug/Displa...
Depends on:
Blocks:
 
 
Reported: 2017-09-20 13:22 UTC by Petr Pisar
Modified: 2017-09-20 14:25 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Petr Pisar 2017-09-20 13:22:50 UTC
After upgrading libxml2 from 2.9.4 to 2.9.5, XML-LibXML-2.0129, a Perl binding to libxml2, tests started to fail <https://rt.cpan.org/Public/Bug/Display.html?id=122958>. One of the failures, t/32xpc_variables.t line 114, looks like a new bug in libxml2.

The change is that evaluating an XPath expression that uses a variable after unregistering variables stopped reporting an error.

If you compile this C code:

#include <stdio.h>
#include <string.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>

void die(const char* message) {
    fprintf(stderr, "%s\n", message);
    exit(EXIT_FAILURE);
}

xmlXPathObjectPtr getvariable(void *ctx, const xmlChar *name,
        const xmlChar *ns) {
    if (NULL == name) return NULL;
    if (!strcmp(name, "a")) {
        return xmlXPathNewFloat(2.0);
    }
    return NULL;
}

int main(void) {
    xmlDocPtr document;
    xmlXPathContextPtr xpath_ctx;
    xmlXPathObjectPtr xpath_object;
    xmlXPathVariablePtr variable;

    document = xmlParseDoc(BAD_CAST "<foo><bar a=\"b\">Bla</bar><bar/></foo>");
    if (!document) die("xmlParseDoc failed\n");

    xpath_ctx = xmlXPathNewContext(document);
    if (!xpath_ctx) die("xmlXPathNewContext failed");

    xmlXPathRegisterVariableLookup(xpath_ctx, getvariable, NULL);
    xmlXPathRegisterVariableLookup(xpath_ctx, NULL, NULL);

    xpath_object = xmlXPathEval("$a", xpath_ctx);
    if (!xpath_object) die("xmlXPathEval failed");

    xmlXPathFreeObject(xpath_object);
    xmlXPathFreeContext(xpath_ctx);
    xmlFreeDoc(document);
    exit(EXIT_SUCCESS);
}


It prints these two lines with 2.9.4:

$ ./a.out 
xmlXPathEval: evaluation failed
xmlXPathEval failed

while 2.9.5 is missing the first line, the libxml error message:

$ ./a.out 
xmlXPathEval failed

This causes the Perl binding's test failure because the binding intercepts errors and checks them.

The xmlXPathEval() still returns NULL in both cases, but the error reported via libxml2's error reporting mechanism is missing. I think this is a bug.

This change was introduced by this commit:

commit c851970c6ec2166df804b1d551df0998de182fc4
Author: Nick Wellnhofer <wellnhofer@aevum.de>
Date:   Sat May 27 15:26:11 2017 +0200

    Rework final handling of XPath results
    
    Move cleanup of XPath stack to xmlXPathFreeParserContext. This avoids
    memory leaks if valuePop fails in some error cases. Found with
    libFuzzer and ASan.
    
    Rework handling of the final XPath result object in
    xmlXPathCompiledEvalInternal and xmlXPathEval to avoid useless error
    messages.
Comment 1 Nick Wellnhofer 2017-09-20 14:25:34 UTC
Fixed with https://git.gnome.org/browse/libxml2/commit/?id=3157cf4e53c03bc3da604472c015c63141907db8

Thanks for the report.