Suppress "chunk is not well balanced" errors from libxml2.
authorTom Lane <[email protected]>
Tue, 9 Jul 2024 19:01:05 +0000 (15:01 -0400)
committerTom Lane <[email protected]>
Tue, 9 Jul 2024 19:01:13 +0000 (15:01 -0400)
libxml2 2.13 has an entirely different rule than earlier versions
about when to emit "chunk is not well balanced" errors.  This
causes regression test output discrepancies for three test cases
that formerly provoked that error (along with others) and now don't.

Closer inspection shows that at least in 2.13, this error is pretty
useless because it can only be emitted after some other more-relevant
error.  So let's get rid of the cross-version discrepancy by just
suppressing it.  In case some older libxml2 version is capable of
emitting this error by itself, suppress only when some other error
has already been captured.

Like 066e8ac6e and 6082b3d5d, this will need to be back-patched,
but let's check the results in HEAD first.  (The patch for xml_2.out,
in particular, is blind since I can't test it here.)

Erik Wienhold and Tom Lane, per report from Frank Streitzig.

Discussion: https://postgr.es/m/trinity-b0161630-d230-4598-9ebc-7a23acdb37cb-1720186432160@3c-app-gmx-bap25
Discussion: https://postgr.es/m/trinity-361ba18b-541a-4fe7-bc63-655ae3a7d599-1720259822452@3c-app-gmx-bs01

src/backend/utils/adt/xml.c
src/test/regress/expected/xml.out
src/test/regress/expected/xml_1.out
src/test/regress/expected/xml_2.out
src/test/regress/sql/xml.sql

index 8893be568269341cce55c25863bf53d7835eb0da..447e72b21eb4454dc52f043f03a3ede4393d0b8e 100644 (file)
@@ -2114,6 +2114,19 @@ xml_errorHandler(void *data, PgXmlErrorPtr error)
    switch (domain)
    {
        case XML_FROM_PARSER:
+
+           /*
+            * XML_ERR_NOT_WELL_BALANCED is typically reported after some
+            * other, more on-point error.  Furthermore, libxml2 2.13 reports
+            * it under a completely different set of rules than prior
+            * versions.  To avoid cross-version behavioral differences,
+            * suppress it so long as we already logged some error.
+            */
+           if (error->code == XML_ERR_NOT_WELL_BALANCED &&
+               xmlerrcxt->err_occurred)
+               return;
+           /* fall through */
+
        case XML_FROM_NONE:
        case XML_FROM_MEMORY:
        case XML_FROM_IO:
index 6500cff885d10a78dad632c6807c7e2939d89a0a..d6a51f9e38c06ebd364c244fa0ba91c1ceaf779a 100644 (file)
@@ -254,17 +254,11 @@ ERROR:  invalid XML content
 DETAIL:  line 1: xmlParseEntityRef: no name
 <invalidentity>&</invalidentity>
                 ^
-line 1: chunk is not well balanced
-<invalidentity>&</invalidentity>
-                                ^
 SELECT xmlparse(content '<undefinedentity>&idontexist;</undefinedentity>');
 ERROR:  invalid XML content
 DETAIL:  line 1: Entity 'idontexist' not defined
 <undefinedentity>&idontexist;</undefinedentity>
                              ^
-line 1: chunk is not well balanced
-<undefinedentity>&idontexist;</undefinedentity>
-                                               ^
 SELECT xmlparse(content '<invalidns xmlns=''&lt;''/>');
          xmlparse          
 ---------------------------
@@ -283,9 +277,6 @@ DETAIL:  line 1: Entity 'idontexist' not defined
 <twoerrors>&idontexist;</unbalanced>
                        ^
 line 1: Opening and ending tag mismatch: twoerrors line 1 and unbalanced
-<twoerrors>&idontexist;</unbalanced>
-                                    ^
-line 1: chunk is not well balanced
 <twoerrors>&idontexist;</unbalanced>
                                     ^
 SELECT xmlparse(content '<nosuchprefix:tag/>');
@@ -294,6 +285,19 @@ SELECT xmlparse(content '<nosuchprefix:tag/>');
  <nosuchprefix:tag/>
 (1 row)
 
+SELECT xmlparse(content '<unclosed>');
+ERROR:  invalid XML content
+DETAIL:  line 1: Premature end of data in tag unclosed line 1
+<unclosed>
+          ^
+SELECT xmlparse(content '<parent><child></parent></child>');
+ERROR:  invalid XML content
+DETAIL:  line 1: Opening and ending tag mismatch: child line 1 and parent
+<parent><child></parent></child>
+                        ^
+line 1: Opening and ending tag mismatch: parent line 1 and child
+<parent><child></parent></child>
+                                ^
 SELECT xmlparse(document '   ');
 ERROR:  invalid XML document
 DETAIL:  line 1: Start tag expected, '<' not found
@@ -352,6 +356,19 @@ SELECT xmlparse(document '<nosuchprefix:tag/>');
  <nosuchprefix:tag/>
 (1 row)
 
+SELECT xmlparse(document '<unclosed>');
+ERROR:  invalid XML document
+DETAIL:  line 1: Premature end of data in tag unclosed line 1
+<unclosed>
+          ^
+SELECT xmlparse(document '<parent><child></parent></child>');
+ERROR:  invalid XML document
+DETAIL:  line 1: Opening and ending tag mismatch: child line 1 and parent
+<parent><child></parent></child>
+                        ^
+line 1: Opening and ending tag mismatch: parent line 1 and child
+<parent><child></parent></child>
+                                ^
 SELECT xmlpi(name foo);
   xmlpi  
 ---------
index 9323b84ae21d26aee2a6f98f8f0685d7022314bd..d3f2bdfc1412840302784fb454548a74e630a527 100644 (file)
@@ -180,6 +180,12 @@ DETAIL:  This functionality requires the server to be built with libxml support.
 SELECT xmlparse(content '<nosuchprefix:tag/>');
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires the server to be built with libxml support.
+SELECT xmlparse(content '<unclosed>');
+ERROR:  unsupported XML feature
+DETAIL:  This functionality requires the server to be built with libxml support.
+SELECT xmlparse(content '<parent><child></parent></child>');
+ERROR:  unsupported XML feature
+DETAIL:  This functionality requires the server to be built with libxml support.
 SELECT xmlparse(document '   ');
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires the server to be built with libxml support.
@@ -207,6 +213,12 @@ DETAIL:  This functionality requires the server to be built with libxml support.
 SELECT xmlparse(document '<nosuchprefix:tag/>');
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires the server to be built with libxml support.
+SELECT xmlparse(document '<unclosed>');
+ERROR:  unsupported XML feature
+DETAIL:  This functionality requires the server to be built with libxml support.
+SELECT xmlparse(document '<parent><child></parent></child>');
+ERROR:  unsupported XML feature
+DETAIL:  This functionality requires the server to be built with libxml support.
 SELECT xmlpi(name foo);
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires the server to be built with libxml support.
index e1d165c6c936005cbc0f724d9a175d604068b549..376b7bd015bd48b091be62263d49dd8d6d2185d1 100644 (file)
@@ -250,13 +250,11 @@ ERROR:  invalid XML content
 DETAIL:  line 1: xmlParseEntityRef: no name
 <invalidentity>&</invalidentity>
                 ^
-line 1: chunk is not well balanced
 SELECT xmlparse(content '<undefinedentity>&idontexist;</undefinedentity>');
 ERROR:  invalid XML content
 DETAIL:  line 1: Entity 'idontexist' not defined
 <undefinedentity>&idontexist;</undefinedentity>
                              ^
-line 1: chunk is not well balanced
 SELECT xmlparse(content '<invalidns xmlns=''&lt;''/>');
          xmlparse          
 ---------------------------
@@ -275,13 +273,25 @@ DETAIL:  line 1: Entity 'idontexist' not defined
 <twoerrors>&idontexist;</unbalanced>
                        ^
 line 1: Opening and ending tag mismatch: twoerrors line 1 and unbalanced
-line 1: chunk is not well balanced
 SELECT xmlparse(content '<nosuchprefix:tag/>');
       xmlparse       
 ---------------------
  <nosuchprefix:tag/>
 (1 row)
 
+SELECT xmlparse(content '<unclosed>');
+ERROR:  invalid XML content
+DETAIL:  line 1: Premature end of data in tag unclosed line 1
+<unclosed>
+          ^
+SELECT xmlparse(content '<parent><child></parent></child>');
+ERROR:  invalid XML content
+DETAIL:  line 1: Opening and ending tag mismatch: child line 1 and parent
+<parent><child></parent></child>
+                        ^
+line 1: Opening and ending tag mismatch: parent line 1 and child
+<parent><child></parent></child>
+                                ^
 SELECT xmlparse(document '   ');
 ERROR:  invalid XML document
 DETAIL:  line 1: Start tag expected, '<' not found
@@ -332,6 +342,19 @@ SELECT xmlparse(document '<nosuchprefix:tag/>');
  <nosuchprefix:tag/>
 (1 row)
 
+SELECT xmlparse(document '<unclosed>');
+ERROR:  invalid XML document
+DETAIL:  line 1: Premature end of data in tag unclosed line 1
+<unclosed>
+          ^
+SELECT xmlparse(document '<parent><child></parent></child>');
+ERROR:  invalid XML document
+DETAIL:  line 1: Opening and ending tag mismatch: child line 1 and parent
+<parent><child></parent></child>
+                        ^
+line 1: Opening and ending tag mismatch: parent line 1 and child
+<parent><child></parent></child>
+                                ^
 SELECT xmlpi(name foo);
   xmlpi  
 ---------
index 953bac09e45f9988b1c33489dc7085c9c387a99e..15ccbe1d35db08ddb2aad866890b341f3400e04c 100644 (file)
@@ -77,6 +77,8 @@ SELECT xmlparse(content '<invalidns xmlns=''&lt;''/>');
 SELECT xmlparse(content '<relativens xmlns=''relative''/>');
 SELECT xmlparse(content '<twoerrors>&idontexist;</unbalanced>');
 SELECT xmlparse(content '<nosuchprefix:tag/>');
+SELECT xmlparse(content '<unclosed>');
+SELECT xmlparse(content '<parent><child></parent></child>');
 
 SELECT xmlparse(document '   ');
 SELECT xmlparse(document 'abc');
@@ -87,6 +89,8 @@ SELECT xmlparse(document '<invalidns xmlns=''&lt;''/>');
 SELECT xmlparse(document '<relativens xmlns=''relative''/>');
 SELECT xmlparse(document '<twoerrors>&idontexist;</unbalanced>');
 SELECT xmlparse(document '<nosuchprefix:tag/>');
+SELECT xmlparse(document '<unclosed>');
+SELECT xmlparse(document '<parent><child></parent></child>');
 
 
 SELECT xmlpi(name foo);