[php-src] master: Merge branch 'PHP-8.6'

From: Date: Sat, 24 Oct 2026 08:56:02 +0000
Subject: [php-src] master: Merge branch 'PHP-8.6'
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-142660@lists.php.net to get a copy of this message
Author: ndossche (ndossche) Date: 2026-10-24T10:55:52+02:00 Commit: https://github.com/php/php-src/commit/0c2f56bedfd1ecacf846d176476c0cba9fd2127a Raw diff: https://github.com/php/php-src/commit/0c2f56bedfd1ecacf846d176476c0cba9fd2127a.diff Merge branch 'PHP-8.6' * PHP-8.6: Fix GOST and Snefru digests of 512 MiB or more Changed paths: A ext/hash/tests/gost_snefru_512mib.phpt M ext/hash/hash_gost.c M ext/hash/hash_snefru.c Diff: diff --git a/ext/hash/hash_gost.c b/ext/hash/hash_gost.c index 91edbd50834f..f141a58e8a38 100644 --- a/ext/hash/hash_gost.c +++ b/ext/hash/hash_gost.c @@ -245,17 +245,12 @@ PHP_HASH_API void PHP_GOSTInitCrypto(PHP_GOST_CTX *context, ZEND_ATTRIBUTE_UNUSE context->tables = &tables_crypto; } -static const uint32_t MAX32 = 0xffffffffLU; - PHP_HASH_API void PHP_GOSTUpdate(PHP_GOST_CTX *context, const unsigned char *input, size_t len) { - if ((MAX32 - context->count[0]) < (len * 8)) { - context->count[1]++; - context->count[0] = MAX32 - context->count[0]; - context->count[0] = (len * 8) - context->count[0]; - } else { - context->count[0] += len * 8; - } + uint64_t count = (((uint64_t) context->count[1] << 32) | context->count[0]) + (uint64_t) len * 8; + + context->count[0] = (uint32_t) count; + context->count[1] = (uint32_t) (count >> 32); if (context->length + len < 32) { memcpy(&context->buffer[context->length], input, len); diff --git a/ext/hash/hash_snefru.c b/ext/hash/hash_snefru.c index 3fe16b4398a3..6ecca3bcb67e 100644 --- a/ext/hash/hash_snefru.c +++ b/ext/hash/hash_snefru.c @@ -131,17 +131,12 @@ PHP_HASH_API void PHP_SNEFRUInit(PHP_SNEFRU_CTX *context, ZEND_ATTRIBUTE_UNUSED memset(context, 0, sizeof(*context)); } -static const uint32_t MAX32 = 0xffffffffLU; - PHP_HASH_API void PHP_SNEFRUUpdate(PHP_SNEFRU_CTX *context, const unsigned char *input, size_t len) { - if ((MAX32 - context->count[1]) < (len * 8)) { - context->count[0]++; - context->count[1] = MAX32 - context->count[1]; - context->count[1] = ((uint32_t) len * 8) - context->count[1]; - } else { - context->count[1] += (uint32_t) len * 8; - } + uint64_t count = (((uint64_t) context->count[0] << 32) | context->count[1]) + (uint64_t) len * 8; + + context->count[0] = (uint32_t) (count >> 32); + context->count[1] = (uint32_t) count; if (context->length + len < 32) { memcpy(&context->buffer[context->length], input, len); diff --git a/ext/hash/tests/gost_snefru_512mib.phpt b/ext/hash/tests/gost_snefru_512mib.phpt new file mode 100644 index 000000000000..6649140b2722 --- /dev/null +++ b/ext/hash/tests/gost_snefru_512mib.phpt @@ -0,0 +1,29 @@ +--TEST-- +Hash: gost and snefru with 512 MiB of input (bit counter carry) +--SKIPIF-- +<?php +if (!getenv('RUN_RESOURCE_HEAVY_TESTS')) die('skip resource-heavy test'); +if (getenv('SKIP_SLOW_TESTS')) die('skip slow tests excluded by request'); +?> +--INI-- +memory_limit=-1 +--FILE-- +<?php +/* 2^29 bytes are 2^32 bits, so the low word of the bit counter wraps. */ +$chunk = str_repeat('a', 1 << 20); +foreach (['gost', 'snefru'] as $algo) { + $ctx = hash_init($algo); + for ($i = 0; $i < 512; $i++) { + hash_update($ctx, $chunk); + } + echo $algo, ': ', hash_final($ctx), "\n"; +} +unset($chunk); + +/* A single update of 2^29 bytes. */ +echo 'snefru: ', hash('snefru', str_repeat('a', 1 << 29)), "\n"; +?> +--EXPECT-- +gost: 6c30acc180f544a79c22fa763593a812aec721dd61658b1a5e9a6f3a7955146d +snefru: 0842a8e735ab08a30149e7e6e34833f365291978ee68c37a5135253b70afa486 +snefru: 0842a8e735ab08a30149e7e6e34833f365291978ee68c37a5135253b70afa486

« previous php.cvs (#142660) next »