php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #51939
Patch Bug51939.patch revision 2011-07-21 13:03 UTC by davidc@php.net
Patch bug51939-3-ws.patch revision 2011-07-21 12:43 UTC by davidc@php.net
Patch bug51392-ws revision 2011-07-21 12:39 UTC by davidc@php.net
Patch bug51939.patch revision 2011-07-19 16:21 UTC by davidc@php.net

Patch bug51939-3-ws.patch for XML related Bug #51939

Patch version 2011-07-21 12:43 UTC

Return to Bug #51939 | Download this patch
This patch is obsolete

Obsoleted by patches:

This patch renders other patches obsolete

Obsolete patches:

Patch Revisions:

Developer: davidc@php.net

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--
+<?php 
+if (!extension_loaded("xml")) {
+	print "skip - XML extension not loaded"; 
+}	 
+?> 
+--FILE--
+<?php
+$data =<<<EOF
+<?xml version="1.0"?>
+<!DOCTYPE store [
+    <!ENTITY phpName "Sample Store">
+    <!ENTITY phpExample SYSTEM "./example.txt">
+    <!ENTITY % NOME "php-testing-xml-entity-decl1">
+    <!ENTITY % NAME "php-testing-xml-entity-decl2">
+]>
+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<br>\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--
+<?php 
+if (!extension_loaded("xml")) {
+	print "skip - XML extension not loaded"; 
+}	 
+?> 
+--FILE--
+<?php
+$data = '<!DOCTYPE test [<!ENTITY generalEntity "General Entity">]><test>&generalEntity;</test>';
+
+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<br>\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);
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 13:01:28 2024 UTC