Skip to content

Commit 1ee56bd

Browse files
committed
Fix out of bound writes to SafeArray data
Converting PHP arrays to Variants originally supported almost arbitrary numeric arrays, possibly filling gaps with NULL values. This is broken as of PHP 7.0.0[1] so that the SafeArray only has as many elements as the PHP array. Thus, unless the array is a list, some elements may be written outside of the SafeArray data. To avoid breaking userland code after that long time, we do not restore the original behavior, but instead only suppress the erroneous writes. To avoid the need to split the regression test for 32bit and 64bit Windows, we suppress the "max number 4294967295 of elements in safe array exceeded" warning, which only occurs for 64bit versions. [1] <c865472> Closes GH-16309.
1 parent e49d732 commit 1ee56bd

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.2.26
44

5+
- COM:
6+
. Fixed out of bound writes to SafeArray data. (cmb)
7+
58
- Curl:
69
. Fixed bug GH-16302 (CurlMultiHandle holds a reference to CurlHandle if
710
curl_multi_add_handle fails). (timwolla)

ext/com_dotnet/com_variant.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626

2727
/* create an automation SafeArray from a PHP array.
2828
* Only creates a single-dimensional array of variants.
29-
* The keys of the PHP hash MUST be numeric. If the array
30-
* is sparse, then the gaps will be filled with NULL variants */
29+
* The keys of the PHP hash MUST be numeric. */
3130
static void safe_array_from_zval(VARIANT *v, zval *z, int codepage)
3231
{
3332
SAFEARRAY *sa = NULL;
@@ -71,7 +70,9 @@ static void safe_array_from_zval(VARIANT *v, zval *z, int codepage)
7170
break;
7271
}
7372
zend_hash_get_current_key_ex(Z_ARRVAL_P(z), &strindex, &intindex, &pos);
74-
php_com_variant_from_zval(&va[intindex], item, codepage);
73+
if (intindex < bound.cElements) {
74+
php_com_variant_from_zval(&va[intindex], item, codepage);
75+
}
7576
}
7677

7778
/* Unlock it and stuff it into our variant */
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
Testing variant arrays
3+
--EXTENSIONS--
4+
com_dotnet
5+
--FILE--
6+
<?php
7+
$arrays = [
8+
"order" => [2 => 1, 1 => 2, 0 => 3],
9+
"off" => [2 => 1, 1 => 2, 3],
10+
"negative" => [-1 => 42],
11+
];
12+
foreach ($arrays as $desc => $array) {
13+
echo "-- $desc --\n";
14+
$v = new variant($array);
15+
foreach ($v as $val) {
16+
var_dump($val);
17+
}
18+
}
19+
?>
20+
--EXPECTF--
21+
-- order --
22+
int(3)
23+
int(2)
24+
int(1)
25+
-- off --
26+
NULL
27+
int(2)
28+
int(1)
29+
-- negative --
30+
%ANULL

0 commit comments

Comments
 (0)