Skip to content

Commit 74c006f

Browse files
Use proper hash_spec_result enum for return values in ext/hash (#19386)
1 parent d65025b commit 74c006f

File tree

10 files changed

+104
-96
lines changed

10 files changed

+104
-96
lines changed

UPGRADING.INTERNALS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ PHP 8.5 INTERNALS UPGRADE NOTES
2929
be heap-allocated and stored in the pointer as a minimal change to keep
3030
compatibility.
3131

32+
- Hash
33+
. Hash functions now use proper hash_spec_result enum for return values
34+
instead of using SUCCESS and FAILURE.
35+
3236
- Zend
3337
. Added zend_safe_assign_to_variable_noref() function to safely assign
3438
a value to a non-reference zval.

ext/hash/hash.c

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -229,20 +229,20 @@ static void one_to_buffer(size_t sz, unsigned char *buf, uint64_t val) {
229229
significant bits first. This allows 32-bit and 64-bit architectures to
230230
interchange serialized HashContexts. */
231231

232-
PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */
232+
PHP_HASH_API hash_spec_result php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */
233233
{
234234
size_t pos = 0, max_alignment = 1;
235235
unsigned char *buf = (unsigned char *) hash->context;
236236
zval tmp;
237237
if (buf == NULL) {
238-
return FAILURE;
238+
return HASH_SPEC_FAILURE;
239239
}
240240
array_init(zv);
241241
while (*spec != '\0' && *spec != '.') {
242242
char spec_ch = *spec;
243243
size_t sz, count = parse_serialize_spec(&spec, &pos, &sz, &max_alignment);
244244
if (pos + count * sz > hash->ops->context_size) {
245-
return FAILURE;
245+
return HASH_SPEC_FAILURE;
246246
}
247247
if (isupper((unsigned char) spec_ch)) {
248248
pos += count * sz;
@@ -265,38 +265,33 @@ PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *h
265265
}
266266
}
267267
if (*spec == '.' && align_to(pos, max_alignment) != hash->ops->context_size) {
268-
return FAILURE;
268+
return HASH_SPEC_FAILURE;
269269
}
270-
return SUCCESS;
270+
return HASH_SPEC_SUCCESS;
271271
}
272272
/* }}} */
273273

274-
/* Unserialize a hash context serialized by `php_hash_serialize_spec` with `spec`.
275-
Returns SUCCESS on success and a negative error code on failure.
276-
Codes: FAILURE (-1) == generic failure
277-
-999 == spec wrong size for context
278-
-1000 - POS == problem at byte offset POS */
279-
280-
PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec) /* {{{ */
274+
/* Unserialize a hash context serialized by `php_hash_serialize_spec` with `spec`. */
275+
PHP_HASH_API hash_spec_result php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec) /* {{{ */
281276
{
282277
size_t pos = 0, max_alignment = 1, j = 0;
283278
unsigned char *buf = (unsigned char *) hash->context;
284279
zval *elt;
285280
if (Z_TYPE_P(zv) != IS_ARRAY) {
286-
return FAILURE;
281+
return HASH_SPEC_FAILURE;
287282
}
288283
while (*spec != '\0' && *spec != '.') {
289284
char spec_ch = *spec;
290285
size_t sz, count = parse_serialize_spec(&spec, &pos, &sz, &max_alignment);
291286
if (pos + count * sz > hash->ops->context_size) {
292-
return -999;
287+
return WRONG_CONTEXT_SIZE;
293288
}
294289
if (isupper((unsigned char) spec_ch)) {
295290
pos += count * sz;
296291
} else if (sz == 1 && count > 1) {
297292
elt = zend_hash_index_find(Z_ARRVAL_P(zv), j);
298293
if (!elt || Z_TYPE_P(elt) != IS_STRING || Z_STRLEN_P(elt) != count) {
299-
return -1000 - pos;
294+
return BYTE_OFFSET_POS_ERROR - pos;
300295
}
301296
++j;
302297
memcpy(buf + pos, Z_STRVAL_P(elt), count);
@@ -306,14 +301,14 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const z
306301
uint64_t val;
307302
elt = zend_hash_index_find(Z_ARRVAL_P(zv), j);
308303
if (!elt || Z_TYPE_P(elt) != IS_LONG) {
309-
return -1000 - pos;
304+
return BYTE_OFFSET_POS_ERROR - pos;
310305
}
311306
++j;
312307
val = (uint32_t) Z_LVAL_P(elt);
313308
if (sz == 8) {
314309
elt = zend_hash_index_find(Z_ARRVAL_P(zv), j);
315310
if (!elt || Z_TYPE_P(elt) != IS_LONG) {
316-
return -1000 - pos;
311+
return BYTE_OFFSET_POS_ERROR - pos;
317312
}
318313
++j;
319314
val += ((uint64_t) Z_LVAL_P(elt)) << 32;
@@ -325,31 +320,32 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const z
325320
}
326321
}
327322
if (*spec == '.' && align_to(pos, max_alignment) != hash->ops->context_size) {
328-
return -999;
323+
return WRONG_CONTEXT_SIZE;
329324
}
330-
return SUCCESS;
325+
326+
return HASH_SPEC_SUCCESS;
331327
}
332328
/* }}} */
333329

334-
PHP_HASH_API zend_result php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */
330+
PHP_HASH_API hash_spec_result php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */
335331
{
336-
if (hash->ops->serialize_spec) {
337-
*magic = PHP_HASH_SERIALIZE_MAGIC_SPEC;
338-
return php_hash_serialize_spec(hash, zv, hash->ops->serialize_spec);
339-
} else {
340-
return FAILURE;
341-
}
332+
if (!hash->ops->serialize_spec) {
333+
return HASH_SPEC_FAILURE;
334+
}
335+
336+
*magic = PHP_HASH_SERIALIZE_MAGIC_SPEC;
337+
return php_hash_serialize_spec(hash, zv, hash->ops->serialize_spec);
342338
}
343339
/* }}} */
344340

345-
PHP_HASH_API int php_hash_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) /* {{{ */
341+
PHP_HASH_API hash_spec_result php_hash_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) /* {{{ */
346342
{
347343
if (hash->ops->serialize_spec
348344
&& magic == PHP_HASH_SERIALIZE_MAGIC_SPEC) {
349345
return php_hash_unserialize_spec(hash, zv, hash->ops->serialize_spec);
350-
} else {
351-
return FAILURE;
352346
}
347+
348+
return HASH_SPEC_FAILURE;
353349
}
354350
/* }}} */
355351

@@ -1475,7 +1471,7 @@ PHP_METHOD(HashContext, __serialize)
14751471
ZVAL_LONG(&tmp, hash->options);
14761472
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);
14771473

1478-
if (hash->ops->hash_serialize(hash, &magic, &tmp) != SUCCESS) {
1474+
if (hash->ops->hash_serialize(hash, &magic, &tmp) != HASH_SPEC_SUCCESS) {
14791475
goto serialize_failure;
14801476
}
14811477
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);
@@ -1504,7 +1500,7 @@ PHP_METHOD(HashContext, __unserialize)
15041500
HashTable *data;
15051501
zval *algo_zv, *magic_zv, *options_zv, *hash_zv, *members_zv;
15061502
zend_long magic, options;
1507-
int unserialize_result;
1503+
hash_spec_result unserialize_result;
15081504
const php_hash_ops *ops;
15091505

15101506
if (zend_parse_parameters(ZEND_NUM_ARGS(), "h", &data) == FAILURE) {
@@ -1553,7 +1549,7 @@ PHP_METHOD(HashContext, __unserialize)
15531549
ops->hash_init(hash->context, NULL);
15541550

15551551
unserialize_result = ops->hash_unserialize(hash, magic, hash_zv);
1556-
if (unserialize_result != SUCCESS) {
1552+
if (unserialize_result != HASH_SPEC_SUCCESS) {
15571553
zend_throw_exception_ex(NULL, 0, "Incomplete or ill-formed serialization data (\"%s\" code %d)", ops->algo, unserialize_result);
15581554
/* free context */
15591555
php_hashcontext_dtor(Z_OBJ_P(object));

ext/hash/hash_gost.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -304,17 +304,17 @@ PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context)
304304
ZEND_SECURE_ZERO(context, sizeof(*context));
305305
}
306306

307-
static int php_gost_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
307+
static hash_spec_result php_gost_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
308308
{
309309
PHP_GOST_CTX *ctx = (PHP_GOST_CTX *) hash->context;
310-
int r = FAILURE;
310+
hash_spec_result r = HASH_SPEC_FAILURE;
311311
if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
312-
&& (r = php_hash_unserialize_spec(hash, zv, PHP_GOST_SPEC)) == SUCCESS
312+
&& (r = php_hash_unserialize_spec(hash, zv, PHP_GOST_SPEC)) == HASH_SPEC_SUCCESS
313313
&& ctx->length < sizeof(ctx->buffer)) {
314-
return SUCCESS;
315-
} else {
316-
return r != SUCCESS ? r : -2000;
314+
return HASH_SPEC_SUCCESS;
317315
}
316+
317+
return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE;
318318
}
319319

320320
const php_hash_ops php_hash_gost_ops = {

ext/hash/hash_md.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const php_hash_ops php_hash_md4_ops = {
4747
1
4848
};
4949

50-
static int php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv);
50+
static hash_spec_result php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv);
5151

5252
const php_hash_ops php_hash_md2_ops = {
5353
"md2",
@@ -356,15 +356,15 @@ PHP_HASH_API void PHP_MD2Final(unsigned char output[16], PHP_MD2_CTX *context)
356356
memcpy(output, context->state, 16);
357357
}
358358

359-
static int php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
359+
static hash_spec_result php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
360360
{
361361
PHP_MD2_CTX *ctx = (PHP_MD2_CTX *) hash->context;
362-
int r = FAILURE;
362+
hash_spec_result r = HASH_SPEC_FAILURE;
363363
if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
364-
&& (r = php_hash_unserialize_spec(hash, zv, PHP_MD2_SPEC)) == SUCCESS
364+
&& (r = php_hash_unserialize_spec(hash, zv, PHP_MD2_SPEC)) == HASH_SPEC_SUCCESS
365365
&& (unsigned char) ctx->in_buffer < sizeof(ctx->buffer)) {
366-
return SUCCESS;
367-
} else {
368-
return r != SUCCESS ? r : -2000;
366+
return HASH_SPEC_SUCCESS;
369367
}
368+
369+
return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE;
370370
}

ext/hash/hash_sha3.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -200,20 +200,20 @@ static void PHP_SHA3_Final(unsigned char* digest,
200200
ZEND_SECURE_ZERO(ctx, sizeof(PHP_SHA3_CTX));
201201
}
202202

203-
static int php_sha3_unserialize(php_hashcontext_object *hash,
203+
static hash_spec_result php_sha3_unserialize(php_hashcontext_object *hash,
204204
zend_long magic,
205205
const zval *zv,
206206
size_t block_size)
207207
{
208208
PHP_SHA3_CTX *ctx = (PHP_SHA3_CTX *) hash->context;
209-
int r = FAILURE;
209+
hash_spec_result r = HASH_SPEC_FAILURE;
210210
if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
211-
&& (r = php_hash_unserialize_spec(hash, zv, PHP_SHA3_SPEC)) == SUCCESS
211+
&& (r = php_hash_unserialize_spec(hash, zv, PHP_SHA3_SPEC)) == HASH_SPEC_SUCCESS
212212
&& ctx->pos < block_size) {
213-
return SUCCESS;
214-
} else {
215-
return r != SUCCESS ? r : -2000;
213+
return HASH_SPEC_SUCCESS;
216214
}
215+
216+
return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE;
217217
}
218218

219219
// ==========================================================================
@@ -292,23 +292,23 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \
292292
#endif
293293
#define PHP_KECCAK_SPEC "b200IiIIB"
294294

295-
static zend_result php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv)
295+
static hash_spec_result php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv)
296296
{
297297
*magic = PHP_HASH_SERIALIZE_MAGIC_KECCAK;
298298
return php_hash_serialize_spec(hash, zv, PHP_KECCAK_SPEC);
299299
}
300300

301-
static int php_keccak_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
301+
static hash_spec_result php_keccak_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
302302
{
303303
Keccak_HashInstance *ctx = (Keccak_HashInstance *) hash->context;
304-
int r = FAILURE;
304+
hash_spec_result r = HASH_SPEC_FAILURE;
305305
if (magic == PHP_HASH_SERIALIZE_MAGIC_KECCAK
306-
&& (r = php_hash_unserialize_spec(hash, zv, PHP_KECCAK_SPEC)) == SUCCESS
306+
&& (r = php_hash_unserialize_spec(hash, zv, PHP_KECCAK_SPEC)) == HASH_SPEC_SUCCESS
307307
&& ctx->sponge.byteIOIndex < ctx->sponge.rate / 8) {
308-
return SUCCESS;
309-
} else {
310-
return r != SUCCESS ? r : -2000;
308+
return HASH_SPEC_SUCCESS;
311309
}
310+
311+
return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE;
312312
}
313313

314314
// ==========================================================================

ext/hash/hash_snefru.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,17 +189,17 @@ PHP_HASH_API void PHP_SNEFRUFinal(unsigned char digest[32], PHP_SNEFRU_CTX *cont
189189
ZEND_SECURE_ZERO(context, sizeof(*context));
190190
}
191191

192-
static int php_snefru_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
192+
static hash_spec_result php_snefru_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
193193
{
194194
PHP_SNEFRU_CTX *ctx = (PHP_SNEFRU_CTX *) hash->context;
195-
int r = FAILURE;
195+
hash_spec_result r = HASH_SPEC_FAILURE;
196196
if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
197-
&& (r = php_hash_unserialize_spec(hash, zv, PHP_SNEFRU_SPEC)) == SUCCESS
197+
&& (r = php_hash_unserialize_spec(hash, zv, PHP_SNEFRU_SPEC)) == HASH_SPEC_SUCCESS
198198
&& ctx->length < sizeof(ctx->buffer)) {
199-
return SUCCESS;
200-
} else {
201-
return r != SUCCESS ? r : -2000;
199+
return HASH_SPEC_SUCCESS;
202200
}
201+
202+
return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE;
203203
}
204204

205205
const php_hash_ops php_hash_snefru_ops = {

ext/hash/hash_tiger.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -239,17 +239,17 @@ PHP_HASH_API void PHP_TIGER192Final(unsigned char digest[24], PHP_TIGER_CTX *con
239239
ZEND_SECURE_ZERO(context, sizeof(*context));
240240
}
241241

242-
static int php_tiger_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
242+
static hash_spec_result php_tiger_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
243243
{
244244
PHP_TIGER_CTX *ctx = (PHP_TIGER_CTX *) hash->context;
245-
int r = FAILURE;
245+
hash_spec_result r = HASH_SPEC_FAILURE;
246246
if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
247-
&& (r = php_hash_unserialize_spec(hash, zv, PHP_TIGER_SPEC)) == SUCCESS
247+
&& (r = php_hash_unserialize_spec(hash, zv, PHP_TIGER_SPEC)) == HASH_SPEC_SUCCESS
248248
&& ctx->length < sizeof(ctx->buffer)) {
249-
return SUCCESS;
250-
} else {
251-
return r != SUCCESS ? r : -2000;
249+
return HASH_SPEC_SUCCESS;
252250
}
251+
252+
return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE;
253253
}
254254

255255
#define PHP_HASH_TIGER_OPS(p, b) \

ext/hash/hash_whirlpool.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -429,20 +429,20 @@ PHP_HASH_API void PHP_WHIRLPOOLFinal(unsigned char digest[64], PHP_WHIRLPOOL_CTX
429429
ZEND_SECURE_ZERO(context, sizeof(*context));
430430
}
431431

432-
static int php_whirlpool_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
432+
static hash_spec_result php_whirlpool_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
433433
{
434434
PHP_WHIRLPOOL_CTX *ctx = (PHP_WHIRLPOOL_CTX *) hash->context;
435-
int r = FAILURE;
435+
hash_spec_result r = HASH_SPEC_FAILURE;
436436
if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
437-
&& (r = php_hash_unserialize_spec(hash, zv, PHP_WHIRLPOOL_SPEC)) == SUCCESS
437+
&& (r = php_hash_unserialize_spec(hash, zv, PHP_WHIRLPOOL_SPEC)) == HASH_SPEC_SUCCESS
438438
&& ctx->buffer.pos >= 0
439439
&& ctx->buffer.pos < (int) sizeof(ctx->buffer.data)
440440
&& ctx->buffer.bits >= ctx->buffer.pos * 8
441441
&& ctx->buffer.bits < ctx->buffer.pos * 8 + 8) {
442-
return SUCCESS;
443-
} else {
444-
return r != SUCCESS ? r : -2000;
442+
return HASH_SPEC_SUCCESS;
445443
}
444+
445+
return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE;
446446
}
447447

448448
const php_hash_ops php_hash_whirlpool_ops = {

0 commit comments

Comments
 (0)