#1035554 libxml2-utils: xmllint ignores --output option and writes to stdout

Package:
libxml2-utils
Source:
libxml2-utils
Description:
GNOME XML library - utilities
Submitter:
Tj
Date:
2024-02-21 06:15:04 UTC
Severity:
normal
Tags:
#1035554#5
Date:
2023-05-05 10:51:05 UTC
From:
To:
xmllint is ignoring --output FILE option. I've done a debug run with gdb and it correctly reads the option and assigns its value to the 'output' variable but doesn't read that variable before writing the output. Confirmed with gdb's hardware watch `awatch output`. The final trace before the output is written to stdout is:

3701                if (repeat) {
(gdb) n
3724                    nbregister = 0;
(gdb) n
3727                    if (stream != 0)
(gdb) n
3731                    if (sax) {
(gdb) n
3734                        parseAndPrintFile(argv[i], NULL);



$ xmllint --output test.txt --html --xpath '//div[contains(@class, '\''test'\'')]/div/ul/li/a/@href' xmllint-test.html
 href="test0.html"
 href="test1.html"
 href="test2.html"
 href="test3.html"
 href="test4.html"
 href="test5.html"
 href="test6.html"
 href="test7.html"
 href="test8.html"
 href="test9.html"

$ cat xmllint-test.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>xmllint test --output</title>
 </head>
 <body>
  <h1>xmllint test --output</h1>
  <div class="test">
   <div>
    <ul>
     <li><a href="test0.html">test0</a></li>
     <li><a href="test1.html">test1</a></li>
     <li><a href="test2.html">test2</a></li>
     <li><a href="test3.html">test3</a></li>
     <li><a href="test4.html">test4</a></li>
     <li><a href="test5.html">test5</a></li>
     <li><a href="test6.html">test6</a></li>
     <li><a href="test7.html">test7</a></li>
     <li><a href="test8.html">test8</a></li>
     <li><a href="test9.html">test9</a></li>
    </ul>
   </div>
  </div>
 </body>
</html>

#1035554#10
Date:
2023-05-05 14:23:21 UTC
From:
To:
I've done some follow-up debugging (on upstream git) to be sure the
problem seems to exist upstream - unless I'm severely misunderstanding
what --output is supposed to do. Anyhow; the trace shows it reaches
doXPathDump(). Note that 'buf' is hard-coded to use stdout. The call to
xmlOutputBufferClose(buf) causes the output to be sent. In gdb I confirm
'output' is set immediately after that:

$ gdb -directory /srv/NAS/Sunny/SourceCode/libxml2/libxml2 -args
/srv/NAS/Sunny/SourceCode/libxml2/libxml2/.libs/xmllint --output
test.txt --html --xpath '//div[contains(@class,
'\''test'\'')]/div/ul/li/a/@href' xmllint-test.html

2038                break;
(gdb) p output
$1 = 0x7fffffffe1d5 "test.txt"

xmllint.c:

static void doXPathDump(xmlXPathObjectPtr cur) {
     switch(cur->type) {
         case XPATH_NODESET: {
             int i;
             xmlNodePtr node;
#ifdef LIBXML_OUTPUT_ENABLED
             xmlOutputBufferPtr buf;

             if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr
<= 0)) {
                 if (!quiet) {
                     fprintf(stderr, "XPath set is empty\n");
                 }
                 break;
             }
             buf = xmlOutputBufferCreateFile(stdout, NULL);
             if (buf == NULL) {
                 fprintf(stderr, "Out of memory for XPath\n");
                 progresult = XMLLINT_ERR_MEM;
                 return;
             }
             for (i = 0;i < cur->nodesetval->nodeNr;i++) {
                 node = cur->nodesetval->nodeTab[i];
                 xmlNodeDumpOutput(buf, NULL, node, 0, 0, NULL);
                 xmlOutputBufferWrite(buf, 1, "\n");
             }
             xmlOutputBufferClose(buf);