#ifdef USE_LIBXML
#include
#include
+#include
#include
#include
#include
static StringInfo xml_err_buf = NULL;
+static xmlParserInputPtr xmlPgEntityLoader(const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt);
static void xml_errorHandler(void *ctxt, const char *msg,...);
static void xml_ereport_by_code(int level, int sqlcode,
const char *msg, int errcode);
/* Now that xml_err_buf exists, safe to call xml_errorHandler */
xmlSetGenericErrorFunc(NULL, xml_errorHandler);
+ /* set up our entity loader, too */
+ xmlSetExternalEntityLoader(xmlPgEntityLoader);
+
#ifdef USE_LIBXMLCONTEXT
/* Set up memory allocation our way, too */
xml_memory_init();
* about, anyway.
*/
xmlSetGenericErrorFunc(NULL, xml_errorHandler);
+
+ /* set up our entity loader, too */
+ xmlSetExternalEntityLoader(xmlPgEntityLoader);
}
}
#endif /* USE_LIBXMLCONTEXT */
+/*
+ * xmlPgEntityLoader --- entity loader callback function
+ *
+ * Silently prevent any external entity URL from being loaded. We don't want
+ * to throw an error, so instead make the entity appear to expand to an empty
+ * string.
+ *
+ * We would prefer to allow loading entities that exist in the system's
+ * global XML catalog; but the available libxml2 APIs make that a complex
+ * and fragile task. For now, just shut down all external access.
+ */
+static xmlParserInputPtr
+xmlPgEntityLoader(const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt)
+{
+ return xmlNewStringInputStream(ctxt, (const xmlChar *) "");
+}
+
+
/*
* xml_ereport --- report an XML-related error
*
{two,etc}
(1 row)
+-- External entity references should not leak filesystem information.
+SELECT XMLPARSE(DOCUMENT ']>&c;');
+ xmlparse
+-----------------------------------------------------------------
+ ]>&c;
+(1 row)
+
+SELECT XMLPARSE(DOCUMENT ']>&c;');
+ xmlparse
+-----------------------------------------------------------------------
+ ]>&c;
+(1 row)
+
+-- This might or might not load the requested DTD, but it mustn't throw error.
+SELECT XMLPARSE(DOCUMENT ' ');
+ xmlparse
+------------------------------------------------------------------------------------------------------------------------------------------------------
+
+(1 row)
+
^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
+-- External entity references should not leak filesystem information.
+SELECT XMLPARSE(DOCUMENT ']>&c;');
+ERROR: unsupported XML feature
+DETAIL: This functionality requires the server to be built with libxml support.
+HINT: You need to rebuild PostgreSQL using --with-libxml.
+SELECT XMLPARSE(DOCUMENT ']>&c;');
+ERROR: unsupported XML feature
+DETAIL: This functionality requires the server to be built with libxml support.
+HINT: You need to rebuild PostgreSQL using --with-libxml.
+-- This might or might not load the requested DTD, but it mustn't throw error.
+SELECT XMLPARSE(DOCUMENT ' ');
+ERROR: unsupported XML feature
+DETAIL: This functionality requires the server to be built with libxml support.
+HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xpath('//text()', 'number one');
SELECT xpath('//loc:piece/@id', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
+
+-- External entity references should not leak filesystem information.
+SELECT XMLPARSE(DOCUMENT ']>&c;');
+SELECT XMLPARSE(DOCUMENT ']>&c;');
+-- This might or might not load the requested DTD, but it mustn't throw error.
+SELECT XMLPARSE(DOCUMENT ' ');