pá 8. 3. 2019 v 7:41 odesílatel Pavel Stehule <pavel.steh...@gmail.com> napsal:
> Hi > > pá 8. 3. 2019 v 3:44 odesílatel Alvaro Herrera <alvhe...@2ndquadrant.com> > napsal: > >> On 2019-Mar-07, Alvaro Herrera wrote: >> >> > On 2019-Feb-11, Chapman Flack wrote: >> > >> > > xmltable-xpath-result-processing-bugfix-6.patch includes a >> regress/expected >> > > output for the no-libxml case that was left out of -5. >> > >> > Pushed this one, with some trivial changes: I renamed and relocated >> > Pavel's function to strdup-and-free and fused the new test cases to use >> > less queries for the same functionality. Naturally I had to adjust the >> > expected files ... I tried to do my best but there's always a little >> > something that sneaks under one's nose. >> >> So we now have a double-free bug here or something ... Too tired right >> now to do anything about it. >> >> >> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=grison&dt=2019-03-08%2002%3A00%3A02 >> >> ================== stack trace: >> pgsql.build/src/test/regress/tmp_check/data/core ================== >> [New LWP 20275] >> >> warning: Can't read pathname for load map: Input/output error. >> [Thread debugging using libthread_db enabled] >> Using host libthread_db library >> "/lib/arm-linux-gnueabihf/libthread_db.so.1". >> Core was generated by `postgres: pgbuildfarm regression [local] SELECT >> '. >> Program terminated with signal 11, Segmentation fault. >> #0 0x76a32e04 in free () from /lib/arm-linux-gnueabihf/libc.so.6 >> #0 0x76a32e04 in free () from /lib/arm-linux-gnueabihf/libc.so.6 >> #1 0x76e28380 in xmlFreeNode () from >> /usr/lib/arm-linux-gnueabihf/libxml2.so.2 >> #2 0x00481f94 in xml_xmlnodetoxmltype (cur=<optimized out>, >> xmlerrcxt=<optimized out>) at xml.c:3751 >> #3 0x004823dc in XmlTableGetValue (state=0x148c370, colnum=1994818404, >> typid=2124685192, typmod=0, isnull=0x7ea42117) at xml.c:4540 >> #4 0x0026df60 in tfuncLoadRows (econtext=0x2, tstate=0x14a8578) at >> nodeTableFuncscan.c:489 >> #5 tfuncFetchRows (tstate=0x14a8578, econtext=0x2) at >> nodeTableFuncscan.c:318 >> #6 0x0026e248 in TableFuncNext (node=0x14a83e0) at nodeTableFuncscan.c:65 >> #7 0x0023e640 in ExecScanFetch (recheckMtd=0x23e640 <ExecScan+816>, >> accessMtd=0x26db1c <TableFuncRecheck>, node=0x14a83e0) at execScan.c:93 >> #8 ExecScan (node=0x14a83e0, accessMtd=0x26db1c <TableFuncRecheck>, >> recheckMtd=0x23e640 <ExecScan+816>) at execScan.c:143 >> #9 0x0023c638 in ExecProcNodeFirst (node=0x14a83e0) at execProcnode.c:445 >> #10 0x00235630 in ExecProcNode (node=0x14a83e0) at >> ../../../src/include/executor/executor.h:241 >> #11 ExecutePlan (execute_once=<optimized out>, dest=0x14b8d08, >> direction=<optimized out>, numberTuples=0, sendTuples=<optimized out>, >> operation=CMD_SELECT, use_parallel_mode=<optimized out>, >> planstate=0x14a83e0, estate=0x14a82a0) at execMain.c:1643 >> #12 standard_ExecutorRun (queryDesc=0x142c0e0, direction=<optimized out>, >> count=0, execute_once=true) at execMain.c:362 >> #13 0x003955f4 in PortalRunSelect (portal=0x13e3f48, forward=<optimized >> out>, count=0, dest=<optimized out>) at pquery.c:929 >> #14 0x00396a0c in PortalRun (portal=0x0, count=0, isTopLevel=<optimized >> out>, run_once=<optimized out>, dest=0x14b8d08, altdest=0x14b8d08, >> completionTag=0x7ea42414 "") at pquery.c:770 >> #15 0x003923c8 in exec_simple_query (query_string=0x7ea42414 "") at >> postgres.c:1215 >> #16 0x00393e8c in PostgresMain (argc=<optimized out>, argv=<optimized >> out>, dbname=0x0, username=<optimized out>) at postgres.c:4256 >> #17 0x000849a8 in BackendRun (port=0x13967b8) at postmaster.c:4399 >> #18 BackendStartup (port=0x13967b8) at postmaster.c:4090 >> #19 ServerLoop () at postmaster.c:1703 >> #20 0x0031607c in PostmasterMain (argc=<optimized out>, argv=<optimized >> out>) at postmaster.c:1376 >> #21 0x000864d4 in main (argc=7301080, argv=0x8) at main.c:228 >> > > looks like error in xmlXPathCompiledEval function, that produce little bit broken result for XML_DOCUMENT_NODE type. I hadn't this problem with libxml2 2.7.6 64bit, but I seen this issue on same version on 32bit. Currently I had not fresh 32 bit system to check it. I found a workaround - in this case copy (and release xmlNode) is not necessary. please, apply attached patch. > Pavel > > >> >> -- >> Álvaro Herrera https://www.2ndQuadrant.com/ >> PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services >> >
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 28b3eaaa20..41145e697a 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -3720,35 +3720,58 @@ xml_xmlnodetoxmltype(xmlNodePtr cur, PgXmlErrorContext *xmlerrcxt) if (cur->type != XML_ATTRIBUTE_NODE && cur->type != XML_TEXT_NODE) { - xmlBufferPtr buf; - xmlNodePtr cur_copy; + volatile xmlBufferPtr buf = NULL; + volatile xmlNodePtr cur_copy = NULL; - buf = xmlBufferCreate(); + PG_TRY(); + { + int bytes; - /* - * The result of xmlNodeDump() won't contain namespace definitions - * from parent nodes, but xmlCopyNode() duplicates a node along with - * its required namespace definitions. - */ - cur_copy = xmlCopyNode(cur, 1); + buf = xmlBufferCreate(); - if (cur_copy == NULL) - xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, - "could not copy node"); + if (buf == NULL || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not allocate xmlBuffer"); + + /* + * The result of xmlNodeDump() won't contain namespace definitions + * from parent nodes, but xmlCopyNode() duplicates a node along with + * its required namespace definitions. + * + * Some older libxml2 like 2.7.6 produces partialy broken + * XML_DOCUMENT_NODE nodes (unset content field). The copy of this node + * is ok, but xmlFreeNode fails. Fortunately, XML_DOCUMENT_NODE should + * not to have parent nodes, and we don't need to use xmlCopyNode. + */ + if (cur->type != XML_DOCUMENT_NODE) + { + cur_copy = xmlCopyNode(cur, 1); + if (cur == NULL || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not copy node"); + } + else + cur_copy = cur; + + bytes = xmlNodeDump(buf, NULL, cur_copy, 0, 1); + if (bytes == -1 || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not dump node"); - PG_TRY(); - { - xmlNodeDump(buf, NULL, cur_copy, 0, 1); result = xmlBuffer_to_xmltype(buf); } PG_CATCH(); { - xmlFreeNode(cur_copy); - xmlBufferFree(buf); + if (cur_copy && cur_copy != cur) + xmlFreeNode(cur_copy); + if (buf) + xmlBufferFree(buf); PG_RE_THROW(); } PG_END_TRY(); - xmlFreeNode(cur_copy); + + if (cur_copy != cur) + xmlFreeNode(cur_copy); xmlBufferFree(buf); } else