Skip to content

Commit 562e6bc

Browse files
committed
fix #83
checking the count of an array with its internal next free element index is insufficient to determine if the array has sequential keys
1 parent 1a8533f commit 562e6bc

3 files changed

Lines changed: 50 additions & 16 deletions

File tree

msgpack_pack.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,16 @@
2121
#include "msgpack/pack_template.h"
2222

2323
static inline int msgpack_check_ht_is_map(zval *array) /* {{{ */ {
24-
uint32_t count;
25-
26-
ZEND_ASSERT(Z_TYPE_P(array) == IS_ARRAY);
27-
28-
count = zend_hash_num_elements(Z_ARRVAL_P(array));
29-
30-
if (count != (Z_ARRVAL_P(array))->nNextFreeElement) {
31-
return 1;
32-
} else {
33-
zend_string *key;
24+
Bucket *b;
25+
zend_ulong i = 0;
3426

35-
ZEND_HASH_FOREACH_STR_KEY(Z_ARRVAL_P(array), key) {
36-
if (key) {
37-
return 1;
38-
}
39-
} ZEND_HASH_FOREACH_END();
27+
ZEND_HASH_FOREACH_BUCKET(Z_ARRVAL_P(array), b)
28+
{
29+
if (b->key || b->h != i++) {
30+
return 1;
31+
}
4032
}
33+
ZEND_HASH_FOREACH_END();
4134
return 0;
4235
}
4336
/* }}} */

tests/bug006.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ Array
3333
)
3434
Array
3535
(
36-
[0] => dummy
3736
[1] => foo
3837
[2] => bar
38+
[0] => dummy
3939
)
4040
string(3) "foo"
4141
string(3) "bar"

tests/issue083.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Issue #83 (Arrays and negative index)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded("msgpack")) {
6+
die("skip");
7+
}
8+
?>
9+
--FILE--
10+
<?php
11+
12+
var_dump(msgpack_unpack(msgpack_pack([-1=>-1,1=>1])));
13+
14+
$a = [
15+
-1 => -1,
16+
0,
17+
1 => 1,
18+
2
19+
];
20+
// next free element == 3 and count() == 3, but it's still not an MP array
21+
unset($a[1]);
22+
var_dump(msgpack_unpack(msgpack_pack($a)));
23+
24+
?>
25+
OK
26+
--EXPECT--
27+
array(2) {
28+
[-1]=>
29+
int(-1)
30+
[1]=>
31+
int(1)
32+
}
33+
array(3) {
34+
[-1]=>
35+
int(-1)
36+
[0]=>
37+
int(0)
38+
[2]=>
39+
int(2)
40+
}
41+
OK

0 commit comments

Comments
 (0)