@@ -928,6 +928,7 @@ PgXmlErrorContext *
928928pg_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