@@ -207,12 +207,36 @@ static void php_libxml_node_free(xmlNodePtr node)
207207 * dtd is attached to the document. This works around the issue by inspecting the parent directly. */
208208 case XML_ENTITY_DECL : {
209209 xmlEntityPtr entity = (xmlEntityPtr ) node ;
210- php_libxml_unlink_entity_decl (entity );
211- if (entity -> orig != NULL ) {
212- xmlFree ((char * ) entity -> orig );
213- entity -> orig = NULL ;
210+ if (entity -> etype != XML_INTERNAL_PREDEFINED_ENTITY ) {
211+ php_libxml_unlink_entity_decl (entity );
212+ #if LIBXML_VERSION >= 21200
213+ xmlFreeEntity (entity );
214+ #else
215+ if (entity -> children != NULL && entity -> owner && entity == (xmlEntityPtr ) entity -> children -> parent ) {
216+ xmlFreeNodeList (entity -> children );
217+ }
218+ xmlDictPtr dict = entity -> doc != NULL ? entity -> doc -> dict : NULL ;
219+ if (dict == NULL || !xmlDictOwns (dict , entity -> name )) {
220+ xmlFree ((xmlChar * ) entity -> name );
221+ }
222+ if (dict == NULL || !xmlDictOwns (dict , entity -> ExternalID )) {
223+ xmlFree ((xmlChar * ) entity -> ExternalID );
224+ }
225+ if (dict == NULL || !xmlDictOwns (dict , entity -> SystemID )) {
226+ xmlFree ((xmlChar * ) entity -> SystemID );
227+ }
228+ if (dict == NULL || !xmlDictOwns (dict , entity -> URI )) {
229+ xmlFree ((xmlChar * ) entity -> URI );
230+ }
231+ if (dict == NULL || !xmlDictOwns (dict , entity -> content )) {
232+ xmlFree (entity -> content );
233+ }
234+ if (dict == NULL || !xmlDictOwns (dict , entity -> orig )) {
235+ xmlFree (entity -> orig );
236+ }
237+ xmlFree (entity );
238+ #endif
214239 }
215- xmlFreeNode (node );
216240 break ;
217241 }
218242 case XML_NOTATION_NODE : {
@@ -1386,6 +1410,15 @@ PHP_LIBXML_API void php_libxml_node_free_resource(xmlNodePtr node)
13861410 case XML_DOCUMENT_NODE :
13871411 case XML_HTML_DOCUMENT_NODE :
13881412 break ;
1413+ case XML_ENTITY_REF_NODE :
1414+ /* Entity reference nodes are special: their children point to entity declarations,
1415+ * but they don't own the declarations and therefore shouldn't free the children.
1416+ * Moreover, there can be more than one reference node for a single entity declarations. */
1417+ php_libxml_unregister_node (node );
1418+ if (node -> parent == NULL ) {
1419+ php_libxml_node_free (node );
1420+ }
1421+ break ;
13891422 default :
13901423 if (node -> parent == NULL || node -> type == XML_NAMESPACE_DECL ) {
13911424 php_libxml_node_free_list ((xmlNodePtr ) node -> children );
0 commit comments