bojan 84416c
--- apr/apr-util/branches/0.9.x/xml/apr_xml.c	2009/06/03 15:37:44	781436
bojan 84416c
+++ apr/apr-util/branches/0.9.x/xml/apr_xml.c	2009/06/03 15:38:19	781437
bojan 84416c
@@ -339,6 +339,25 @@
bojan 84416c
     return APR_SUCCESS;
bojan 84416c
 }
bojan 84416c
 
bojan 84416c
+#if XML_MAJOR_VERSION > 1
bojan 84416c
+/* Stop the parser if an entity declaration is hit. */
bojan 84416c
+static void entity_declaration(void *userData, const XML_Char *entityName,
bojan 84416c
+                               int is_parameter_entity, const XML_Char *value,
bojan 84416c
+                               int value_length, const XML_Char *base,
bojan 84416c
+                               const XML_Char *systemId, const XML_Char *publicId,
bojan 84416c
+                               const XML_Char *notationName)
bojan 84416c
+{
bojan 84416c
+    apr_xml_parser *parser = userData;
bojan 84416c
+
bojan 84416c
+    XML_StopParser(parser->xp, XML_FALSE);
bojan 84416c
+}
bojan 84416c
+#else
bojan 84416c
+/* A noop default_handler. */
bojan 84416c
+static void default_handler(void *userData, const XML_Char *s, int len)
bojan 84416c
+{
bojan 84416c
+}
bojan 84416c
+#endif
bojan 84416c
+
bojan 84416c
 APU_DECLARE(apr_xml_parser *) apr_xml_parser_create(apr_pool_t *pool)
bojan 84416c
 {
bojan 84416c
     apr_xml_parser *parser = apr_pcalloc(pool, sizeof(*parser));
bojan 84416c
@@ -364,6 +383,19 @@
bojan 84416c
     XML_SetElementHandler(parser->xp, start_handler, end_handler);
bojan 84416c
     XML_SetCharacterDataHandler(parser->xp, cdata_handler);
bojan 84416c
 
bojan 84416c
+    /* Prevent the "billion laughs" attack against expat by disabling
bojan 84416c
+     * internal entity expansion.  With 2.x, forcibly stop the parser
bojan 84416c
+     * if an entity is declared - this is safer and a more obvious
bojan 84416c
+     * failure mode.  With older versions, installing a noop
bojan 84416c
+     * DefaultHandler means that internal entities will be expanded as
bojan 84416c
+     * the empty string, which is also sufficient to prevent the
bojan 84416c
+     * attack. */
bojan 84416c
+#if XML_MAJOR_VERSION > 1
bojan 84416c
+    XML_SetEntityDeclHandler(parser->xp, entity_declaration);
bojan 84416c
+#else
bojan 84416c
+    XML_SetDefaultHandler(parser->xp, default_handler);
bojan 84416c
+#endif
bojan 84416c
+
bojan 84416c
     return parser;
bojan 84416c
 }
bojan 84416c