From f48abfa9022c026c2447b14bc03c978d2b831b27 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 9 Oct 2017 15:35:38 +0200 Subject: Fix array access on undeclared properties in DateInterval --- ext/date/php_date.c | 37 +++++++++++++++++++++++++++++- ext/date/tests/date_interval_prop_dim.phpt | 16 +++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 ext/date/tests/date_interval_prop_dim.phpt diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 00722d3c8e..f46167bf60 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -647,6 +647,7 @@ static HashTable *date_object_get_gc_timezone(zval *object, zval **table, int *n zval *date_interval_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv); void date_interval_write_property(zval *object, zval *member, zval *value, void **cache_slot); +static zval *date_interval_get_property_ptr_ptr(zval *object, zval *member, int type, void **cache_slot); static zval *date_period_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv); static void date_period_write_property(zval *object, zval *member, zval *value, void **cache_slot); @@ -2117,7 +2118,7 @@ static void date_register_classes(void) /* {{{ */ date_object_handlers_interval.read_property = date_interval_read_property; date_object_handlers_interval.write_property = date_interval_write_property; date_object_handlers_interval.get_properties = date_object_get_properties_interval; - date_object_handlers_interval.get_property_ptr_ptr = NULL; + date_object_handlers_interval.get_property_ptr_ptr = date_interval_get_property_ptr_ptr; date_object_handlers_interval.get_gc = date_object_get_gc_interval; INIT_CLASS_ENTRY(ce_period, "DatePeriod", date_funcs_period); @@ -4142,6 +4143,40 @@ void date_interval_write_property(zval *object, zval *member, zval *value, void } /* }}} */ +/* {{{ date_interval_get_property_ptr_ptr */ +static zval *date_interval_get_property_ptr_ptr(zval *object, zval *member, int type, void **cache_slot) +{ + zval tmp_member, *ret; + + if (Z_TYPE_P(member) != IS_STRING) { + tmp_member = *member; + zval_copy_ctor(&tmp_member); + convert_to_string(&tmp_member); + member = &tmp_member; + cache_slot = NULL; + } + + if(zend_binary_strcmp("y", sizeof("y") - 1, Z_STRVAL_P(member), Z_STRLEN_P(member)) == 0 || + zend_binary_strcmp("m", sizeof("m") - 1, Z_STRVAL_P(member), Z_STRLEN_P(member)) == 0 || + zend_binary_strcmp("d", sizeof("d") - 1, Z_STRVAL_P(member), Z_STRLEN_P(member)) == 0 || + zend_binary_strcmp("h", sizeof("h") - 1, Z_STRVAL_P(member), Z_STRLEN_P(member)) == 0 || + zend_binary_strcmp("i", sizeof("i") - 1, Z_STRVAL_P(member), Z_STRLEN_P(member)) == 0 || + zend_binary_strcmp("s", sizeof("s") - 1, Z_STRVAL_P(member), Z_STRLEN_P(member)) == 0 || + zend_binary_strcmp("days", sizeof("days") - 1, Z_STRVAL_P(member), Z_STRLEN_P(member)) == 0 || + zend_binary_strcmp("invert", sizeof("invert") - 1, Z_STRVAL_P(member), Z_STRLEN_P(member)) == 0) { + /* Fallback to read_property. */ + ret = NULL; + } else { + ret = (zend_get_std_object_handlers())->get_property_ptr_ptr(object, member, type, cache_slot); + } + + if (member == &tmp_member) { + zval_dtor(member); + } + + return ret; +} +/* }}} */ /* {{{ proto DateInterval::__construct([string interval_spec]) Creates new DateInterval object. diff --git a/ext/date/tests/date_interval_prop_dim.phpt b/ext/date/tests/date_interval_prop_dim.phpt new file mode 100644 index 0000000000..3f9af6f472 --- /dev/null +++ b/ext/date/tests/date_interval_prop_dim.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test DateInterval props with dimension handling +--FILE-- +prop[1]=10; +while ($i < 1026) { + $z->prop[$i] = $i; + $i++; +} +?> +==NOCRASH== +--EXPECT-- +==NOCRASH== -- cgit v1.2.1