From bc59289b7a25219ea2179554dc26c88e533250a5 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 26 Oct 2017 13:05:23 +0300 Subject: Fixed indirect modification of magic method arguments. --- Zend/tests/bug75420.1.phpt | 18 ++++++++++++++++++ Zend/tests/bug75420.2.phpt | 20 ++++++++++++++++++++ Zend/tests/bug75420.3.phpt | 18 ++++++++++++++++++ Zend/tests/bug75420.4.phpt | 17 +++++++++++++++++ Zend/tests/bug75420.5.phpt | 19 +++++++++++++++++++ Zend/tests/bug75420.6.phpt | 19 +++++++++++++++++++ Zend/tests/bug75420.phpt | 2 +- Zend/zend_object_handlers.c | 25 +++++++++++++++++++------ 8 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 Zend/tests/bug75420.1.phpt create mode 100644 Zend/tests/bug75420.2.phpt create mode 100644 Zend/tests/bug75420.3.phpt create mode 100644 Zend/tests/bug75420.4.phpt create mode 100644 Zend/tests/bug75420.5.phpt create mode 100644 Zend/tests/bug75420.6.phpt diff --git a/Zend/tests/bug75420.1.phpt b/Zend/tests/bug75420.1.phpt new file mode 100644 index 0000000000..80e951ac9e --- /dev/null +++ b/Zend/tests/bug75420.1.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #75420.1 (Indirect modification of magic method argument) +--FILE-- +$name ?? 12); +var_dump($name); +?> +--EXPECT-- +string(3) "foo" +int(42) +int(24) diff --git a/Zend/tests/bug75420.2.phpt b/Zend/tests/bug75420.2.phpt new file mode 100644 index 0000000000..3e7a63ffed --- /dev/null +++ b/Zend/tests/bug75420.2.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #75420.2 (Indirect modification of magic method argument) +--FILE-- +$name ?? 12); +var_dump($name); +?> +--EXPECT-- +string(6) "foofoo" +int(42) +int(24) + diff --git a/Zend/tests/bug75420.3.phpt b/Zend/tests/bug75420.3.phpt new file mode 100644 index 0000000000..4810618d15 --- /dev/null +++ b/Zend/tests/bug75420.3.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #75420.3 (Indirect modification of magic method argument) +--FILE-- +$name)); +var_dump($name); +?> +--EXPECT-- +string(3) "foo" +bool(false) +int(24) diff --git a/Zend/tests/bug75420.4.phpt b/Zend/tests/bug75420.4.phpt new file mode 100644 index 0000000000..e25bf313cb --- /dev/null +++ b/Zend/tests/bug75420.4.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #75420.4 (Indirect modification of magic method argument) +--FILE-- +$name)); +?> +--EXPECT-- +string(6) "foofoo" +bool(false) diff --git a/Zend/tests/bug75420.5.phpt b/Zend/tests/bug75420.5.phpt new file mode 100644 index 0000000000..85fedc4679 --- /dev/null +++ b/Zend/tests/bug75420.5.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #75420.5 (Indirect modification of magic method argument) +--FILE-- +$name ?? 12); +var_dump($obj); +?> +--EXPECT-- +object(Test)#1 (0) { +} +int(42) +int(24) diff --git a/Zend/tests/bug75420.6.phpt b/Zend/tests/bug75420.6.phpt new file mode 100644 index 0000000000..e4aa230b48 --- /dev/null +++ b/Zend/tests/bug75420.6.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #75420.6 (Indirect modification of magic method argument) +--FILE-- +$name)); +var_dump($obj); +?> +--EXPECT-- +object(Test)#1 (0) { +} +bool(false) +int(24) diff --git a/Zend/tests/bug75420.phpt b/Zend/tests/bug75420.phpt index 969a4a0417..5528ad301b 100644 --- a/Zend/tests/bug75420.phpt +++ b/Zend/tests/bug75420.phpt @@ -13,5 +13,5 @@ $name = "foo"; var_dump($obj->$name ?? 12); ?> --EXPECT-- -int(24) +string(3) "foo" int(42) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 22455b9254..8028b2ee5b 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -507,7 +507,7 @@ static zend_long *zend_get_property_guard(zend_object *zobj, zend_string *member zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv) /* {{{ */ { zend_object *zobj; - zval tmp_member; + zval tmp_member, tmp_object; zval *retval; uint32_t property_offset; zend_long *guard = NULL; @@ -543,12 +543,18 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ goto exit; } + ZVAL_UNDEF(&tmp_object); + /* magic isset */ if ((type == BP_VAR_IS) && zobj->ce->__isset) { - zval tmp_object, tmp_result; + zval tmp_result; guard = zend_get_property_guard(zobj, Z_STR_P(member)); if (!((*guard) & IN_ISSET)) { + if (Z_TYPE(tmp_member) == IS_UNDEF) { + ZVAL_COPY(&tmp_member, member); + member = &tmp_member; + } ZVAL_COPY(&tmp_object, object); ZVAL_UNDEF(&tmp_result); @@ -563,7 +569,6 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ goto exit; } - zval_ptr_dtor(&tmp_object); zval_ptr_dtor(&tmp_result); } } @@ -574,10 +579,10 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ guard = zend_get_property_guard(zobj, Z_STR_P(member)); } if (!((*guard) & IN_GET)) { - zval tmp_object; - /* have getter - try with it! */ - ZVAL_COPY(&tmp_object, object); + if (Z_TYPE(tmp_object) == IS_UNDEF) { + ZVAL_COPY(&tmp_object, object); + } *guard |= IN_GET; /* prevent circular getting */ zend_std_call_getter(&tmp_object, member, rv); *guard &= ~IN_GET; @@ -597,6 +602,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ zval_ptr_dtor(&tmp_object); goto exit; } else { + zval_ptr_dtor(&tmp_object); if (Z_STRVAL_P(member)[0] == '\0') { if (Z_STRLEN_P(member) == 0) { zend_throw_error(NULL, "Cannot access empty property"); @@ -610,6 +616,9 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ } } } + + zval_ptr_dtor(&tmp_object); + if ((type != BP_VAR_IS)) { zend_error(E_NOTICE,"Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), Z_STRVAL_P(member)); } @@ -1510,6 +1519,10 @@ found: zval tmp_object; /* have issetter - try with it! */ + if (Z_TYPE(tmp_member) == IS_UNDEF) { + ZVAL_COPY(&tmp_member, member); + member = &tmp_member; + } ZVAL_COPY(&tmp_object, object); (*guard) |= IN_ISSET; /* prevent circular getting */ zend_std_call_issetter(&tmp_object, member, &rv); -- cgit v1.2.1