aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/xml.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-07-26 16:29:53 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-07-26 16:31:04 -0400
commitc1420fcf7d9e899b3378e25f5e21776f6461b4a4 (patch)
tree69326a45913ddcc487d4f8084fb465065cd6b6d5 /src/backend/utils/adt/xml.c
parente67efb01e886d69d40d1cd87fba4507e8bb1035e (diff)
downloadpostgresql-c1420fcf7d9e899b3378e25f5e21776f6461b4a4.tar.gz
postgresql-c1420fcf7d9e899b3378e25f5e21776f6461b4a4.zip
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.
Diffstat (limited to 'src/backend/utils/adt/xml.c')
-rw-r--r--src/backend/utils/adt/xml.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index f3db3f07548..99b978c42c0 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -928,6 +928,7 @@ PgXmlErrorContext *
pg_xml_init(PgXmlStrictness strictness)
{
PgXmlErrorContext *errcxt;
+ void *new_errcxt;
/* Do one-time setup if needed */
pg_xml_init_library();
@@ -956,6 +957,34 @@ pg_xml_init(PgXmlStrictness strictness)
xmlSetStructuredErrorFunc((void *) errcxt, xml_errorHandler);
+ /*
+ * Verify that xmlSetStructuredErrorFunc set the context variable we
+ * expected it to. If not, the error context pointer we just saved is not
+ * the correct thing to restore, and since that leaves us without a way to
+ * restore the context in pg_xml_done, we must fail.
+ *
+ * The only known situation in which this test fails is if we compile with
+ * headers from a libxml2 that doesn't track the structured error context
+ * separately (<= 2.7.3), but at runtime use a version that does, or vice
+ * versa. The libxml2 authors did not treat that change as constituting
+ * an ABI break, so the LIBXML_TEST_VERSION test in pg_xml_init_library
+ * fails to protect us from this.
+ */
+
+#ifdef HAVE_XMLSTRUCTUREDERRORCONTEXT
+ new_errcxt = xmlStructuredErrorContext;
+#else
+ new_errcxt = xmlGenericErrorContext;
+#endif
+
+ if (new_errcxt != (void *) errcxt)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("could not set up XML error handler"),
+ errhint("This probably indicates that the version of libxml2"
+ " being used is not compatible with the libxml2"
+ " header files that PostgreSQL was built with.")));
+
return errcxt;
}
@@ -1494,9 +1523,14 @@ xml_errorHandler(void *data, xmlErrorPtr error)
int level = error->level;
StringInfo errorBuf;
- /* Defend against someone passing us a bogus context struct */
+ /*
+ * Defend against someone passing us a bogus context struct.
+ *
+ * We force a backend exit if this check fails because longjmp'ing out of
+ * libxml would likely render it unsafe to use further.
+ */
if (xmlerrcxt->magic != ERRCXT_MAGIC)
- elog(ERROR, "xml_errorHandler called with invalid PgXmlErrorContext");
+ elog(FATAL, "xml_errorHandler called with invalid PgXmlErrorContext");
/*----------
* Older libxml versions report some errors differently.