diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 82f273974cd5..24f6a1b96674 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -29,6 +29,10 @@ PHP 8.7 INTERNALS UPGRADE NOTES and C23, which means that ZEND_NORETURN needs to come first in the modifier list. Consider using noreturn (C11) / [[noreturn]] (C23) directly if header interoperability is not required. +- The signature of zend_is_callable() has been changed to + zend_is_callable(const zval *callable, zend_fcall_info_cache *fcc, char **error) + from zend_is_callable(const zval *callable, uint32_t check_flags, zend_string **callable_name). + This new signature covers the most common parameters used with zend_is_callable_ex(). ======================== 2. Build system changes diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 5c4083052202..c94a71cf56b8 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -422,9 +422,9 @@ ZEND_API bool zend_is_callable_at_frame( const zval *callable, zend_object *object, const zend_execute_data *frame, uint32_t check_flags, zend_fcall_info_cache *fcc, char **error); ZEND_API bool zend_is_callable_ex(const zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error); -static zend_always_inline bool zend_is_callable(const zval *callable, uint32_t check_flags, zend_string **callable_name) +static zend_always_inline bool zend_is_callable(const zval *callable, zend_fcall_info_cache *fcc, char **error) { - return zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, NULL); + return zend_is_callable_ex(callable, NULL, 0, NULL, fcc, error); } ZEND_API const char *zend_get_module_version(const char *module_name); diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index d4c0b5881369..9d5971fac479 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -399,7 +399,7 @@ static zend_result zend_create_closure_from_callable(zval *return_value, zval *c zend_function *mptr; zend_internal_function call; - if (!zend_is_callable_ex(callable, NULL, 0, NULL, &fcc, error)) { + if (!zend_is_callable(callable, &fcc, error)) { return FAILURE; } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index ff3a5f0b3de9..9c414634a23e 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1213,7 +1213,7 @@ static zend_always_inline bool zend_check_type_slow( const uint32_t type_mask = ZEND_TYPE_FULL_MASK(*type); if ((type_mask & MAY_BE_CALLABLE) && - zend_is_callable(arg, is_internal ? IS_CALLABLE_SUPPRESS_DEPRECATIONS : 0, NULL)) { + zend_is_callable_ex(arg, NULL, is_internal ? IS_CALLABLE_SUPPRESS_DEPRECATIONS : 0, NULL, NULL, NULL)) { return 1; } if ((type_mask & MAY_BE_STATIC) && zend_value_instanceof_static(arg)) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 9c9e262169f8..d1355208c287 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3985,10 +3985,10 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMP|CV, NUM) SAVE_OPLINE(); function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { + if (zend_is_callable(function_name, &fcc, &error)) { ZEND_ASSERT(!error); - /* Deprecation can be emitted from zend_is_callable_ex(), which can + /* Deprecation can be emitted from zend_is_callable(), which can * invoke a user error handler and throw an exception. * For the CONST and CV case we reuse the same exception block below * to make sure we don't increase VM size too much. */ diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 942f18eb7040..fe2df85c23e3 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -7668,10 +7668,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CAL SAVE_OPLINE(); function_name = RT_CONSTANT(opline, opline->op2); - if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { + if (zend_is_callable(function_name, &fcc, &error)) { ZEND_ASSERT(!error); - /* Deprecation can be emitted from zend_is_callable_ex(), which can + /* Deprecation can be emitted from zend_is_callable(), which can * invoke a user error handler and throw an exception. * For the CONST and CV case we reuse the same exception block below * to make sure we don't increase VM size too much. */ @@ -10444,10 +10444,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CAL SAVE_OPLINE(); function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { + if (zend_is_callable(function_name, &fcc, &error)) { ZEND_ASSERT(!error); - /* Deprecation can be emitted from zend_is_callable_ex(), which can + /* Deprecation can be emitted from zend_is_callable(), which can * invoke a user error handler and throw an exception. * For the CONST and CV case we reuse the same exception block below * to make sure we don't increase VM size too much. */ @@ -13108,10 +13108,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CAL SAVE_OPLINE(); function_name = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { + if (zend_is_callable(function_name, &fcc, &error)) { ZEND_ASSERT(!error); - /* Deprecation can be emitted from zend_is_callable_ex(), which can + /* Deprecation can be emitted from zend_is_callable(), which can * invoke a user error handler and throw an exception. * For the CONST and CV case we reuse the same exception block below * to make sure we don't increase VM size too much. */ @@ -60529,10 +60529,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPE SAVE_OPLINE(); function_name = RT_CONSTANT(opline, opline->op2); - if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { + if (zend_is_callable(function_name, &fcc, &error)) { ZEND_ASSERT(!error); - /* Deprecation can be emitted from zend_is_callable_ex(), which can + /* Deprecation can be emitted from zend_is_callable(), which can * invoke a user error handler and throw an exception. * For the CONST and CV case we reuse the same exception block below * to make sure we don't increase VM size too much. */ @@ -63305,10 +63305,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPE SAVE_OPLINE(); function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { + if (zend_is_callable(function_name, &fcc, &error)) { ZEND_ASSERT(!error); - /* Deprecation can be emitted from zend_is_callable_ex(), which can + /* Deprecation can be emitted from zend_is_callable(), which can * invoke a user error handler and throw an exception. * For the CONST and CV case we reuse the same exception block below * to make sure we don't increase VM size too much. */ @@ -65867,10 +65867,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPE SAVE_OPLINE(); function_name = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { + if (zend_is_callable(function_name, &fcc, &error)) { ZEND_ASSERT(!error); - /* Deprecation can be emitted from zend_is_callable_ex(), which can + /* Deprecation can be emitted from zend_is_callable(), which can * invoke a user error handler and throw an exception. * For the CONST and CV case we reuse the same exception block below * to make sure we don't increase VM size too much. */ diff --git a/ext/dom/xpath_callbacks.c b/ext/dom/xpath_callbacks.c index e4ad6c59b3d1..e0f75fbf6a7c 100644 --- a/ext/dom/xpath_callbacks.c +++ b/ext/dom/xpath_callbacks.c @@ -204,7 +204,7 @@ static zend_result php_dom_xpath_callback_ns_update_method_handler( ZEND_HASH_FOREACH_STR_KEY_VAL(callable_ht, key, entry) { zend_fcall_info_cache* fcc = emalloc(sizeof(*fcc)); char *error; - if (!zend_is_callable_ex(entry, NULL, 0, NULL, fcc, &error)) { + if (!zend_is_callable(entry, fcc, &error)) { zend_argument_type_error(1, "must be an array with valid callbacks as values, %s", error); efree(fcc); efree(error); @@ -251,7 +251,7 @@ static zend_result php_dom_xpath_callback_ns_update_method_handler( char *error; zval tmp; ZVAL_STR(&tmp, name); - if (!zend_is_callable_ex(&tmp, NULL, 0, NULL, fcc, &error)) { + if (!zend_is_callable(&tmp, fcc, &error)) { zend_argument_type_error(1, "must be a callable, %s", error); efree(fcc); efree(error); diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 37a0a215262b..0f6e7626d834 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -1006,7 +1006,7 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ * return NULL; } - if (!zend_is_callable_ex(value, NULL, 0, NULL, &fcc, &error)) { + if (!zend_is_callable(value, &fcc, &error)) { zend_throw_error(zend_ffi_exception_ce, "Attempt to assign an invalid callback, %s", error); return NULL; } diff --git a/ext/gd/tests/gif-oob.phpt b/ext/gd/tests/gif-oob.phpt new file mode 100644 index 000000000000..73fd0427c8e8 --- /dev/null +++ b/ext/gd/tests/gif-oob.phpt @@ -0,0 +1,63 @@ +--TEST-- +GIF OOB array access when using code size of 12 +--EXTENSIONS-- +gd +--FILE-- + "GIF", + "version" => "89a", +]; +$fileHeader = implode("", $fileHeaderParts); + +$logicalScreenDescriptorParts = [ + // little-endian format + "width" => "\x04\x00", + "height" => "\x04\x00", + // packed data: global color table flag (most significant bit), + // color resolution (3 bits, only meaningful if global color table is enabled + // and we don't enable it here) + // sort flag (one bit, again only meaningful if global color table is enabled) + // size of global color table (3 bits) + "packed_info" => "\x00", + "background_color_index" => "\x00", + "pixel_aspect_ratio" => "\x00", +]; +$logicalScreenDescriptor = implode("", $logicalScreenDescriptorParts); + +$startImage = ","; + +$imgDescParts = [ + // little-ending format + "left" => "\x00\x00", + "top" => "\x00\x00", + "width" => "\x04\x00", + "height" => "\x04\x00", + // more packed data: local color table flag, interlace flag, sort flag, + // 2 bits reserved for future use, then 3 bits for size of local color + // table, which we don't have + "packed_info" => "\x00", +]; +$imgDesc = implode("", $imgDescParts); + +$imgDataParts = [ + "lzw_min_code_size" => "\x0c", // 12 + "sub_block_num_bytes" => "\x05", + // Data in the block: 3 12-bit codes, and then 4 trailing 0 bits + "sub_block_bytes" => "\xff\x5f\x00\x06\x40", + // end of data + "end" => "\x00" +]; +$imgData = implode("", $imgDataParts); + +$trailer = ";"; + +$source = $fileHeader . $logicalScreenDescriptor . $startImage . $imgDesc . $imgData . $trailer; +$img = imagecreatefromstring($source); +var_dump($img); + +?> +--EXPECTF-- +object(GdImage)#%d (0) { +} diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 0466dd4bf653..854227318da0 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -2007,7 +2007,7 @@ static zend_result php_openssl_validate_and_allocate_psk_callback( char *is_callable_error = NULL; zend_fcall_info_cache fcc = {0}; - if (!zend_is_callable_ex(callable, NULL, 0, NULL, &fcc, &is_callable_error)) { + if (!zend_is_callable(callable, &fcc, &is_callable_error)) { if (is_callable_error) { zend_type_error("%s must be a valid callback, %s", callback_name, is_callable_error); @@ -2130,7 +2130,7 @@ static zend_result php_openssl_setup_server_early_data(php_stream *stream, char *is_callable_error = NULL; zend_fcall_info_cache fcc = {0}; - if (!zend_is_callable_ex(val, NULL, 0, NULL, &fcc, &is_callable_error)) { + if (!zend_is_callable(val, &fcc, &is_callable_error)) { if (is_callable_error) { zend_type_error("early_data_cb must be a valid callback, %s", is_callable_error); efree(is_callable_error); @@ -2318,7 +2318,7 @@ static zend_result php_openssl_validate_and_allocate_session_callback( /* Validate callable */ zend_fcall_info_cache fcc; - if (!zend_is_callable_ex(callable, NULL, 0, NULL, &fcc, &is_callable_error)) { + if (!zend_is_callable(callable, &fcc, &is_callable_error)) { if (is_callable_error) { zend_type_error("%s must be a valid callback, %s", callback_name, is_callable_error); efree(is_callable_error); diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index c73478fe5835..0a40bd0f2dfe 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -842,7 +842,7 @@ PHP_FUNCTION(pcntl_signal) RETURN_TRUE; } - if (!zend_is_callable_ex(handle, NULL, 0, NULL, NULL, NULL)) { + if (!zend_is_callable(handle, NULL, NULL)) { PCNTL_G(last_error) = EINVAL; zend_argument_type_error(2, "must be of type callable|int, %s given", zend_zval_value_name(handle)); diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 4c63ab0920ae..fce1a21a6c29 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -2459,7 +2459,7 @@ PHP_FUNCTION(preg_replace_callback_array) /* Copy potential trampoline */ ZVAL_COPY_VALUE(&fci.function_name, replace); - if (!zend_is_callable_ex(replace, NULL, 0, NULL, &fcc, NULL)) { + if (!zend_is_callable(replace, &fcc, NULL)) { zend_argument_type_error(1, "must contain only valid callbacks"); goto error; } diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 9774b197b7d9..4b56dbdbbd59 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -1116,7 +1116,7 @@ static bool pdo_get_fcc_from_zval(zend_fcall_info_cache *fcc, zval *callable) { } char *is_callable_error = NULL; - if (!zend_is_callable_ex(callable, NULL, 0, NULL, fcc, &is_callable_error)) { + if (!zend_is_callable(callable, fcc, &is_callable_error)) { if (is_callable_error) { zend_type_error("%s", is_callable_error); efree(is_callable_error); diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 7552b00c1151..b1968d9ff118 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5142,7 +5142,7 @@ void reflection_class_new_lazy(INTERNAL_FUNCTION_PARAMETERS, /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal * with it ourselves. It is important that it is not refetched on every call, * because calls may occur from different scopes. */ - zend_is_callable_ex(&fci.function_name, NULL, 0, NULL, &fcc, NULL); + zend_is_callable(&fci.function_name, &fcc, NULL); } obj = zend_object_make_lazy(obj, ce, &fci.function_name, &fcc, diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 90341109210f..6502ac279e26 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -967,7 +967,7 @@ static zend_result parse_context_params(php_stream_context *context, const HashT zend_fcall_info_cache *fcc = emalloc(sizeof(*fcc)); char *error; - if (!zend_is_callable_ex(tmp, NULL, 0, NULL, fcc, &error)) { + if (!zend_is_callable(tmp, fcc, &error)) { zend_argument_type_error(1, "must be an array with valid callbacks as values, %s", error); efree(fcc); efree(error); diff --git a/ext/tidy/tests/reparse_node.phpt b/ext/tidy/tests/reparse_node.phpt new file mode 100644 index 000000000000..2ee03d8344e8 --- /dev/null +++ b/ext/tidy/tests/reparse_node.phpt @@ -0,0 +1,57 @@ +--TEST-- +tidyNode objects are invalid after reparsing their document +--EXTENSIONS-- +tidy +--FILE-- +

one

two

'); +$node = $tidy->body()->child[0]; +var_dump($node->isHtml()); +var_dump($node->hasSiblings()); + +$tidy->parseString('

three

'); + +$operations = [ + 'string cast' => static fn() => (string) $node, + 'hasChildren' => static fn() => $node->hasChildren(), + 'hasSiblings' => static fn() => $node->hasSiblings(), + 'isComment' => static fn() => $node->isComment(), + 'isHtml' => static fn() => $node->isHtml(), + 'isText' => static fn() => $node->isText(), + 'isJste' => static fn() => $node->isJste(), + 'isAsp' => static fn() => $node->isAsp(), + 'isPhp' => static fn() => $node->isPhp(), + 'getParent' => static fn() => $node->getParent(), + 'getPreviousSibling' => static fn() => $node->getPreviousSibling(), + 'getNextSibling' => static fn() => $node->getNextSibling(), +]; + +foreach ($operations as $operation => $callback) { + try { + $callback(); + echo $operation, ": no error\n"; + } catch (Error $e) { + echo $operation, ': ', $e::class, ': ', $e->getMessage(), "\n"; + } +} + +var_dump($tidy->body()->child[0]->isHtml()); + +?> +--EXPECT-- +bool(true) +bool(true) +string cast: Error: tidyNode object is no longer valid after its document was reparsed +hasChildren: Error: tidyNode object is no longer valid after its document was reparsed +hasSiblings: Error: tidyNode object is no longer valid after its document was reparsed +isComment: Error: tidyNode object is no longer valid after its document was reparsed +isHtml: Error: tidyNode object is no longer valid after its document was reparsed +isText: Error: tidyNode object is no longer valid after its document was reparsed +isJste: Error: tidyNode object is no longer valid after its document was reparsed +isAsp: Error: tidyNode object is no longer valid after its document was reparsed +isPhp: Error: tidyNode object is no longer valid after its document was reparsed +getParent: Error: tidyNode object is no longer valid after its document was reparsed +getPreviousSibling: Error: tidyNode object is no longer valid after its document was reparsed +getNextSibling: Error: tidyNode object is no longer valid after its document was reparsed +bool(true) diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index 98e1c05a720f..dcb87dd509b0 100644 --- a/ext/tidy/tidy.c +++ b/ext/tidy/tidy.c @@ -68,6 +68,11 @@ ZEND_PARSE_PARAMETERS_NONE(); \ obj = Z_TIDY_P(ZEND_THIS); \ +#define TIDY_FETCH_VALID_NODE \ + TIDY_FETCH_ONLY_OBJECT; \ + if (tidy_node_validate(obj) != SUCCESS) { \ + RETURN_THROWS(); \ + } #define TIDY_SET_DEFAULT_CONFIG(_doc) \ if (TG(default_config) && TG(default_config)[0]) { \ php_tidy_load_config(_doc, TG(default_config)); \ @@ -94,12 +99,14 @@ struct _PHPTidyDoc { TidyDoc doc; TidyBuffer *errbuf; uint32_t ref_count; + size_t parse_generation; bool initialized; }; struct _PHPTidyObj { TidyNode node; tidy_obj_type type; + size_t node_generation; PHPTidyDoc *ptdoc; zend_object std; }; @@ -211,12 +218,28 @@ static zend_result php_tidy_apply_config(TidyDoc doc, const zend_string *str_str return SUCCESS; } +static zend_result tidy_node_validate(const PHPTidyObj *obj) +{ + if (!obj->ptdoc) { + zend_throw_error(NULL, "tidyNode object is not initialized"); + return FAILURE; + } + + if (obj->node_generation != obj->ptdoc->parse_generation) { + zend_throw_error(NULL, "tidyNode object is no longer valid after its document was reparsed"); + return FAILURE; + } + + return SUCCESS; +} + static void tidy_create_node_object(zval *zv, PHPTidyDoc *ptdoc, TidyNode node) { object_init_ex(zv, tidy_ce_node); PHPTidyObj *newobj = Z_TIDY_P(zv); newobj->node = node; newobj->type = is_node; + newobj->node_generation = ptdoc->parse_generation; newobj->ptdoc = ptdoc; newobj->ptdoc->ref_count++; tidy_add_node_default_properties(newobj); @@ -374,6 +397,7 @@ static zend_object *tidy_object_new(zend_class_entry *class_type, const zend_obj intern->ptdoc = emalloc(sizeof(PHPTidyDoc)); intern->ptdoc->doc = tidyCreate(); intern->ptdoc->ref_count = 1; + intern->ptdoc->parse_generation = 0; intern->ptdoc->initialized = false; intern->ptdoc->errbuf = emalloc(sizeof(TidyBuffer)); tidyBufInit(intern->ptdoc->errbuf); @@ -468,6 +492,9 @@ static zend_result tidy_node_cast_handler(zend_object *in, zval *out, int type) case IS_STRING: obj = php_tidy_fetch_object(in); + if (tidy_node_validate(obj) != SUCCESS) { + return FAILURE; + } tidyBufInit(&buf); if (obj->ptdoc && tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf)) { ZVAL_STRINGL(out, (const char *) buf.bp, buf.size-1); @@ -524,6 +551,10 @@ static void tidy_add_node_default_properties(PHPTidyObj *obj) zval attribute, children, temp; const char *name; + if (tidy_node_validate(obj) != SUCCESS) { + return; + } + tidyBufInit(&buf); (void) tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf); @@ -814,6 +845,7 @@ static zend_result php_tidy_parse_string(PHPTidyObj *obj, const zend_string *str obj->ptdoc->initialized = true; tidyBufInit(&buf); + obj->ptdoc->parse_generation++; tidyBufAttach(&buf, (byte *) ZSTR_VAL(string), (unsigned int) ZSTR_LEN(string)); if (tidyParseBuffer(obj->ptdoc->doc, &buf) < 0) { php_error_docref(NULL, E_WARNING, "%s", (const char*) obj->ptdoc->errbuf->bp); @@ -1473,7 +1505,7 @@ PHP_FUNCTION(tidy_get_body) /* {{{ Returns true if this node has children */ PHP_METHOD(tidyNode, hasChildren) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; RETURN_BOOL(tidyGetChild(obj->node)); } @@ -1482,7 +1514,7 @@ PHP_METHOD(tidyNode, hasChildren) /* {{{ Returns true if this node has siblings */ PHP_METHOD(tidyNode, hasSiblings) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; RETURN_BOOL(obj->node && tidyGetNext(obj->node)); } @@ -1491,7 +1523,7 @@ PHP_METHOD(tidyNode, hasSiblings) /* {{{ Returns true if this node represents a comment */ PHP_METHOD(tidyNode, isComment) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; RETURN_BOOL(tidyNodeGetType(obj->node) == TidyNode_Comment); } @@ -1500,7 +1532,7 @@ PHP_METHOD(tidyNode, isComment) /* {{{ Returns true if this node is part of a HTML document */ PHP_METHOD(tidyNode, isHtml) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; switch (tidyNodeGetType(obj->node)) { case TidyNode_Start: @@ -1516,7 +1548,7 @@ PHP_METHOD(tidyNode, isHtml) /* {{{ Returns true if this node represents text (no markup) */ PHP_METHOD(tidyNode, isText) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; RETURN_BOOL(tidyNodeGetType(obj->node) == TidyNode_Text); } @@ -1525,7 +1557,7 @@ PHP_METHOD(tidyNode, isText) /* {{{ Returns true if this node is JSTE */ PHP_METHOD(tidyNode, isJste) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; RETURN_BOOL(tidyNodeGetType(obj->node) == TidyNode_Jste); } @@ -1534,7 +1566,7 @@ PHP_METHOD(tidyNode, isJste) /* {{{ Returns true if this node is ASP */ PHP_METHOD(tidyNode, isAsp) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; RETURN_BOOL(tidyNodeGetType(obj->node) == TidyNode_Asp); } @@ -1543,7 +1575,7 @@ PHP_METHOD(tidyNode, isAsp) /* {{{ Returns true if this node is PHP */ PHP_METHOD(tidyNode, isPhp) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; RETURN_BOOL(tidyNodeGetType(obj->node) == TidyNode_Php); } @@ -1552,7 +1584,7 @@ PHP_METHOD(tidyNode, isPhp) /* {{{ Returns the parent node if available or NULL */ PHP_METHOD(tidyNode, getParent) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; TidyNode parent_node = tidyGetParent(obj->node); if (parent_node) { @@ -1563,7 +1595,7 @@ PHP_METHOD(tidyNode, getParent) PHP_METHOD(tidyNode, getPreviousSibling) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; TidyNode previous_node = tidyGetPrev(obj->node); if (previous_node) { @@ -1573,7 +1605,7 @@ PHP_METHOD(tidyNode, getPreviousSibling) PHP_METHOD(tidyNode, getNextSibling) { - TIDY_FETCH_ONLY_OBJECT; + TIDY_FETCH_VALID_NODE; TidyNode next_node = tidyGetNext(obj->node); if (next_node) { diff --git a/main/streams/stream_errors.c b/main/streams/stream_errors.c index e16d3425a4d3..788dceff445b 100644 --- a/main/streams/stream_errors.c +++ b/main/streams/stream_errors.c @@ -369,7 +369,7 @@ static void php_stream_call_error_handler(const zval *handler, zval *errors_arra zend_fcall_info_cache fcc; char *is_callable_error = NULL; - if (!zend_is_callable_ex(handler, NULL, 0, NULL, &fcc, &is_callable_error)) { + if (!zend_is_callable(handler, &fcc, &is_callable_error)) { if (is_callable_error) { zend_type_error("stream error handler must be a valid callback, %s", is_callable_error); efree(is_callable_error);