Skip to content

Commit 932d7a2

Browse files
committed
Generate tests comparing compile time to runtime offset behaviour
1 parent d1eb4a9 commit 932d7a2

File tree

2 files changed

+196
-0
lines changed

2 files changed

+196
-0
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
--TEST--
2+
Test binary operands exposing the same behavior at compile as at run time
3+
--INI--
4+
memory_limit=256M
5+
opcache.file_update_protection=1
6+
--SKIPIF--
7+
<?php
8+
//if (getenv("SKIP_SLOW_TESTS")) die('skip slow test');
9+
?>
10+
--FILE--
11+
<?php
12+
13+
$containers = [
14+
null,
15+
false,
16+
true,
17+
4,
18+
5.5,
19+
'10',
20+
'25.5',
21+
'string',
22+
[],
23+
STDERR,
24+
new stdClass(),
25+
];
26+
27+
$offsets = [
28+
null,
29+
false,
30+
true,
31+
4,
32+
5.5,
33+
6.0,
34+
//PHP_INT_MAX,
35+
//PHP_INT_MIN,
36+
PHP_INT_MAX * 2,
37+
PHP_INT_MIN * 2,
38+
INF,
39+
NAN,
40+
'string',
41+
'7',
42+
'8.5',
43+
'9.0',
44+
'2e3',
45+
'20a',
46+
' 20',
47+
'20 ',
48+
//"9179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368",
49+
//"-9179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368",
50+
"0x14",
51+
(string) PHP_INT_MAX * 2,
52+
(string) PHP_INT_MIN * 2,
53+
];
54+
55+
function makeContainer($container) {
56+
if (is_array($container)) {
57+
return "[]";
58+
}
59+
if (is_resource($container)) {
60+
return "STDERR";
61+
}
62+
if ($container instanceof stdClass) {
63+
return "new stdClass()";
64+
}
65+
return var_export($container, true);
66+
}
67+
function makeOffset($offset) {
68+
if ($offset === PHP_INT_MIN) {
69+
return "PHP_INT_MIN";
70+
}
71+
if ($offset === PHP_INT_MAX) {
72+
return "PHP_INT_MAX";
73+
}
74+
return var_export($offset, true);
75+
}
76+
77+
function makeTestFile($container, $offset) {
78+
$offset_p = makeOffset($offset);
79+
$container_p = makeContainer($container);
80+
$fileContent = <<<test
81+
<?php
82+
83+
\$container = $container_p;
84+
85+
// Read before write
86+
try {
87+
echo "Read before write:\\n";
88+
var_dump(\$container[$offset_p]);
89+
} catch (\Throwable \$e) {
90+
echo \$e->getMessage(), "\\n";
91+
}
92+
// Write
93+
try {
94+
echo "Write:\\n";
95+
\$container[$offset_p] = 'v';
96+
} catch (\Throwable \$e) {
97+
echo \$e->getMessage(), "\\n";
98+
}
99+
// Read
100+
try {
101+
echo "Read:\\n";
102+
var_dump(\$container[$offset_p]);
103+
} catch (\Throwable \$e) {
104+
echo \$e->getMessage(), "\\n";
105+
}
106+
// Read-Write
107+
try {
108+
echo "Read-Write:\\n";
109+
\$container[$offset_p] .= 'append';
110+
} catch (\Throwable \$e) {
111+
echo \$e->getMessage(), "\\n";
112+
}
113+
// Is
114+
try {
115+
echo "isset():\\n";
116+
var_dump(isset(\$container[$offset_p]));
117+
} catch (\Throwable \$e) {
118+
echo \$e->getMessage(), "\\n";
119+
}
120+
try {
121+
echo "empty():\\n";
122+
var_dump(empty(\$container[$offset_p]));
123+
} catch (\Throwable \$e) {
124+
echo \$e->getMessage(), "\\n";
125+
}
126+
try {
127+
echo "Coalesce():\\n";
128+
var_dump(\$container[$offset_p] ?? 'default');
129+
} catch (\Throwable \$e) {
130+
echo \$e->getMessage(), "\\n";
131+
}
132+
test;
133+
return $fileContent;
134+
}
135+
136+
$const_dim_filename = __DIR__ . DIRECTORY_SEPARATOR . 'compare_binary_offsets_temp.php';
137+
138+
$failures = [];
139+
$failuresNb = 0;
140+
$testCasesTotal = 0;
141+
142+
$var_dim_filename = __DIR__ . DIRECTORY_SEPARATOR . 'test_variable_offsets.inc';
143+
144+
ob_start();
145+
foreach ($containers as $container_orig) {
146+
foreach ($offsets as $offset) {
147+
$error = makeContainer($container_orig) . '[' . makeOffset($offset) . '] has different outputs' . "\n";
148+
file_put_contents($const_dim_filename, makeTestFile($container_orig, $offset));
149+
150+
include $const_dim_filename;
151+
$constOutput = ob_get_contents();
152+
ob_clean();
153+
$constOutput = str_replace(
154+
[$const_dim_filename],
155+
['%s'],
156+
$constOutput
157+
);
158+
159+
$dimension = $offset;
160+
$container = $container_orig;
161+
include $var_dim_filename;
162+
$varOutput = ob_get_contents();
163+
ob_clean();
164+
$varOutput = str_replace(
165+
[$var_dim_filename],
166+
['%s'],
167+
$varOutput
168+
);
169+
170+
if ($constOutput !== $varOutput) {
171+
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . "debug_const_{$failuresNb}.txt", $constOutput);
172+
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . "debug_var_{$failuresNb}.txt", $varOutput);
173+
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . "debug_test_case_{$failuresNb}.txt", makeTestFile($container_orig, $offset));
174+
++$failuresNb;
175+
$failures[] = $error;
176+
}
177+
++$testCasesTotal;
178+
}
179+
}
180+
ob_end_clean();
181+
182+
echo "Executed $testCasesTotal tests\n";
183+
if ($failures !== []) {
184+
echo "Failures:\n" . implode($failures);
185+
}
186+
187+
?>
188+
--CLEAN--
189+
<?php
190+
$fl = __DIR__ . DIRECTORY_SEPARATOR . 'compare_binary_offsets_temp.php';
191+
@unlink($fl);
192+
?>
193+
--EXPECT--
194+
Executed 231 tests

Zend/tests/offsets/test_variable_offsets.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
//$container var declaration in const generated file
4+
35
// Read before write
46
try {
57
echo "Read before write:\n";

0 commit comments

Comments
 (0)