Skip to content

Commit 0c22692

Browse files
committed
Consistent return and notices for substr type of functions
1 parent 6d538e8 commit 0c22692

26 files changed

+1077
-11955
lines changed

ext/iconv/iconv.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -639,23 +639,38 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval,
639639
}
640640

641641
if (len < 0) {
642-
if ((len += (total_len - offset)) < 0) {
643-
return PHP_ICONV_ERR_SUCCESS;
642+
len += (total_len - offset);
643+
if (len < 0) {
644+
/* Argument 2 is offsetn and argument 1 is source string */
645+
php_error_docref(NULL, E_NOTICE, "Argument #2 ($%s) is not contained in argument #1 ($%s)",
646+
get_active_function_arg_name(2), get_active_function_arg_name(1));
647+
len = 0;
644648
}
645649
}
646650

647651
if (offset < 0) {
648-
if ((offset += total_len) < 0) {
649-
return PHP_ICONV_ERR_SUCCESS;
652+
offset += total_len;
653+
if (offset < 0) {
654+
/* Argument 2 is offsetn and argument 1 is source string */
655+
php_error_docref(NULL, E_NOTICE, "Argument #2 ($%s) is not contained in argument #1 ($%s)",
656+
get_active_function_arg_name(2), get_active_function_arg_name(1));
657+
offset = 0;
650658
}
651659
}
652660

653661
if((size_t)len > total_len) {
662+
// TODO Emit notice/ValueError
654663
len = total_len;
655664
}
656665

657666

658667
if ((size_t)offset > total_len) {
668+
/* Argument 2 is offsetn and argument 1 is source string */
669+
php_error_docref(NULL, E_NOTICE, "Argument #2 ($%s) is not contained in argument #1 ($%s)",
670+
get_active_function_arg_name(2), get_active_function_arg_name(1));
671+
/* Return an empty string */
672+
smart_str_appendl(pretval, "", 0);
673+
smart_str_0(pretval);
659674
return PHP_ICONV_ERR_SUCCESS;
660675
}
661676

ext/iconv/tests/iconv_substr.phpt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,17 @@ bar("This is a test", 0, -100000);
4040
bar("This is a test", -9, -100000);
4141
var_dump(iconv("ISO-2022-JP", "EUC-JP", iconv_substr(iconv("EUC-JP", "ISO-2022-JP", "こんにちは ISO-2022-JP"), 3, 8, "ISO-2022-JP")));
4242
?>
43-
--EXPECT--
43+
--EXPECTF--
4444
666768696a6b6c
4545
666768696a6b6c
4646
a6a4a8a4aaa4ab
4747
a4aba4ada4afa4b1a4b3a4b5a4b7
48-
bool(false)
49-
bool(false)
48+
49+
Notice: substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
50+
string(0) ""
51+
52+
Notice: iconv_substr(): Argument #2 ($offset) is not contained in argument #1 ($str) in %s on line %d
53+
string(0) ""
5054
string(14) "This is a test"
5155
string(14) "This is a test"
5256
string(3) "est"
@@ -56,7 +60,11 @@ string(3) "est"
5660
string(5) "This "
5761
string(5) "This "
5862
bool(false)
63+
64+
Notice: iconv_substr(): Argument #2 ($offset) is not contained in argument #1 ($str) in %s on line %d
65+
string(0) ""
5966
bool(false)
60-
bool(false)
61-
bool(false)
67+
68+
Notice: iconv_substr(): Argument #2 ($offset) is not contained in argument #1 ($str) in %s on line %d
69+
string(0) ""
6270
string(10) "ちは ISO-2"

ext/mbstring/mbstring.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,6 +2160,8 @@ PHP_FUNCTION(mb_substr)
21602160
} else if (-from < mblen) {
21612161
real_from = mblen + from;
21622162
} else {
2163+
php_error_docref(NULL, E_NOTICE, "Argument #2 ($%s) is not contained in argument #1 ($%s)",
2164+
get_active_function_arg_name(2), get_active_function_arg_name(1));
21632165
real_from = 0;
21642166
}
21652167

@@ -2173,6 +2175,7 @@ PHP_FUNCTION(mb_substr)
21732175
} else if (real_from < mblen && -len < mblen - real_from) {
21742176
real_len = (mblen - real_from) + len;
21752177
} else {
2178+
// TODO Emit notice?
21762179
real_len = 0;
21772180
}
21782181

@@ -2218,6 +2221,8 @@ PHP_FUNCTION(mb_strcut)
22182221
if (from < 0) {
22192222
from = string.len + from;
22202223
if (from < 0) {
2224+
php_error_docref(NULL, E_NOTICE, "Argument #2 ($%s) is not contained in argument #1 ($%s)",
2225+
get_active_function_arg_name(2), get_active_function_arg_name(1));
22212226
from = 0;
22222227
}
22232228
}
@@ -2233,6 +2238,8 @@ PHP_FUNCTION(mb_strcut)
22332238
}
22342239

22352240
if (from > string.len) {
2241+
php_error_docref(NULL, E_NOTICE, "Argument #2 ($%s) is not contained in argument #1 ($%s)",
2242+
get_active_function_arg_name(2), get_active_function_arg_name(1));
22362243
RETURN_EMPTY_STRING();
22372244
}
22382245

ext/mbstring/tests/bug49354.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ var_dump(mb_strcut($crap, 12, 100, 'UTF-8'));
1313
var_dump(mb_strcut($crap, 13, 100, 'UTF-8'));
1414

1515
?>
16-
--EXPECT--
16+
--EXPECTF--
1717
string(12) "AåBäCöDü"
1818
string(11) "åBäCöDü"
1919
string(11) "åBäCöDü"
2020
string(9) "BäCöDü"
2121
string(0) ""
22+
23+
Notice: mb_strcut(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
2224
string(0) ""

ext/mbstring/tests/mb_strcut.phpt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,16 @@ print MBStringChars(mb_strcut($utf16le, 1, 3, 'UTF-16LE'), 'UTF-16LE') . "\n";
5555
print MBStringChars(mb_strcut($utf16le, 1, 4, 'UTF-16LE'), 'UTF-16LE') . "\n";
5656

5757
?>
58-
--EXPECT--
58+
--EXPECTF--
5959
== EUC-JP ==
6060
[a4ce cab8]
6161
[a4b3 a4ce]
6262
[30 31 32 33 a4b3 a4ce cab8 bbfa cef3 a4cf c6fc cbdc b8ec a4c7 a4b9 a1a3 45 55 43 2d 4a 50 a4f2 bbc8 a4c3 a4c6 a4a4 a4de a4b9 a1a3 c6fc cbdc b8ec a4cf cccc c5dd bdad a4a4 a1a3]
63+
64+
Notice: mb_strcut(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
6365
OK
66+
67+
Notice: mb_strcut(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
6468
OK
6569
== UTF-8 ==
6670
[]

ext/mbstring/tests/mb_substr.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ $str = mb_substr($euc_jp, -100, 10,'EUC-JP');
2424
($str !== "") ? print "4 OK: ".bin2hex($str)."\n" : print "NG: ".bin2hex($str)."\n";
2525

2626
?>
27-
--EXPECT--
27+
--EXPECTF--
2828
1: c6fccbdcb8eca4c7a4b9a1a34555432d
2929
2: 30313233a4b3a4cecab8bbfacef3a4cfc6fccbdcb8eca4c7a4b9a1a34555432d4a50a4f2bbc8a4c3a4c6a4a4a4dea4b9a1a3c6fccbdcb8eca4cfccccc5ddbdada4a4a1a3
3030
3 OK
31+
32+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
3133
4 OK: 30313233a4b3a4cecab8bbfacef3a4cf

ext/mbstring/tests/mb_substr_variation4.phpt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,47 @@ for ($i = -60; $i <= 60; $i += 10) {
4444

4545
echo "Done";
4646
?>
47-
--EXPECT--
47+
--EXPECTF--
4848
*** Testing mb_substr() : usage variations ***
4949

5050
**-- Offset is: -60 --**
5151
-- ASCII String --
52+
53+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
5254
string(8) "K0lzIA=="
5355
--Multibyte String --
56+
57+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
5458
string(16) "5pel5pys6Kqe44OG"
5559

5660
**-- Offset is: -50 --**
5761
-- ASCII String --
62+
63+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
5864
string(8) "K0lzIA=="
5965
--Multibyte String --
66+
67+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
6068
string(16) "5pel5pys6Kqe44OG"
6169

6270
**-- Offset is: -40 --**
6371
-- ASCII String --
72+
73+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
6474
string(8) "K0lzIA=="
6575
--Multibyte String --
76+
77+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
6678
string(16) "5pel5pys6Kqe44OG"
6779

6880
**-- Offset is: -30 --**
6981
-- ASCII String --
82+
83+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
7084
string(8) "K0lzIA=="
7185
--Multibyte String --
86+
87+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
7288
string(16) "5pel5pys6Kqe44OG"
7389

7490
**-- Offset is: -20 --**

ext/mbstring/tests/mb_substr_variation6.phpt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,31 +49,47 @@ for ($i = -60; $i <= 60; $i += 10) {
4949

5050
echo "Done";
5151
?>
52-
--EXPECT--
52+
--EXPECTF--
5353
*** Testing mb_substr() : usage variations ***
5454

5555
**-- Offset is: -60 --**
5656
-- ASCII String --
57+
58+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
5759
string(8) "2b497320"
5860
--Multibyte String --
61+
62+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
5963
string(24) "e697a5e69cace8aa9ee38386"
6064

6165
**-- Offset is: -50 --**
6266
-- ASCII String --
67+
68+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
6369
string(8) "2b497320"
6470
--Multibyte String --
71+
72+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
6573
string(24) "e697a5e69cace8aa9ee38386"
6674

6775
**-- Offset is: -40 --**
6876
-- ASCII String --
77+
78+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
6979
string(8) "2b497320"
7080
--Multibyte String --
81+
82+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
7183
string(24) "e697a5e69cace8aa9ee38386"
7284

7385
**-- Offset is: -30 --**
7486
-- ASCII String --
87+
88+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
7589
string(8) "2b497320"
7690
--Multibyte String --
91+
92+
Notice: mb_substr(): Argument #2 ($start) is not contained in argument #1 ($str) in %s on line %d
7793
string(24) "e697a5e69cace8aa9ee38386"
7894

7995
**-- Offset is: -20 --**

ext/opcache/Optimizer/sccp.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -968,12 +968,6 @@ static inline int ct_eval_func_call(
968968
return FAILURE;
969969
}
970970
/* pass */
971-
} else if (zend_string_equals_literal(name, "substr")) {
972-
if (Z_TYPE_P(args[0]) != IS_STRING
973-
|| Z_TYPE_P(args[1]) != IS_LONG) {
974-
return FAILURE;
975-
}
976-
/* pass */
977971
} else if (zend_string_equals_literal(name, "pow")) {
978972
if ((Z_TYPE_P(args[0]) != IS_LONG && Z_TYPE_P(args[0]) != IS_DOUBLE)
979973
|| (Z_TYPE_P(args[1]) != IS_LONG && Z_TYPE_P(args[1]) != IS_DOUBLE)) {

ext/standard/basic_functions.stub.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,9 +543,9 @@ function bin2hex(string $data): string {}
543543

544544
function hex2bin(string $data): string|false {}
545545

546-
function strspn(string $str, string $mask, int $start = 0, ?int $len = null): int|false {}
546+
function strspn(string $str, string $mask, int $start = 0, ?int $len = null): int {}
547547

548-
function strcspn(string $str, string $mask, int $start = 0, ?int $len = null): int|false {}
548+
function strcspn(string $str, string $mask, int $start = 0, ?int $len = null): int {}
549549

550550
#if HAVE_NL_LANGINFO
551551
function nl_langinfo(int $item): string|false {}
@@ -610,7 +610,7 @@ function chunk_split(string $str, int $chunklen = 76, string $ending = "\r\n"):
610610

611611
function substr(string $str, int $start, ?int $length = null): string|false {}
612612

613-
function substr_replace(array|string $str, array|string $replace, array|int $start, array|int|null $length = null): string|array|false {}
613+
function substr_replace(array|string $str, array|string $replace, array|int $start, array|int|null $length = null): string|array {}
614614

615615
function quotemeta(string $str): string {}
616616

@@ -688,7 +688,7 @@ function str_split(string $str, int $split_length = 1): array {}
688688

689689
function strpbrk(string $haystack, string $char_list): string|false {}
690690

691-
function substr_compare(string $main_str, string $str, int $offset, ?int $length = null, bool $case_insensitivity = false): int|false {}
691+
function substr_compare(string $main_str, string $str, int $offset, ?int $length = null, bool $case_insensitivity = false): int {}
692692

693693
function utf8_encode(string $data): string {}
694694

ext/standard/basic_functions_arginfo.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 0224dc521c4a8bd49fbcfd26cddb01a2e571cf74 */
2+
* Stub hash: 3937e2a532217fd78bc2ec94014a86a3e570d001 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0)
55
ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
@@ -807,7 +807,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hex2bin, 0, 1, MAY_BE_STRING|MAY
807807
ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
808808
ZEND_END_ARG_INFO()
809809

810-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strspn, 0, 2, MAY_BE_LONG|MAY_BE_FALSE)
810+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_strspn, 0, 2, IS_LONG, 0)
811811
ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0)
812812
ZEND_ARG_TYPE_INFO(0, mask, IS_STRING, 0)
813813
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, start, IS_LONG, 0, "0")
@@ -930,7 +930,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr, 0, 2, MAY_BE_STRING|MAY_
930930
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null")
931931
ZEND_END_ARG_INFO()
932932

933-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr_replace, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_FALSE)
933+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr_replace, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY)
934934
ZEND_ARG_TYPE_MASK(0, str, MAY_BE_ARRAY|MAY_BE_STRING, NULL)
935935
ZEND_ARG_TYPE_MASK(0, replace, MAY_BE_ARRAY|MAY_BE_STRING, NULL)
936936
ZEND_ARG_TYPE_MASK(0, start, MAY_BE_ARRAY|MAY_BE_LONG, NULL)
@@ -1082,7 +1082,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strpbrk, 0, 2, MAY_BE_STRING|MAY
10821082
ZEND_ARG_TYPE_INFO(0, char_list, IS_STRING, 0)
10831083
ZEND_END_ARG_INFO()
10841084

1085-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr_compare, 0, 3, MAY_BE_LONG|MAY_BE_FALSE)
1085+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_substr_compare, 0, 3, IS_LONG, 0)
10861086
ZEND_ARG_TYPE_INFO(0, main_str, IS_STRING, 0)
10871087
ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0)
10881088
ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0)

0 commit comments

Comments
 (0)