@@ -182,7 +182,7 @@ PHP_HASH_API int php_hash_serialize_spec(const php_hashcontext_object *hash, zen
182
182
size_t pos = 0 , sz , count ;
183
183
unsigned char * buf = (unsigned char * ) hash -> context ;
184
184
zval tmp ;
185
- * magic = 2 ;
185
+ * magic = PHP_HASH_SERIALIZE_MAGIC_SPEC ;
186
186
array_init (zv );
187
187
while (* spec != '\0' && * spec != '.' ) {
188
188
char specch = * spec ;
@@ -222,21 +222,21 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, zend_lo
222
222
size_t pos = 0 , sz , count , j = 0 ;
223
223
unsigned char * buf = (unsigned char * ) hash -> context ;
224
224
zval * elt ;
225
- if (magic != 2 || Z_TYPE_P (zv ) != IS_ARRAY ) {
226
- return FAILURE ;
225
+ if (magic != PHP_HASH_SERIALIZE_MAGIC_SPEC || Z_TYPE_P (zv ) != IS_ARRAY ) {
226
+ return -2000 ;
227
227
}
228
228
while (* spec != '\0' && * spec != '.' ) {
229
229
char specch = * spec ;
230
230
count = parse_serialize_spec (& spec , & pos , & sz );
231
231
if (pos + count * sz > hash -> ops -> context_size ) {
232
- return FAILURE ;
232
+ return -1000 - pos ;
233
233
}
234
234
if (specch == '-' ) {
235
235
pos += count ;
236
236
} else if (sz == 1 && count > 1 ) {
237
237
elt = zend_hash_index_find (Z_ARRVAL_P (zv ), j );
238
238
if (!elt || Z_TYPE_P (elt ) != IS_STRING || Z_STRLEN_P (elt ) != count ) {
239
- return FAILURE ;
239
+ return -1000 - pos ;
240
240
}
241
241
++ j ;
242
242
memcpy (buf + pos , Z_STRVAL_P (elt ), count );
@@ -246,14 +246,14 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, zend_lo
246
246
uint64_t val ;
247
247
elt = zend_hash_index_find (Z_ARRVAL_P (zv ), j );
248
248
if (!elt || Z_TYPE_P (elt ) != IS_LONG ) {
249
- return FAILURE ;
249
+ return -1000 - pos ;
250
250
}
251
251
++ j ;
252
252
val = (uint32_t ) zval_get_long (elt );
253
253
if (sz == 8 ) {
254
254
elt = zend_hash_index_find (Z_ARRVAL_P (zv ), j );
255
255
if (!elt || Z_TYPE_P (elt ) != IS_LONG ) {
256
- return FAILURE ;
256
+ return -1000 - pos ;
257
257
}
258
258
++ j ;
259
259
val += ((uint64_t ) zval_get_long (elt )) << 32 ;
@@ -265,7 +265,7 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, zend_lo
265
265
}
266
266
}
267
267
if (* spec == '.' && pos != hash -> ops -> context_size ) {
268
- return FAILURE ;
268
+ return -2001 ;
269
269
}
270
270
return SUCCESS ;
271
271
}
@@ -1434,6 +1434,7 @@ PHP_METHOD(HashContext, __unserialize)
1434
1434
HashTable * data ;
1435
1435
zval * algo_zv , * magic_zv , * options_zv , * hash_zv , * members_zv ;
1436
1436
zend_long magic , options ;
1437
+ int unserialize_result ;
1437
1438
const php_hash_ops * ops ;
1438
1439
1439
1440
if (zend_parse_parameters (ZEND_NUM_ARGS (), "h" , & data ) == FAILURE ) {
@@ -1481,8 +1482,9 @@ PHP_METHOD(HashContext, __unserialize)
1481
1482
ops -> hash_init (hash -> context );
1482
1483
hash -> options = options ;
1483
1484
1484
- if (ops -> hash_unserialize (hash , magic , hash_zv ) != SUCCESS ) {
1485
- zend_value_error ("HashContext for algorithm '%s' cannot be unserialized, format may be non-portable" , ops -> algo );
1485
+ unserialize_result = ops -> hash_unserialize (hash , magic , hash_zv );
1486
+ if (unserialize_result != SUCCESS ) {
1487
+ zend_value_error ("HashContext for algorithm '%s' cannot be unserialized, format may be non-portable (code %d)" , ops -> algo , unserialize_result );
1486
1488
/* Free internally allocated resources */
1487
1489
php_hashcontext_dtor (Z_OBJ_P (object ));
1488
1490
RETURN_THROWS ();
0 commit comments