From 5e7e357012409e9ccdab7c591376fd3d30c0fbfc Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 4 Aug 2024 23:49:05 +0200 Subject: [PATCH] Fix crash when converting array data for array in shm in xxh3 --- ext/hash/hash_xxhash.c | 10 +++++++--- ext/hash/tests/xxh3_convert_secret_to_string.phpt | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 ext/hash/tests/xxh3_convert_secret_to_string.phpt diff --git a/ext/hash/hash_xxhash.c b/ext/hash/hash_xxhash.c index 8a155c986227..24da754d8835 100644 --- a/ext/hash/hash_xxhash.c +++ b/ext/hash/hash_xxhash.c @@ -174,11 +174,14 @@ zend_always_inline static void _PHP_XXH3_Init(PHP_XXH3_64_CTX *ctx, HashTable *a func_init_seed(&ctx->s, (XXH64_hash_t)Z_LVAL_P(_seed)); return; } else if (_secret) { - if (!try_convert_to_string(_secret)) { + zend_string *secret_string = zval_try_get_string(_secret); + if (UNEXPECTED(!secret_string)) { + ZEND_ASSERT(EG(exception)); return; } - size_t len = Z_STRLEN_P(_secret); + size_t len = ZSTR_LEN(secret_string); if (len < PHP_XXH3_SECRET_SIZE_MIN) { + zend_string_release(secret_string); zend_throw_error(NULL, "%s: Secret length must be >= %u bytes, %zu bytes passed", algo_name, XXH3_SECRET_SIZE_MIN, len); return; } @@ -186,7 +189,8 @@ zend_always_inline static void _PHP_XXH3_Init(PHP_XXH3_64_CTX *ctx, HashTable *a len = sizeof(ctx->secret); php_error_docref(NULL, E_WARNING, "%s: Secret content exceeding %zu bytes discarded", algo_name, sizeof(ctx->secret)); } - memcpy((unsigned char *)ctx->secret, Z_STRVAL_P(_secret), len); + memcpy((unsigned char *)ctx->secret, ZSTR_VAL(secret_string), len); + zend_string_release(secret_string); func_init_secret(&ctx->s, ctx->secret, len); return; } diff --git a/ext/hash/tests/xxh3_convert_secret_to_string.phpt b/ext/hash/tests/xxh3_convert_secret_to_string.phpt new file mode 100644 index 000000000000..dfc161b084c0 --- /dev/null +++ b/ext/hash/tests/xxh3_convert_secret_to_string.phpt @@ -0,0 +1,14 @@ +--TEST-- +xxh3 convert secret to string should not modify (shm) array +--FILE-- + 4]); +} catch (Throwable) {} +var_dump($x); +?> +--EXPECT-- +array(1) { + ["secret"]=> + int(4) +}