Skip to content

Commit 9523b8c

Browse files
committed
Add switch error handling to other strpos variants
1 parent e72bf63 commit 9523b8c

16 files changed

+472
-320
lines changed

ext/mbstring/libmbfl/mbfl/mbfilter.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -881,13 +881,15 @@ mbfl_strpos(
881881
goto out;
882882
}
883883

884+
885+
size_t jtbl[1 << (sizeof(unsigned char) * 8)];
886+
size_t needle_u8_len = needle_u8->len;
887+
size_t i;
888+
const unsigned char *p, *q, *e;
889+
const unsigned char *haystack_u8_val = haystack_u8->val,
890+
*needle_u8_val = needle_u8->val;
891+
/* Bug somewhere in this segment for Out Of Bound detection (normal mode (i.e. !reverse) with negative offsets) */
884892
if (!reverse) {
885-
size_t jtbl[1 << (sizeof(unsigned char) * 8)];
886-
size_t needle_u8_len = needle_u8->len;
887-
size_t i;
888-
const unsigned char *p, *q, *e;
889-
const unsigned char *haystack_u8_val = haystack_u8->val,
890-
*needle_u8_val = needle_u8->val;
891893
for (i = 0; i < sizeof(jtbl) / sizeof(*jtbl); ++i) {
892894
jtbl[i] = needle_u8_len + 1;
893895
}
@@ -897,6 +899,7 @@ mbfl_strpos(
897899
e = haystack_u8_val + haystack_u8->len;
898900
p = haystack_u8_val;
899901
while (offset-- > 0) {
902+
/* If positive offset is larger than the number of code points in the string */
900903
if (p >= e) {
901904
result = (size_t) -16;
902905
goto out;
@@ -933,12 +936,8 @@ mbfl_strpos(
933936
}
934937
}
935938
} else {
936-
size_t jtbl[1 << (sizeof(unsigned char) * 8)];
937-
size_t needle_u8_len = needle_u8->len, needle_len = 0;
938-
size_t i;
939-
const unsigned char *p, *e, *q, *qe;
940-
const unsigned char *haystack_u8_val = haystack_u8->val,
941-
*needle_u8_val = needle_u8->val;
939+
size_t needle_len = 0;
940+
const unsigned char *qe;
942941
for (i = 0; i < sizeof(jtbl) / sizeof(*jtbl); ++i) {
943942
jtbl[i] = needle_u8_len;
944943
}

ext/mbstring/mbstring.c

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,22 +2115,24 @@ PHP_FUNCTION(mb_strpos)
21152115
RETVAL_LONG(n);
21162116
} else {
21172117
switch (-n) {
2118-
case 1:
2119-
break;
2120-
case 2:
2121-
php_error_docref(NULL, E_WARNING, "Needle has not positive length");
2122-
break;
2123-
case 4:
2124-
php_error_docref(NULL, E_WARNING, "Unknown encoding or conversion error");
2125-
break;
2126-
case 8:
2127-
php_error_docref(NULL, E_NOTICE, "Argument is empty");
2128-
break;
2129-
default:
2130-
php_error_docref(NULL, E_WARNING, "Unknown error in mb_strpos");
2131-
break;
2118+
case 1:
2119+
RETURN_FALSE;
2120+
case 2:
2121+
zend_value_error("Needle has not positive length");
2122+
RETURN_THROWS();
2123+
case 4:
2124+
zend_value_error("Unknown encoding or conversion error");
2125+
RETURN_THROWS();
2126+
case 8:
2127+
zend_value_error("Argument is empty");
2128+
RETURN_THROWS();
2129+
case 16:
2130+
zend_value_error("Offset not contained in string");
2131+
RETURN_THROWS();
2132+
default:
2133+
zend_value_error("Unknown error in mb_strripos");
2134+
RETURN_THROWS();
21322135
}
2133-
RETVAL_FALSE;
21342136
}
21352137
}
21362138
/* }}} */
@@ -2166,7 +2168,25 @@ PHP_FUNCTION(mb_strrpos)
21662168
if (!mbfl_is_error(n)) {
21672169
RETVAL_LONG(n);
21682170
} else {
2169-
RETVAL_FALSE;
2171+
switch (-n) {
2172+
case 1:
2173+
RETURN_FALSE;
2174+
case 2:
2175+
zend_value_error("Needle has not positive length");
2176+
RETURN_THROWS();
2177+
case 4:
2178+
zend_value_error("Unknown encoding or conversion error");
2179+
RETURN_THROWS();
2180+
case 8:
2181+
zend_value_error("Argument is empty");
2182+
RETURN_THROWS();
2183+
case 16:
2184+
zend_value_error("Offset not contained in string");
2185+
RETURN_THROWS();
2186+
default:
2187+
zend_value_error("Unknown error in mb_strripos");
2188+
RETURN_THROWS();
2189+
}
21702190
}
21712191
}
21722192
/* }}} */
@@ -2189,7 +2209,25 @@ PHP_FUNCTION(mb_stripos)
21892209
if (!mbfl_is_error(n)) {
21902210
RETVAL_LONG(n);
21912211
} else {
2192-
RETVAL_FALSE;
2212+
switch (-n) {
2213+
case 1:
2214+
RETURN_FALSE;
2215+
case 2:
2216+
zend_value_error("Needle has not positive length");
2217+
RETURN_THROWS();
2218+
case 4:
2219+
zend_value_error("Unknown encoding or conversion error");
2220+
RETURN_THROWS();
2221+
case 8:
2222+
zend_value_error("Argument is empty");
2223+
RETURN_THROWS();
2224+
case 16:
2225+
zend_value_error("Offset not contained in string");
2226+
RETURN_THROWS();
2227+
default:
2228+
zend_value_error("Unknown error in mb_strripos");
2229+
RETURN_THROWS();
2230+
}
21932231
}
21942232
}
21952233
/* }}} */
@@ -2212,7 +2250,25 @@ PHP_FUNCTION(mb_strripos)
22122250
if (!mbfl_is_error(n)) {
22132251
RETVAL_LONG(n);
22142252
} else {
2215-
RETVAL_FALSE;
2253+
switch (-n) {
2254+
case 1:
2255+
RETURN_FALSE;
2256+
case 2:
2257+
zend_value_error("Needle has not positive length");
2258+
RETURN_THROWS();
2259+
case 4:
2260+
zend_value_error("Unknown encoding or conversion error");
2261+
RETURN_THROWS();
2262+
case 8:
2263+
zend_value_error("Argument is empty");
2264+
RETURN_THROWS();
2265+
case 16:
2266+
zend_value_error("Offset not contained in string");
2267+
RETURN_THROWS();
2268+
default:
2269+
zend_value_error("Unknown error in mb_strripos");
2270+
RETURN_THROWS();
2271+
}
22162272
}
22172273
}
22182274
/* }}} */

ext/mbstring/tests/bug43840.phpt

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,20 @@ $needle = base64_decode('44CC');
2626
foreach($offsets as $i) {
2727
echo "\n-- Offset is $i --\n";
2828
echo "--Multibyte String:--\n";
29-
var_dump( mb_strpos($string_mb, $needle, $i, 'UTF-8') );
29+
try {
30+
var_dump( mb_strpos($string_mb, $needle, $i, 'UTF-8') );
31+
} catch (\ValueError $e) {
32+
echo $e->getMessage() . \PHP_EOL;
33+
}
3034
echo"--ASCII String:--\n";
31-
var_dump(mb_strpos('This is na English ta', 'a', $i));
35+
try {
36+
var_dump(mb_strpos('This is na English ta', 'a', $i));
37+
} catch (\ValueError $e) {
38+
echo $e->getMessage() . \PHP_EOL;
39+
}
3240
}
3341
?>
34-
--EXPECTF--
42+
--EXPECT--
3543
-- Offset is 20 --
3644
--Multibyte String:--
3745
int(20)
@@ -46,30 +54,18 @@ bool(false)
4654

4755
-- Offset is 22 --
4856
--Multibyte String:--
49-
50-
Warning: mb_strpos(): Offset not contained in string in %s on line %d
51-
bool(false)
57+
Offset not contained in string
5258
--ASCII String:--
53-
54-
Warning: mb_strpos(): Offset not contained in string in %s on line %d
55-
bool(false)
59+
Offset not contained in string
5660

5761
-- Offset is 53 --
5862
--Multibyte String:--
59-
60-
Warning: mb_strpos(): Offset not contained in string in %s on line %d
61-
bool(false)
63+
Offset not contained in string
6264
--ASCII String:--
63-
64-
Warning: mb_strpos(): Offset not contained in string in %s on line %d
65-
bool(false)
65+
Offset not contained in string
6666

6767
-- Offset is 54 --
6868
--Multibyte String:--
69-
70-
Warning: mb_strpos(): Offset not contained in string in %s on line %d
71-
bool(false)
69+
Offset not contained in string
7270
--ASCII String:--
73-
74-
Warning: mb_strpos(): Offset not contained in string in %s on line %d
75-
bool(false)
71+
Offset not contained in string

ext/mbstring/tests/bug43841.phpt

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,30 @@ function_exists('mb_strrpos') or die("skip mb_strrpos() is not available in this
1717
*/
1818

1919
$offsets = array(-25, -24, -13, -12);
20-
$string_mb =
21-
base64_decode('5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvv
22-
JfvvJjvvJnjgII=');
23-
$needle = base64_decode('44CC');
20+
// Japanese string in UTF-8
21+
$string_mb = "日本語テキストです。0123456789。";
22+
$needle = "";
2423

2524
foreach ($offsets as $i) {
2625
echo "\n-- Offset is $i --\n";
2726
echo "Multibyte String:\n";
28-
var_dump( mb_strrpos($string_mb, $needle, $i, 'UTF-8') );
27+
try {
28+
var_dump( mb_strrpos($string_mb, $needle, $i, 'UTF-8') );
29+
} catch (\ValueError $e) {
30+
echo $e->getMessage() . \PHP_EOL;
31+
}
2932
echo "ASCII String:\n";
3033
echo "mb_strrpos:\n";
31-
var_dump(mb_strrpos('This is na English ta', 'a', $i));
34+
try {
35+
var_dump(mb_strrpos('This is na English ta', 'a', $i));
36+
} catch (\ValueError $e) {
37+
echo $e->getMessage() . \PHP_EOL;
38+
}
3239
echo "strrpos:\n";
3340
try {
3441
var_dump(strrpos('This is na English ta', 'a', $i));
35-
} catch (ValueError $exception) {
36-
echo $exception->getMessage() . "\n";
42+
} catch (\ValueError $e) {
43+
echo $e->getMessage() . \PHP_EOL;
3744
}
3845
}
3946
?>

ext/mbstring/tests/bug45923.phpt

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ Bug #45923 (mb_st[r]ripos() offset not handled correctly)
88
function section($func, $haystack, $needle)
99
{
1010
echo "\n------- $func -----------\n\n";
11-
foreach(array(0, 3, 6, 9, 11, 12, -1, -3, -6, -20) as $offset) {
11+
foreach([0, 3, 6, 9, 11, 12, -1, -3, -6, -20] as $offset) {
1212
echo "> Offset: $offset\n";
13-
try {
14-
var_dump($func($haystack,$needle,$offset));
15-
} catch (ValueError $exception) {
16-
echo $exception->getMessage() . "\n";
17-
}
13+
try {
14+
var_dump($func($haystack, $needle, $offset));
15+
} catch (\ValueError $e) {
16+
echo $e->getMessage() . \PHP_EOL;
17+
}
1818
}
1919
}
2020

@@ -67,19 +67,15 @@ bool(false)
6767
> Offset: 11
6868
bool(false)
6969
> Offset: 12
70-
71-
Warning: mb_strpos(): Offset not contained in string in %s on line %d
72-
bool(false)
70+
Offset not contained in string
7371
> Offset: -1
7472
bool(false)
7573
> Offset: -3
7674
int(8)
7775
> Offset: -6
7876
int(8)
7977
> Offset: -20
80-
81-
Warning: mb_strpos(): Offset not contained in string in %s on line %d
82-
bool(false)
78+
Offset not contained in string
8379

8480
------- stripos -----------
8581

@@ -117,19 +113,15 @@ bool(false)
117113
> Offset: 11
118114
bool(false)
119115
> Offset: 12
120-
121-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
122-
bool(false)
116+
Offset not contained in string
123117
> Offset: -1
124118
bool(false)
125119
> Offset: -3
126120
int(8)
127121
> Offset: -6
128122
int(8)
129123
> Offset: -20
130-
131-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
132-
bool(false)
124+
Offset not contained in string
133125

134126
------- strrpos -----------
135127

ext/mbstring/tests/mb_stripos.phpt

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -41,30 +41,6 @@ print mb_stripos($euc_jp, 0, -15, 'EUC-JP') . "\n";
4141
print mb_stripos($euc_jp, 0, -43, 'EUC-JP') . "\n";
4242

4343

44-
// Invalid offset - should return false with warning
45-
print ("== INVALID OFFSET ==\n");
46-
47-
$r = mb_stripos($euc_jp, '日本語', 44, 'EUC-JP');
48-
($r === FALSE) ? print "OK_INVALID_OFFSET\n" : print "NG_INVALID_OFFSET\n";
49-
$r = mb_stripos($euc_jp, '日本語', 50, 'EUC-JP');
50-
($r === FALSE) ? print "OK_INVALID_OFFSET\n" : print "NG_INVALID_OFFSET\n";
51-
$r = mb_stripos($euc_jp, '0', 50, 'EUC-JP');
52-
($r === FALSE) ? print "OK_INVALID_OFFSET\n" : print "NG_INVALID_OFFSET\n";
53-
$r = mb_stripos($euc_jp, 3, 50, 'EUC-JP');
54-
($r === FALSE) ? print "OK_INVALID_OFFSET\n" : print "NG_INVALID_OFFSET\n";
55-
$r = mb_stripos($euc_jp, 0, 50, 'EUC-JP');
56-
($r === FALSE) ? print "OK_INVALID_OFFSET\n" : print "NG_INVALID_OFFSET\n";
57-
$r = mb_stripos($euc_jp, '日本語', -50, 'EUC-JP');
58-
($r === FALSE) ? print "OK_INVALID_OFFSET\n" : print "NG_INVALID_OFFSET\n";
59-
$r = mb_stripos($euc_jp, '0', -50, 'EUC-JP');
60-
($r === FALSE) ? print "OK_INVALID_OFFSET\n" : print "NG_INVALID_OFFSET\n";
61-
$r = mb_stripos($euc_jp, 3, -50, 'EUC-JP');
62-
($r === FALSE) ? print "OK_INVALID_OFFSET\n" : print "NG_INVALID_OFFSET\n";
63-
$r = mb_stripos($euc_jp, 0, -50, 'EUC-JP');
64-
($r === FALSE) ? print "OK_INVALID_OFFSET\n" : print "NG_INVALID_OFFSET\n";
65-
$r = mb_stripos($euc_jp, 0, -44, 'EUC-JP');
66-
($r === FALSE) ? print "OK_INVALID_OFFSET\n" : print "NG_INVALID_OFFSET\n";
67-
6844
// Out of range - should return false
6945
print ("== OUT OF RANGE ==\n");
7046

@@ -143,37 +119,6 @@ String len: 43
143119
33
144120
30
145121
0
146-
== INVALID OFFSET ==
147-
148-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
149-
OK_INVALID_OFFSET
150-
151-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
152-
OK_INVALID_OFFSET
153-
154-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
155-
OK_INVALID_OFFSET
156-
157-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
158-
OK_INVALID_OFFSET
159-
160-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
161-
OK_INVALID_OFFSET
162-
163-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
164-
OK_INVALID_OFFSET
165-
166-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
167-
OK_INVALID_OFFSET
168-
169-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
170-
OK_INVALID_OFFSET
171-
172-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
173-
OK_INVALID_OFFSET
174-
175-
Warning: mb_stripos(): Offset not contained in string in %s on line %d
176-
OK_INVALID_OFFSET
177122
== OUT OF RANGE ==
178123
OK_OUT_RANGE
179124
OK_OUT_RANGE

0 commit comments

Comments
 (0)