Skip to content

Commit c1420fc

Browse files
committed
Check to see whether libxml2 handles error context the way we expect.
It turns out to be possible to link against a libxml2.so that does this differently than the version we configured and built against, so we need a runtime check to avoid bizarre behavior. Per report from Bernd Helmle. Patch by Florian Pflug.
1 parent e67efb0 commit c1420fc

File tree

1 file changed

+36
-2
lines changed
  • src/backend/utils/adt

1 file changed

+36
-2
lines changed

src/backend/utils/adt/xml.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ PgXmlErrorContext *
928928
pg_xml_init(PgXmlStrictness strictness)
929929
{
930930
PgXmlErrorContext *errcxt;
931+
void *new_errcxt;
931932

932933
/* Do one-time setup if needed */
933934
pg_xml_init_library();
@@ -956,6 +957,34 @@ pg_xml_init(PgXmlStrictness strictness)
956957

957958
xmlSetStructuredErrorFunc((void *) errcxt, xml_errorHandler);
958959

960+
/*
961+
* Verify that xmlSetStructuredErrorFunc set the context variable we
962+
* expected it to. If not, the error context pointer we just saved is not
963+
* the correct thing to restore, and since that leaves us without a way to
964+
* restore the context in pg_xml_done, we must fail.
965+
*
966+
* The only known situation in which this test fails is if we compile with
967+
* headers from a libxml2 that doesn't track the structured error context
968+
* separately (<= 2.7.3), but at runtime use a version that does, or vice
969+
* versa. The libxml2 authors did not treat that change as constituting
970+
* an ABI break, so the LIBXML_TEST_VERSION test in pg_xml_init_library
971+
* fails to protect us from this.
972+
*/
973+
974+
#ifdef HAVE_XMLSTRUCTUREDERRORCONTEXT
975+
new_errcxt = xmlStructuredErrorContext;
976+
#else
977+
new_errcxt = xmlGenericErrorContext;
978+
#endif
979+
980+
if (new_errcxt != (void *) errcxt)
981+
ereport(ERROR,
982+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
983+
errmsg("could not set up XML error handler"),
984+
errhint("This probably indicates that the version of libxml2"
985+
" being used is not compatible with the libxml2"
986+
" header files that PostgreSQL was built with.")));
987+
959988
return errcxt;
960989
}
961990

@@ -1494,9 +1523,14 @@ xml_errorHandler(void *data, xmlErrorPtr error)
14941523
int level = error->level;
14951524
StringInfo errorBuf;
14961525

1497-
/* Defend against someone passing us a bogus context struct */
1526+
/*
1527+
* Defend against someone passing us a bogus context struct.
1528+
*
1529+
* We force a backend exit if this check fails because longjmp'ing out of
1530+
* libxml would likely render it unsafe to use further.
1531+
*/
14981532
if (xmlerrcxt->magic != ERRCXT_MAGIC)
1499-
elog(ERROR, "xml_errorHandler called with invalid PgXmlErrorContext");
1533+
elog(FATAL, "xml_errorHandler called with invalid PgXmlErrorContext");
15001534

15011535
/*----------
15021536
* Older libxml versions report some errors differently.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy