From: Dmitry Stogov Date: Thu, 22 Jan 2015 08:50:42 +0000 (+0300) Subject: zend_read_property() has to provide a holder for return value. X-Git-Tag: PRE_PHP7_REMOVALS~25^2~37^2^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3e31838d19750d287431d22e9290856ec962fd6a;p=php zend_read_property() has to provide a holder for return value. Previously it was possible that zend_read_property() returned pointer to zval allocated on stack. --- diff --git a/Zend/zend_API.c b/Zend/zend_API.c index b78cde9b57..3da626139d 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3761,11 +3761,10 @@ ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const } /* }}} */ -ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent) /* {{{ */ +ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv) /* {{{ */ { zval property, *value; zend_class_entry *old_scope = EG(scope); - zval rv; EG(scope) = scope; @@ -3774,7 +3773,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c } ZVAL_STRINGL(&property, name, name_length); - value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, NULL, &rv); + value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, NULL, rv); zval_ptr_dtor(&property); EG(scope) = old_scope; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 724ea9e99b..e3be8d7138 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -335,7 +335,7 @@ ZEND_API int zend_update_static_property_double(zend_class_entry *scope, const c ZEND_API int zend_update_static_property_string(zend_class_entry *scope, const char *name, size_t name_length, const char *value); ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const char *name, size_t name_length, const char *value, size_t value_length); -ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent); +ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv); ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent); diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index cb98df24c1..655542fc30 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -37,7 +37,7 @@ ZEND_API void (*zend_throw_exception_hook)(zval *ex); void zend_exception_set_previous(zend_object *exception, zend_object *add_previous) { - zval tmp, *previous, zv, *pzv; + zval tmp, *previous, zv, *pzv, rv; if (exception == add_previous || !add_previous || !exception) { return; @@ -50,7 +50,7 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo ZVAL_OBJ(&zv, exception); pzv = &zv; do { - previous = zend_read_property(default_exception_ce, pzv, "previous", sizeof("previous")-1, 1); + previous = zend_read_property(default_exception_ce, pzv, "previous", sizeof("previous")-1, 1, &rv); if (Z_TYPE_P(previous) == IS_NULL) { zend_update_property(default_exception_ce, pzv, "previous", sizeof("previous")-1, &tmp); GC_REFCOUNT(add_previous)--; @@ -264,14 +264,16 @@ ZEND_METHOD(error_exception, __construct) } #define GET_PROPERTY(object, name) \ - zend_read_property(default_exception_ce, (object), name, sizeof(name) - 1, 0) + zend_read_property(default_exception_ce, (object), name, sizeof(name) - 1, 0, &rv) #define GET_PROPERTY_SILENT(object, name) \ - zend_read_property(default_exception_ce, (object), name, sizeof(name) - 1, 1) + zend_read_property(default_exception_ce, (object), name, sizeof(name) - 1, 1, &rv) /* {{{ proto string Exception::getFile() Get the file in which the exception occurred */ ZEND_METHOD(exception, getFile) { + zval rv; + DEFAULT_0_PARAMS; ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "file")); @@ -282,6 +284,8 @@ ZEND_METHOD(exception, getFile) Get the line in which the exception occurred */ ZEND_METHOD(exception, getLine) { + zval rv; + DEFAULT_0_PARAMS; ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "line")); @@ -292,6 +296,8 @@ ZEND_METHOD(exception, getLine) Get the exception message */ ZEND_METHOD(exception, getMessage) { + zval rv; + DEFAULT_0_PARAMS; ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "message")); @@ -302,6 +308,8 @@ ZEND_METHOD(exception, getMessage) Get the exception code */ ZEND_METHOD(exception, getCode) { + zval rv; + DEFAULT_0_PARAMS; ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "code")); @@ -312,6 +320,8 @@ ZEND_METHOD(exception, getCode) Get the stack trace for the location in which the exception occurred */ ZEND_METHOD(exception, getTrace) { + zval rv; + DEFAULT_0_PARAMS; ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "trace")); @@ -322,6 +332,8 @@ ZEND_METHOD(exception, getTrace) Get the exception severity */ ZEND_METHOD(error_exception, getSeverity) { + zval rv; + DEFAULT_0_PARAMS; ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "severity")); @@ -519,14 +531,14 @@ static void _build_trace_string(smart_str *str, HashTable *ht, uint32_t num) /* Obtain the backtrace for the exception as a string (instead of an array) */ ZEND_METHOD(exception, getTraceAsString) { - zval *trace, *frame; + zval *trace, *frame, rv; zend_ulong index; smart_str str = {0}; uint32_t num = 0; DEFAULT_0_PARAMS; - trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1); + trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1, &rv); ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(trace), index, frame) { if (Z_TYPE_P(frame) != IS_ARRAY) { zend_error(E_WARNING, "Expected array for frame %pu", index); @@ -549,6 +561,8 @@ ZEND_METHOD(exception, getTraceAsString) Return previous Exception or NULL. */ ZEND_METHOD(exception, getPrevious) { + zval rv; + DEFAULT_0_PARAMS; ZVAL_COPY(return_value, GET_PROPERTY_SILENT(getThis(), "previous")); @@ -585,7 +599,7 @@ ZEND_METHOD(exception, __toString) zval trace, *exception; zend_string *str; zend_fcall_info fci; - zval fname; + zval fname, rv; DEFAULT_0_PARAMS; @@ -802,7 +816,7 @@ ZEND_API void zend_exception_error(zend_object *ex, int severity) /* {{{ */ ZVAL_OBJ(&exception, ex); ce_exception = Z_OBJCE(exception); if (instanceof_function(ce_exception, default_exception_ce)) { - zval tmp; + zval tmp, rv; zend_string *str, *file = NULL; zend_long line = 0; diff --git a/ext/com_dotnet/com_wrapper.c b/ext/com_dotnet/com_wrapper.c index 3e36dc2be6..3b24267f2d 100644 --- a/ext/com_dotnet/com_wrapper.c +++ b/ext/com_dotnet/com_wrapper.c @@ -282,7 +282,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( * and expose it as a COM exception */ if (wFlags & DISPATCH_PROPERTYGET) { - retval = zend_read_property(Z_OBJCE(disp->object), &disp->object, Z_STRVAL_P(name), Z_STRLEN_P(name)+1, 1); + retval = zend_read_property(Z_OBJCE(disp->object), &disp->object, Z_STRVAL_P(name), Z_STRLEN_P(name)+1, 1, &rv); } else if (wFlags & DISPATCH_PROPERTYPUT) { zend_update_property(Z_OBJCE(disp->object), &disp->object, Z_STRVAL_P(name), Z_STRLEN_P(name), ¶ms[0]); } else if (wFlags & DISPATCH_METHOD) { diff --git a/ext/curl/curl_file.c b/ext/curl/curl_file.c index bff067e71d..f2937b4f0d 100644 --- a/ext/curl/curl_file.c +++ b/ext/curl/curl_file.c @@ -72,11 +72,12 @@ PHP_FUNCTION(curl_file_create) static void curlfile_get_property(char *name, INTERNAL_FUNCTION_PARAMETERS) { - zval *res; + zval *res, rv; + if (zend_parse_parameters_none() == FAILURE) { return; } - res = zend_read_property(curl_CURLFile_class, getThis(), name, strlen(name), 1); + res = zend_read_property(curl_CURLFile_class, getThis(), name, strlen(name), 1, &rv); RETURN_ZVAL(res, 1, 0); } diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 6ac5010d00..043e14fdab 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -2493,10 +2493,10 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ if (Z_TYPE_P(current) == IS_OBJECT && instanceof_function(Z_OBJCE_P(current), curl_CURLFile_class)) { /* new-style file upload */ - zval *prop; + zval *prop, rv; char *type = NULL, *filename = NULL; - prop = zend_read_property(curl_CURLFile_class, current, "name", sizeof("name")-1, 0); + prop = zend_read_property(curl_CURLFile_class, current, "name", sizeof("name")-1, 0, &rv); if (Z_TYPE_P(prop) != IS_STRING) { php_error_docref(NULL, E_WARNING, "Invalid filename for key %s", string_key->val); } else { @@ -2506,11 +2506,11 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ return 1; } - prop = zend_read_property(curl_CURLFile_class, current, "mime", sizeof("mime")-1, 0); + prop = zend_read_property(curl_CURLFile_class, current, "mime", sizeof("mime")-1, 0, &rv); if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) { type = Z_STRVAL_P(prop); } - prop = zend_read_property(curl_CURLFile_class, current, "postname", sizeof("postname")-1, 0); + prop = zend_read_property(curl_CURLFile_class, current, "postname", sizeof("postname")-1, 0, &rv); if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) { filename = Z_STRVAL_P(prop); } diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 7e2c49ff0c..6797e894b5 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -1562,11 +1562,12 @@ zval *dom_nodelist_read_dimension(zval *object, zval *offset, int type, zval *rv int dom_nodelist_has_dimension(zval *object, zval *member, int check_empty) { zend_long offset = zval_get_long(member); + zval rv; if (offset < 0) { return 0; } else { - zval *length = zend_read_property(Z_OBJCE_P(object), object, "length", sizeof("length") - 1, 0); + zval *length = zend_read_property(Z_OBJCE_P(object), object, "length", sizeof("length") - 1, 0, &rv); return length && offset < Z_LVAL_P(length); } diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 3f5c7a9062..c95ec0d81e 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -5013,13 +5013,14 @@ ZEND_METHOD(reflection_property, getValue) } else { const char *class_name, *prop_name; size_t prop_name_len; + zval rv; if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &object) == FAILURE) { return; } zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len); - member_p = zend_read_property(ref->ce, object, prop_name, prop_name_len, 1); + member_p = zend_read_property(ref->ce, object, prop_name, prop_name_len, 1, &rv); ZVAL_DUP(return_value, member_p); } } diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 9ceca5b631..a993b2ef8c 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -937,7 +937,7 @@ PHP_METHOD(SoapFault, SoapFault) SoapFault constructor */ PHP_METHOD(SoapFault, __toString) { - zval *faultcode, *faultstring, *file, *line, trace; + zval *faultcode, *faultstring, *file, *line, trace, rv1, rv2, rv3, rv4; zend_string *str; zend_fcall_info fci; zval *this_ptr; @@ -947,10 +947,10 @@ PHP_METHOD(SoapFault, __toString) } this_ptr = getThis(); - faultcode = zend_read_property(soap_fault_class_entry, this_ptr, "faultcode", sizeof("faultcode")-1, 1); - faultstring = zend_read_property(soap_fault_class_entry, this_ptr, "faultstring", sizeof("faultstring")-1, 1); - file = zend_read_property(soap_fault_class_entry, this_ptr, "file", sizeof("file")-1, 1); - line = zend_read_property(soap_fault_class_entry, this_ptr, "line", sizeof("line")-1, 1); + faultcode = zend_read_property(soap_fault_class_entry, this_ptr, "faultcode", sizeof("faultcode")-1, 1, &rv1); + faultstring = zend_read_property(soap_fault_class_entry, this_ptr, "faultstring", sizeof("faultstring")-1, 1, &rv2); + file = zend_read_property(soap_fault_class_entry, this_ptr, "file", sizeof("file")-1, 1, &rv3); + line = zend_read_property(soap_fault_class_entry, this_ptr, "line", sizeof("line")-1, 1, &rv4); fci.size = sizeof(fci); fci.function_table = &Z_OBJCE_P(getThis())->function_table; diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 9737a17ad9..80dcabb907 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -2031,7 +2031,7 @@ SPL_METHOD(RegexIterator, accept) char *subject; zend_string *result; int subject_len, use_copy, count = 0; - zval *subject_ptr, subject_copy, zcount, *replacement, tmp_replacement; + zval *subject_ptr, subject_copy, zcount, *replacement, tmp_replacement, rv; if (zend_parse_parameters_none() == FAILURE) { return; @@ -2096,7 +2096,7 @@ SPL_METHOD(RegexIterator, accept) break; case REGIT_MODE_REPLACE: - replacement = zend_read_property(intern->std.ce, getThis(), "replacement", sizeof("replacement")-1, 1); + replacement = zend_read_property(intern->std.ce, getThis(), "replacement", sizeof("replacement")-1, 1, &rv); if (Z_TYPE_P(replacement) != IS_STRING) { tmp_replacement = *replacement; zval_copy_ctor(&tmp_replacement); diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 07d7825dc7..ca0ea57fa7 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -1107,10 +1107,10 @@ static int do_cli(int argc, char **argv) /* {{{ */ zend_call_method_with_1_params(&ref, pce, &pce->constructor, "__construct", NULL, &arg); if (EG(exception)) { - zval tmp, *msg; + zval tmp, *msg, rv; ZVAL_OBJ(&tmp, EG(exception)); - msg = zend_read_property(zend_exception_get_default(), &tmp, "message", sizeof("message")-1, 0); + msg = zend_read_property(zend_exception_get_default(), &tmp, "message", sizeof("message")-1, 0, &rv); zend_printf("Exception: %s\n", Z_STRVAL_P(msg)); zval_ptr_dtor(&tmp); EG(exception) = NULL;