@@ -371,7 +371,9 @@ static HashTable *xml_parser_get_gc(zend_object *object, zval **table, int *n)
371
371
xml_parser * parser = xml_parser_from_obj (object );
372
372
373
373
zend_get_gc_buffer * gc_buffer = zend_get_gc_buffer_create ();
374
- zend_get_gc_buffer_add_obj (gc_buffer , parser -> object );
374
+ if (parser -> object ) {
375
+ zend_get_gc_buffer_add_obj (gc_buffer , parser -> object );
376
+ }
375
377
if (ZEND_FCC_INITIALIZED (parser -> startElementHandler )) {
376
378
zend_get_gc_buffer_add_fcc (gc_buffer , & parser -> startElementHandler );
377
379
}
@@ -1050,33 +1052,9 @@ PHP_FUNCTION(xml_parser_create_ns)
1050
1052
}
1051
1053
/* }}} */
1052
1054
1053
- /* {{{ Set up object which should be used for callbacks */
1054
- PHP_FUNCTION (xml_set_object )
1055
- {
1056
- xml_parser * parser ;
1057
- zval * pind , * mythis ;
1058
-
1059
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "Oo" , & pind , xml_parser_ce , & mythis ) == FAILURE ) {
1060
- RETURN_THROWS ();
1061
- }
1062
-
1063
- parser = Z_XMLPARSER_P (pind );
1064
-
1065
- if (parser -> object ) {
1066
- // TODO Check methods exist in set FCCs
1067
- OBJ_RELEASE (parser -> object );
1068
- }
1069
-
1070
- parser -> object = Z_OBJ_P (mythis );
1071
- GC_ADDREF (parser -> object );
1072
-
1073
- RETURN_TRUE ;
1074
- }
1075
- /* }}} */
1076
-
1077
1055
static bool php_xml_check_string_method_arg (
1078
1056
unsigned int arg_num ,
1079
- const xml_parser * parser ,
1057
+ zend_object * object ,
1080
1058
zend_string * method_name ,
1081
1059
zend_fcall_info_cache * const parser_handler_fcc
1082
1060
) {
@@ -1085,12 +1063,12 @@ static bool php_xml_check_string_method_arg(
1085
1063
return true;
1086
1064
}
1087
1065
1088
- if (!parser -> object ) {
1066
+ if (!object ) {
1089
1067
zend_argument_value_error (arg_num , "an object must be set via xml_set_object() to be able to lookup method" );
1090
1068
return false;
1091
1069
}
1092
1070
1093
- zend_class_entry * ce = parser -> object -> ce ;
1071
+ zend_class_entry * ce = object -> ce ;
1094
1072
zend_string * lc_name = zend_string_tolower (method_name );
1095
1073
zend_function * method_ptr = zend_hash_find_ptr (& ce -> function_table , lc_name );
1096
1074
zend_string_release_ex (lc_name , 0 );
@@ -1102,11 +1080,59 @@ static bool php_xml_check_string_method_arg(
1102
1080
parser_handler_fcc -> function_handler = method_ptr ;
1103
1081
parser_handler_fcc -> calling_scope = ce ;
1104
1082
parser_handler_fcc -> called_scope = ce ;
1105
- parser_handler_fcc -> object = parser -> object ;
1083
+ parser_handler_fcc -> object = object ;
1106
1084
1107
1085
return true;
1108
1086
}
1109
1087
1088
+ #define PHP_XML_CHECK_NEW_THIS_METHODS (parser_to_check , new_this_obj , fcc_field ) \
1089
+ if (ZEND_FCC_INITIALIZED(parser_to_check->fcc_field) && parser_to_check->fcc_field.object == parser_to_check->object) { \
1090
+ zend_string *method_name = zend_string_copy(parser_to_check->fcc_field.function_handler->common.function_name); \
1091
+ zend_fcc_dtor(&parser_to_check->fcc_field); \
1092
+ bool status = php_xml_check_string_method_arg(2, new_this_obj, method_name, &parser_to_check->fcc_field); \
1093
+ if (status == false) { \
1094
+ /* TODO Better error message */ RETURN_THROWS (); \
1095
+ } \
1096
+ }
1097
+
1098
+
1099
+ /* {{{ Set up object which should be used for callbacks */
1100
+ PHP_FUNCTION (xml_set_object )
1101
+ {
1102
+ xml_parser * parser ;
1103
+ zval * pind , * mythis ;
1104
+ zend_object * new_this ;
1105
+
1106
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "Oo" , & pind , xml_parser_ce , & mythis ) == FAILURE ) {
1107
+ RETURN_THROWS ();
1108
+ }
1109
+
1110
+ parser = Z_XMLPARSER_P (pind );
1111
+ new_this = Z_OBJ_P (mythis );
1112
+
1113
+ if (parser -> object ) {
1114
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , startElementHandler );
1115
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , endElementHandler );
1116
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , characterDataHandler );
1117
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , processingInstructionHandler );
1118
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , defaultHandler );
1119
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , unparsedEntityDeclHandler );
1120
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , notationDeclHandler );
1121
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , externalEntityRefHandler );
1122
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , unknownEncodingHandler );
1123
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , startNamespaceDeclHandler );
1124
+ PHP_XML_CHECK_NEW_THIS_METHODS (parser , new_this , endNamespaceDeclHandler );
1125
+
1126
+ OBJ_RELEASE (parser -> object );
1127
+ }
1128
+
1129
+ parser -> object = new_this ;
1130
+ GC_ADDREF (parser -> object );
1131
+
1132
+ RETURN_TRUE ;
1133
+ }
1134
+ /* }}} */
1135
+
1110
1136
/* {{{ Set up start and end element handlers */
1111
1137
PHP_FUNCTION (xml_set_element_handler )
1112
1138
{
@@ -1136,7 +1162,7 @@ PHP_FUNCTION(xml_set_element_handler)
1136
1162
} else if (zend_parse_parameters_ex (ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS (), "Of!S" , & pind , xml_parser_ce , & start_fci , & start_fcc , & end_method_name ) == SUCCESS ) {
1137
1163
parser = Z_XMLPARSER_P (pind );
1138
1164
1139
- bool status = php_xml_check_string_method_arg (3 , parser , end_method_name , & end_fcc );
1165
+ bool status = php_xml_check_string_method_arg (3 , parser -> object , end_method_name , & end_fcc );
1140
1166
if (status == false) {
1141
1167
RETURN_THROWS ();
1142
1168
}
@@ -1150,7 +1176,7 @@ PHP_FUNCTION(xml_set_element_handler)
1150
1176
} else if (zend_parse_parameters_ex (ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS (), "OSf!" , & pind , xml_parser_ce , & start_method_name , & end_fci , & end_fcc ) == SUCCESS ) {
1151
1177
parser = Z_XMLPARSER_P (pind );
1152
1178
1153
- bool status = php_xml_check_string_method_arg (2 , parser , start_method_name , & start_fcc );
1179
+ bool status = php_xml_check_string_method_arg (2 , parser -> object , start_method_name , & start_fcc );
1154
1180
if (status == false) {
1155
1181
RETURN_THROWS ();
1156
1182
}
@@ -1164,11 +1190,11 @@ PHP_FUNCTION(xml_set_element_handler)
1164
1190
} else if (zend_parse_parameters_ex (ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS (), "OSS" , & pind , xml_parser_ce , & start_method_name , & end_method_name ) == SUCCESS ) {
1165
1191
parser = Z_XMLPARSER_P (pind );
1166
1192
1167
- bool status = php_xml_check_string_method_arg (2 , parser , start_method_name , & start_fcc );
1193
+ bool status = php_xml_check_string_method_arg (2 , parser -> object , start_method_name , & start_fcc );
1168
1194
if (status == false) {
1169
1195
RETURN_THROWS ();
1170
1196
}
1171
- status = php_xml_check_string_method_arg (3 , parser , end_method_name , & end_fcc );
1197
+ status = php_xml_check_string_method_arg (3 , parser -> object , end_method_name , & end_fcc );
1172
1198
if (status == false) {
1173
1199
RETURN_THROWS ();
1174
1200
}
@@ -1225,7 +1251,7 @@ static void php_xml_set_handler_parse_callable(
1225
1251
} else if (zend_parse_parameters_ex (ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS (), "OS" , & pind , xml_parser_ce , & method_name ) == SUCCESS ) {
1226
1252
* parser = Z_XMLPARSER_P (pind );
1227
1253
1228
- bool status = php_xml_check_string_method_arg (2 , * parser , method_name , parser_handler_fcc );
1254
+ bool status = php_xml_check_string_method_arg (2 , ( * parser ) -> object , method_name , parser_handler_fcc );
1229
1255
if (status == false) {
1230
1256
RETURN_THROWS ();
1231
1257
}
0 commit comments