Make contrib/xml2 use core xml.c's error handler, when available (that is,
authorTom Lane <[email protected]>
Wed, 3 Mar 2010 19:10:45 +0000 (19:10 +0000)
committerTom Lane <[email protected]>
Wed, 3 Mar 2010 19:10:45 +0000 (19:10 +0000)
in versions >= 8.3).  The core code is more robust and efficient than what
was there before, and this also reduces risks involved in swapping different
libxml error handler settings.

Before 8.3, there is still some risk of problems if add-on modules such as
Perl invoke libxml without setting their own error handler.  Given the lack
of reports I'm not sure there's a risk in practice, so I didn't take the
step of actually duplicating the core code into older contrib/xml2 branches.
Instead I just tweaked the existing code to ensure it didn't leave a dangling
pointer to short-lived memory when throwing an error.

contrib/xml2/xpath.c

index 2bdc2b40d39640758275f459591a732bbb8e4f59..269ca73ce9a016a0c346978313f885414ebd92d2 100644 (file)
@@ -100,9 +100,20 @@ elog_error(const char *explain, bool force)
                    (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
                     errmsg("%s", explain)));
        else
+       {
+           /*
+            * Ensure pgxml_errorMsg is reset to null before we give up
+            * control.  This provides some protection against crashes if
+            * pgxml_errorHandler is invoked again later, perhaps as a
+            * result of other modules' use of libxml.
+            */
+           char   *msg = pgxml_errorMsg;
+
+           pgxml_errorMsg = NULL;
            ereport(ERROR,
                    (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
-                    errmsg("%s: %s", explain, pgxml_errorMsg)));
+                    errmsg("%s: %s", explain, msg)));
+       }
    }
 }