diff --git a/NEWS b/NEWS index 15c85841eea..88cd54f5479 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,10 @@ PHP NEWS - Filter: . Fix explicit FILTER_REQUIRE_SCALAR with FILTER_CALLBACK (ilutov) +- Hash: + . Fixed bug GH-12186 (segfault copying/cloning a finalized HashContext). + (MaxSem) + - SimpleXML: . Fixed bug GH-12170 (Can't use xpath with comments in SimpleXML). (nielsdos) diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 2d29ff61fa0..c01a1f0f3ec 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -680,7 +680,7 @@ PHP_FUNCTION(hash_init) #define PHP_HASHCONTEXT_VERIFY(hash) { \ if (!hash->context) { \ - zend_argument_type_error(1, "must be a valid Hash Context resource"); \ + zend_argument_type_error(1, "must be a valid, non-finalized HashContext"); \ RETURN_THROWS(); \ } \ } @@ -837,11 +837,15 @@ PHP_FUNCTION(hash_final) PHP_FUNCTION(hash_copy) { zval *zhash; + php_hashcontext_object *context; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zhash, php_hashcontext_ce) == FAILURE) { RETURN_THROWS(); } + context = php_hashcontext_from_object(Z_OBJ_P(zhash)); + PHP_HASHCONTEXT_VERIFY(context); + RETVAL_OBJ(Z_OBJ_HANDLER_P(zhash, clone_obj)(Z_OBJ_P(zhash))); if (php_hashcontext_from_object(Z_OBJ_P(return_value))->context == NULL) { @@ -1405,6 +1409,11 @@ static zend_object *php_hashcontext_clone(zend_object *zobj) { zend_object *znew = php_hashcontext_create(zobj->ce); php_hashcontext_object *newobj = php_hashcontext_from_object(znew); + if (!oldobj->context) { + zend_throw_exception(zend_ce_value_error, "Cannot clone a finalized HashContext", 0); + return znew; + } + zend_objects_clone_members(znew, zobj); newobj->ops = oldobj->ops; diff --git a/ext/hash/tests/gh12186_1.phpt b/ext/hash/tests/gh12186_1.phpt new file mode 100644 index 00000000000..5e34b1dd78e --- /dev/null +++ b/ext/hash/tests/gh12186_1.phpt @@ -0,0 +1,17 @@ +--TEST-- +Hash: bug #12186 - segfault in hash_copy() on a finalized context +--FILE-- +getMessage() . "\n"; +} + +?> +--EXPECTF-- +hash_copy(): Argument #1 ($context) must be a valid, non-finalized HashContext diff --git a/ext/hash/tests/gh12186_2.phpt b/ext/hash/tests/gh12186_2.phpt new file mode 100644 index 00000000000..64a12b15c39 --- /dev/null +++ b/ext/hash/tests/gh12186_2.phpt @@ -0,0 +1,17 @@ +--TEST-- +Hash: bug #12186 - segfault when cloning a finalized context +--FILE-- +getMessage() . "\n"; +} + +?> +--EXPECTF-- +Cannot clone a finalized HashContext diff --git a/ext/hash/tests/reuse.phpt b/ext/hash/tests/reuse.phpt index 229236dd713..b5cfc79c162 100644 --- a/ext/hash/tests/reuse.phpt +++ b/ext/hash/tests/reuse.phpt @@ -14,4 +14,4 @@ catch (\Error $e) { ?> --EXPECT-- -hash_update(): Argument #1 ($context) must be a valid Hash Context resource +hash_update(): Argument #1 ($context) must be a valid, non-finalized HashContext