Index: ext/xml/xml.c
===================================================================
--- ext/xml/xml.c (revision 313531)
+++ ext/xml/xml.c (working copy)
@@ -79,6 +79,7 @@
inline static char xml_decode_us_ascii(unsigned short);
static zval *xml_call_handler(xml_parser *, zval *, zend_function *, int, zval **);
static zval *_xml_xmlchar_zval(const XML_Char *, int, const XML_Char *);
+static zval *_xml_xmlint_zval(long);
static int _xml_xmlcharlen(const XML_Char *);
static void _xml_add_to_info(xml_parser *parser,char *name);
inline static char *_xml_decode_tag(xml_parser *parser, const char *tag);
@@ -89,6 +90,7 @@
void _xml_processingInstructionHandler(void *, const XML_Char *, const XML_Char *);
void _xml_defaultHandler(void *, const XML_Char *, int);
void _xml_unparsedEntityDeclHandler(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
+void _xml_entityDeclHandler(void *, const XML_Char *, int, const XML_Char *, int, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
void _xml_notationDeclHandler(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
int _xml_externalEntityRefHandler(XML_Parser, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
@@ -137,6 +139,11 @@
ZEND_ARG_INFO(0, hdl)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_entity_decl_handler, 0, 0, 2)
+ ZEND_ARG_INFO(0, parser)
+ ZEND_ARG_INFO(0, hdl)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_notation_decl_handler, 0, 0, 2)
ZEND_ARG_INFO(0, parser)
ZEND_ARG_INFO(0, hdl)
@@ -222,6 +229,7 @@
PHP_FE(xml_set_processing_instruction_handler, arginfo_xml_set_processing_instruction_handler)
PHP_FE(xml_set_default_handler, arginfo_xml_set_default_handler)
PHP_FE(xml_set_unparsed_entity_decl_handler,arginfo_xml_set_unparsed_entity_decl_handler)
+ PHP_FE(xml_set_entity_decl_handler, arginfo_xml_set_entity_decl_handler)
PHP_FE(xml_set_notation_decl_handler, arginfo_xml_set_notation_decl_handler)
PHP_FE(xml_set_external_entity_ref_handler, arginfo_xml_set_external_entity_ref_handler)
PHP_FE(xml_set_start_namespace_decl_handler,arginfo_xml_set_start_namespace_decl_handler)
@@ -416,6 +424,17 @@
Z_STRVAL_P(ret) = xml_utf8_decode(s, len, &Z_STRLEN_P(ret), encoding);
return ret;
}
+
+static zval *_xml_xmlint_zval(long value)
+{
+ zval *ret;
+ MAKE_STD_ZVAL(ret);
+
+ Z_TYPE_P(ret) = IS_LONG;
+ Z_LVAL_P(ret) = value;
+
+ return ret;
+}
/* }}} */
/* {{{ xml_parser_dtor() */
@@ -450,6 +469,9 @@
if (parser->unparsedEntityDeclHandler) {
zval_ptr_dtor(&parser->unparsedEntityDeclHandler);
}
+ if (parser->entityDeclHandler) {
+ zval_ptr_dtor(&parser->entityDeclHandler);
+ }
if (parser->notationDeclHandler) {
zval_ptr_dtor(&parser->notationDeclHandler);
}
@@ -1035,6 +1057,39 @@
}
/* }}} */
+/* {{{ _xml_entityDeclHandler() */
+void _xml_entityDeclHandler(void *userData,
+ const XML_Char *entityName,
+ int is_param_entity,
+ const XML_Char *value,
+ int value_length,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName)
+{
+ xml_parser *parser = (xml_parser *)userData;
+
+ // We come to this function "after" _entity_decl_handler
+ if (parser && parser->entityDeclHandler) {
+ zval *retval, *args[8];
+
+ args[0] = _xml_resource_zval(parser->index);
+ args[1] = _xml_xmlchar_zval(entityName, 0, parser->target_encoding);
+ args[2] = _xml_xmlint_zval((long)is_param_entity);
+ args[3] = _xml_xmlchar_zval(value, 0, parser->target_encoding);
+ args[4] = _xml_xmlchar_zval(base, 0, parser->target_encoding);
+ args[5] = _xml_xmlchar_zval(systemId, 0, parser->target_encoding);
+ args[6] = _xml_xmlchar_zval(publicId, 0, parser->target_encoding);
+ args[7] = _xml_xmlchar_zval(notationName, 0, parser->target_encoding);
+ if ((retval = xml_call_handler(parser, parser->entityDeclHandler, parser->entityDeclPtr, 8, args))) {
+ zval_ptr_dtor(&retval);
+ }
+ }
+}
+/* }}} */
+
+
/* {{{ _xml_unparsedEntityDeclHandler() */
void _xml_unparsedEntityDeclHandler(void *userData,
const XML_Char *entityName,
@@ -1351,6 +1406,25 @@
}
/* }}} */
+/* {{{ proto int xml_set_entity_decl_handler(resource parser, string hdl)
+ Set up entity declaration handler */
+PHP_FUNCTION(xml_set_entity_decl_handler)
+{
+ xml_parser *parser;
+ zval *pind, **hdl;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pind, &hdl) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(parser, xml_parser *, &pind, -1, "XML Parser", le_xml_parser);
+
+ xml_set_handler(&parser->entityDeclHandler, hdl);
+ XML_SetEntityDeclHandler(parser->parser, _xml_entityDeclHandler);
+ RETVAL_TRUE;
+}
+/* }}} */
+
/* {{{ proto int xml_set_notation_decl_handler(resource parser, string hdl)
Set up notation declaration handler */
PHP_FUNCTION(xml_set_notation_decl_handler)
Index: ext/xml/tests/xml_entity_declaration_handler.phpt
===================================================================
--- ext/xml/tests/xml_entity_declaration_handler.phpt (revision 0)
+++ ext/xml/tests/xml_entity_declaration_handler.phpt (revision 0)
@@ -0,0 +1,66 @@
+--TEST--
+Test various types of ENTITIES and their return values.
+--SKIPIF--
+
+--FILE--
+
+
+
+
+
+]>
+EOF;
+
+$parser = xml_parser_create();
+xml_set_entity_decl_handler(
+ $parser,
+ function($parser,
+ $entity_name,
+ $param_ent,
+ $value,
+ $base,
+ $system,
+ $public,
+ $notation)
+ {
+ echo 'Name: ' . $entity_name . PHP_EOL;
+ echo 'Is a Parameter Entity: ' . $param_ent . PHP_EOL;
+ echo 'Value: ' . $value . PHP_EOL;
+
+ if (!$value && $system !== null) {
+ echo 'System Entity: ' . $system . PHP_EOL;
+ }
+
+ echo PHP_EOL;
+});
+
+xml_parse($parser,$data,false) or
+ die (sprintf("XML Error: %s at line %d
\n",
+ xml_error_string(xml_get_error_code($parser)),
+ xml_get_current_line_number($parser)));
+xml_parser_free($parser);
+?>
+--EXPECT--
+Name: phpName
+Is a Parameter Entity: 0
+Value: Sample Store
+
+Name: phpExample
+Is a Parameter Entity: 0
+Value:
+System Entity: ./example.txt
+
+Name: NOME
+Is a Parameter Entity: 1
+Value: php-testing-xml-entity-decl1
+
+Name: NAME
+Is a Parameter Entity: 1
+Value: php-testing-xml-entity-decl2
\ No newline at end of file
Index: ext/xml/tests/bug51939.phpt
===================================================================
--- ext/xml/tests/bug51939.phpt (revision 0)
+++ ext/xml/tests/bug51939.phpt (revision 0)
@@ -0,0 +1,26 @@
+--TEST--
+Bug #51939 (Add xml_set_entity_decl_handler function)
+--SKIPIF--
+
+--FILE--
+]>&generalEntity;';
+
+function h_entity_decl($parser,$entity_name,$is_parameter_entity,$value,$base,$system_id,$public_id,$notation_name) {
+ echo "$entity_name - $is_parameter_entity - $value";
+};
+
+$parser = xml_parser_create();
+xml_set_entity_decl_handler($parser, 'h_entity_decl');
+
+xml_parse($parser,$data,false) or
+ die (sprintf("XML Error: %s at line %d
\n",
+ xml_error_string(xml_get_error_code($parser)),
+ xml_get_current_line_number($parser)));
+xml_parser_free($parser);
+--EXPECTF--
+generalEntity - 0 - General Entity
Index: ext/xml/compat.c
===================================================================
--- ext/xml/compat.c (revision 313531)
+++ ext/xml/compat.c (working copy)
@@ -294,10 +294,10 @@
static void
_unparsed_entity_decl_handler(void *user,
- const xmlChar *name,
- const xmlChar *pub_id,
- const xmlChar *sys_id,
- const xmlChar *notation)
+ const xmlChar *name,
+ const xmlChar *pub_id,
+ const xmlChar *sys_id,
+ const xmlChar *notation)
{
XML_Parser parser = (XML_Parser) user;
@@ -309,6 +309,30 @@
}
static void
+_entity_decl_handler(void *user,
+ const xmlChar *name,
+ int type,
+ const xmlChar *pub_id,
+ const xmlChar *sys_id,
+ const xmlChar *value)
+{
+ XML_Parser parser = (XML_Parser) user;
+ int is_param_entity = 0;
+
+ if (parser->h_entity_decl == NULL) {
+ return;
+ }
+
+ /* 4 means an entity of type parameters */
+ if (type == 4) {
+ is_param_entity = 1;
+ }
+
+ /* We always set the base to NULL for now. Same for "notations" */
+ parser->h_entity_decl(parser->user, name, is_param_entity, value, 0, NULL, sys_id, pub_id, NULL);
+}
+
+static void
_notation_decl_handler(void *user, const xmlChar *notation, const xmlChar *pub_id, const xmlChar *sys_id)
{
XML_Parser parser = (XML_Parser) user;
@@ -418,7 +442,7 @@
NULL, /* hasExternalSubset */
NULL, /* resolveEntity */
_get_entity, /* getEntity */
- NULL, /* entityDecl */
+ _entity_decl_handler, /* entityDecl */
_notation_decl_handler,
NULL, /* attributeDecl */
NULL, /* elementDecl */
@@ -443,7 +467,7 @@
NULL,
_start_element_handler_ns,
_end_element_handler_ns,
- NULL
+ NULL
};
PHPAPI XML_Parser
@@ -550,6 +574,12 @@
}
PHPAPI void
+XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler)
+{
+ parser->h_entity_decl = handler;
+}
+
+PHPAPI void
XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler notation_decl)
{
parser->h_notation_decl = notation_decl;
Index: ext/xml/expat_compat.h
===================================================================
--- ext/xml/expat_compat.h (revision 313531)
+++ ext/xml/expat_compat.h (working copy)
@@ -47,6 +47,7 @@
typedef void (*XML_CommentHandler)(void *, const XML_Char *);
typedef void (*XML_DefaultHandler)(void *, const XML_Char *, int);
typedef void (*XML_UnparsedEntityDeclHandler)(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
+typedef void (*XML_EntityDeclHandler)(void *, const XML_Char *, int, const XML_Char *, int, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
typedef void (*XML_NotationDeclHandler)(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
typedef int (*XML_ExternalEntityRefHandler)(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
typedef void (*XML_StartNamespaceDeclHandler)(void *, const XML_Char *, const XML_Char *);
@@ -73,6 +74,7 @@
XML_CommentHandler h_comment;
XML_DefaultHandler h_default;
XML_UnparsedEntityDeclHandler h_unparsed_entity_decl;
+ XML_EntityDeclHandler h_entity_decl;
XML_NotationDeclHandler h_notation_decl;
XML_ExternalEntityRefHandler h_external_entity_ref;
XML_StartNamespaceDeclHandler h_start_ns;
@@ -128,6 +130,7 @@
PHPAPI void XML_SetProcessingInstructionHandler(XML_Parser, XML_ProcessingInstructionHandler);
PHPAPI void XML_SetDefaultHandler(XML_Parser, XML_DefaultHandler);
PHPAPI void XML_SetUnparsedEntityDeclHandler(XML_Parser, XML_UnparsedEntityDeclHandler);
+PHPAPI void XML_SetEntityDeclHandler(XML_Parser, XML_EntityDeclHandler);
PHPAPI void XML_SetNotationDeclHandler(XML_Parser, XML_NotationDeclHandler);
PHPAPI void XML_SetExternalEntityRefHandler(XML_Parser, XML_ExternalEntityRefHandler);
PHPAPI void XML_SetStartNamespaceDeclHandler(XML_Parser, XML_StartNamespaceDeclHandler);
Index: ext/xml/php_xml.h
===================================================================
--- ext/xml/php_xml.h (revision 313531)
+++ ext/xml/php_xml.h (working copy)
@@ -55,6 +55,7 @@
zval *processingInstructionHandler;
zval *defaultHandler;
zval *unparsedEntityDeclHandler;
+ zval *entityDeclHandler;
zval *notationDeclHandler;
zval *externalEntityRefHandler;
zval *unknownEncodingHandler;
@@ -67,6 +68,7 @@
zend_function *processingInstructionPtr;
zend_function *defaultPtr;
zend_function *unparsedEntityDeclPtr;
+ zend_function *entityDeclPtr;
zend_function *notationDeclPtr;
zend_function *externalEntityRefPtr;
zend_function *unknownEncodingPtr;
@@ -116,6 +118,7 @@
PHP_FUNCTION(xml_set_processing_instruction_handler);
PHP_FUNCTION(xml_set_default_handler);
PHP_FUNCTION(xml_set_unparsed_entity_decl_handler);
+PHP_FUNCTION(xml_set_entity_decl_handler);
PHP_FUNCTION(xml_set_notation_decl_handler);
PHP_FUNCTION(xml_set_external_entity_ref_handler);
PHP_FUNCTION(xml_set_start_namespace_decl_handler);