summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/hash/hash.c6
-rw-r--r--ext/hash/tests/bug52240.phpt19
2 files changed, 23 insertions, 2 deletions
diff --git a/ext/hash/hash.c b/ext/hash/hash.c
index 85d67f9e25..d8240462bb 100644
--- a/ext/hash/hash.c
+++ b/ext/hash/hash.c
@@ -561,8 +561,10 @@ PHP_FUNCTION(hash_copy)
copy_hash->ops = hash->ops;
copy_hash->context = context;
copy_hash->options = hash->options;
- copy_hash->key = hash->key;
-
+ copy_hash->key = ecalloc(1, hash->ops->block_size);
+ if (hash->key) {
+ memcpy(copy_hash->key, hash->key, hash->ops->block_size);
+ }
ZEND_REGISTER_RESOURCE(return_value, copy_hash, php_hash_le_hash);
}
/* }}} */
diff --git a/ext/hash/tests/bug52240.phpt b/ext/hash/tests/bug52240.phpt
new file mode 100644
index 0000000000..1f8472c77b
--- /dev/null
+++ b/ext/hash/tests/bug52240.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Bug #52240 (hash_copy() does not copy the HMAC key, causes wrong results and PHP crashes)
+--SKIPIF--
+<?php extension_loaded('hash') or die('skip'); ?>
+--FILE--
+<?php
+
+$h = hash_init('crc32b', HASH_HMAC, '123456' );
+$h2 = hash_copy($h);
+var_dump(hash_final($h));
+$h3 = hash_copy($h2);
+var_dump(hash_final($h2));
+var_dump(hash_final($h3));
+
+?>
+--EXPECT--
+string(8) "278af264"
+string(8) "278af264"
+string(8) "278af264"