Skip to content

Commit 6c16086

Browse files
committed
ext/standard: Add some sscanf tests
This is in preparation for some major refactoring as the current error messages are non-sensical
1 parent a1e9a9a commit 6c16086

7 files changed

+319
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
sscanf(): with strings containing null bytes
3+
--FILE--
4+
<?php
5+
6+
$str = "Hello\0wonderful\0World!";
7+
$format = "%s\0%s\0%s";
8+
try {
9+
var_dump(sscanf($str, $format));
10+
} catch (Throwable $e) {
11+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
12+
}
13+
try {
14+
var_dump(sscanf($str, $format, $a, $b, $c));
15+
var_dump($a, $b, $c);
16+
} catch (Throwable $e) {
17+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
18+
}
19+
?>
20+
--EXPECT--
21+
array(1) {
22+
[0]=>
23+
string(5) "Hello"
24+
}
25+
ValueError: Variable is not assigned by any conversion specifiers
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
--TEST--
2+
sscanf(): format string XPG argument tests
3+
--FILE--
4+
<?php
5+
6+
7+
$formats = [
8+
'%1$s %2$s %1$s',
9+
'%1$s %*s %3$s',
10+
'%s %*s %3$s',
11+
];
12+
13+
$str = "Hello World";
14+
15+
foreach ($formats as $format) {
16+
echo "Using format string '$format':\n";
17+
try {
18+
var_dump(sscanf($str, $format));
19+
} catch (Throwable $e) {
20+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
21+
}
22+
try {
23+
var_dump(sscanf($str, $format, $a, $b, $c));
24+
var_dump($a, $b, $c);
25+
$a = $b = $c = null;
26+
} catch (Throwable $e) {
27+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
28+
}
29+
}
30+
?>
31+
--EXPECT--
32+
Using format string '%1$s %2$s %1$s':
33+
ValueError: Variable is assigned by multiple "%n$" conversion specifiers
34+
ValueError: Variable is assigned by multiple "%n$" conversion specifiers
35+
Using format string '%1$s %*s %3$s':
36+
array(3) {
37+
[0]=>
38+
string(5) "Hello"
39+
[1]=>
40+
NULL
41+
[2]=>
42+
NULL
43+
}
44+
ValueError: Variable is not assigned by any conversion specifiers
45+
Using format string '%s %*s %3$s':
46+
ValueError: cannot mix "%" and "%n$" conversion specifiers
47+
ValueError: cannot mix "%" and "%n$" conversion specifiers
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
sscanf(): unterminated range [] specifier
3+
--FILE--
4+
<?php
5+
6+
function combinatorial_concat(string $base, array $patterns): array {
7+
$r = [$base];
8+
foreach ($patterns as $pattern) {
9+
$r = array_merge(
10+
...array_map(
11+
fn (string $str) => [$str, $str . $pattern],
12+
$r,
13+
)
14+
);
15+
}
16+
return $r;
17+
}
18+
19+
$modifiers = [
20+
'^',
21+
']',
22+
];
23+
24+
$formats = combinatorial_concat('%[', $modifiers);
25+
26+
$str = "Hello World";
27+
28+
foreach ($formats as $format) {
29+
echo "Using format string '$format':\n";
30+
try {
31+
sscanf($str, $format);
32+
} catch (Throwable $e) {
33+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
34+
}
35+
}
36+
?>
37+
--EXPECT--
38+
Using format string '%[':
39+
ValueError: Unmatched [ in format string
40+
Using format string '%[]':
41+
ValueError: Unmatched [ in format string
42+
Using format string '%[^':
43+
ValueError: Unmatched [ in format string
44+
Using format string '%[^]':
45+
ValueError: Unmatched [ in format string
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
--TEST--
2+
sscanf(): format string which is unterminated
3+
--FILE--
4+
<?php
5+
6+
function combinatorial_concat(string $base, array $patterns): array {
7+
$r = [$base];
8+
foreach ($patterns as $pattern) {
9+
$r = array_merge(
10+
...array_map(
11+
fn (string $str) => [$str, $str . $pattern],
12+
$r,
13+
)
14+
);
15+
}
16+
return $r;
17+
}
18+
19+
$modifiers = [
20+
'*',
21+
'1$', // XPG
22+
'2', // Width
23+
'L', // Size
24+
];
25+
26+
$formats = combinatorial_concat('%', $modifiers);
27+
28+
$str = "Hello World";
29+
30+
foreach ($formats as $format) {
31+
echo "Using format string '$format':\n";
32+
try {
33+
sscanf($str, $format);
34+
} catch (Throwable $e) {
35+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
36+
}
37+
}
38+
?>
39+
--EXPECT--
40+
Using format string '%':
41+
ValueError: Bad scan conversion character "
42+
Using format string '%L':
43+
ValueError: Bad scan conversion character "
44+
Using format string '%2':
45+
ValueError: Bad scan conversion character "
46+
Using format string '%2L':
47+
ValueError: Bad scan conversion character "
48+
Using format string '%1$':
49+
ValueError: Bad scan conversion character "
50+
Using format string '%1$L':
51+
ValueError: Bad scan conversion character "
52+
Using format string '%1$2':
53+
ValueError: Bad scan conversion character "
54+
Using format string '%1$2L':
55+
ValueError: Bad scan conversion character "
56+
Using format string '%*':
57+
ValueError: Bad scan conversion character "
58+
Using format string '%*L':
59+
ValueError: Bad scan conversion character "
60+
Using format string '%*2':
61+
ValueError: Bad scan conversion character "
62+
Using format string '%*2L':
63+
ValueError: Bad scan conversion character "
64+
Using format string '%*1$':
65+
ValueError: Bad scan conversion character "$"
66+
Using format string '%*1$L':
67+
ValueError: Bad scan conversion character "$"
68+
Using format string '%*1$2':
69+
ValueError: Bad scan conversion character "$"
70+
Using format string '%*1$2L':
71+
ValueError: Bad scan conversion character "$"
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
sscanf(): test %[] specifier with edge cases
3+
--FILE--
4+
<?php
5+
6+
try {
7+
sscanf('[hello]', '%[][helo]', $out);
8+
var_dump($out);
9+
} catch (Throwable $e) {
10+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
11+
}
12+
try {
13+
sscanf('-in-', '%[-i-n]', $out);
14+
var_dump($out);
15+
} catch (Throwable $e) {
16+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
17+
}
18+
try {
19+
sscanf('-[in]-', '%[][-i-n]', $out);
20+
var_dump($out);
21+
} catch (Throwable $e) {
22+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
23+
}
24+
?>
25+
--EXPECT--
26+
string(7) "[hello]"
27+
string(4) "-in-"
28+
string(4) "-in-"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
--TEST--
2+
sscanf(): test %[] specifier with numbers
3+
--FILE--
4+
<?php
5+
6+
$formats = [
7+
'%[240531]',
8+
'%[0-5]',
9+
'%[5-0]',
10+
'%[^9687]',
11+
'%[^6-9]',
12+
'%[^9-6]',
13+
'%4[240531]',
14+
'%4[0-5]',
15+
'%4[5-0]',
16+
'%4[^9687]',
17+
'%4[^6-9]',
18+
'%4[^9-6]',
19+
];
20+
21+
$str = "00112233445566778899";
22+
23+
foreach ($formats as $format) {
24+
echo "Using format string '$format':\n";
25+
sscanf($str, $format, $out);
26+
var_dump($out);
27+
}
28+
?>
29+
--EXPECT--
30+
Using format string '%[240531]':
31+
string(12) "001122334455"
32+
Using format string '%[0-5]':
33+
string(12) "001122334455"
34+
Using format string '%[5-0]':
35+
string(12) "001122334455"
36+
Using format string '%[^9687]':
37+
string(12) "001122334455"
38+
Using format string '%[^6-9]':
39+
string(12) "001122334455"
40+
Using format string '%[^9-6]':
41+
string(12) "001122334455"
42+
Using format string '%4[240531]':
43+
string(4) "0011"
44+
Using format string '%4[0-5]':
45+
string(4) "0011"
46+
Using format string '%4[5-0]':
47+
string(4) "0011"
48+
Using format string '%4[^9687]':
49+
string(4) "0011"
50+
Using format string '%4[^6-9]':
51+
string(4) "0011"
52+
Using format string '%4[^9-6]':
53+
string(4) "0011"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
sscanf(): test %[] specifier with strings
3+
--FILE--
4+
<?php
5+
6+
$formats = [
7+
'%[aefgbcd]',
8+
'%[a-g]',
9+
'%[g-a]',
10+
'%[^uvwstxyz]',
11+
'%[^s-z]',
12+
'%[^z-s]',
13+
'%4[aefgbcd]',
14+
'%4[g-a]',
15+
'%4[^uvwstxyz]',
16+
'%4[^s-z]',
17+
'%4[^z-s]',
18+
];
19+
20+
$str = "abcdefghijklmnopqrstuvwxyz";
21+
22+
foreach ($formats as $format) {
23+
echo "Using format string '$format':\n";
24+
sscanf($str, $format, $out);
25+
var_dump($out);
26+
}
27+
?>
28+
--EXPECT--
29+
Using format string '%[aefgbcd]':
30+
string(7) "abcdefg"
31+
Using format string '%[a-g]':
32+
string(7) "abcdefg"
33+
Using format string '%[g-a]':
34+
string(7) "abcdefg"
35+
Using format string '%[^uvwstxyz]':
36+
string(18) "abcdefghijklmnopqr"
37+
Using format string '%[^s-z]':
38+
string(18) "abcdefghijklmnopqr"
39+
Using format string '%[^z-s]':
40+
string(18) "abcdefghijklmnopqr"
41+
Using format string '%4[aefgbcd]':
42+
string(4) "abcd"
43+
Using format string '%4[g-a]':
44+
string(4) "abcd"
45+
Using format string '%4[^uvwstxyz]':
46+
string(4) "abcd"
47+
Using format string '%4[^s-z]':
48+
string(4) "abcd"
49+
Using format string '%4[^z-s]':
50+
string(4) "abcd"

0 commit comments

Comments
 (0)