summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--ext/standard/string.c4
-rw-r--r--ext/standard/tests/strings/strripos_offset.phpt45
3 files changed, 48 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 8489254b45..ff89ee8169 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ PHP NEWS
(Ilia)
- Fixed altering $this via argument named "this". (Dmitry)
- Fixed PHP CLI to use the php.ini from the binary location. (Hannes)
+- Fixed segfault in strripos(). (Tony, Joxean Koret)
- Fixed bug #41347 (checkdnsrr() segfaults on empty hostname). (Scott)
- Fixed bug #41337 (WSDL parsing doesn't ignore non soap bindings). (Dmitry)
- Fixed bug #41326 (Writing empty tags with Xmlwriter::WriteElement[ns])
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 98daf7ae9c..56981b0778 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -1856,7 +1856,7 @@ PHP_FUNCTION(strripos)
e = haystack + haystack_len - 1;
} else {
p = haystack;
- if (-offset > haystack_len) {
+ if (-offset > haystack_len || -offset < 0) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Offset is greater than the length of haystack string");
RETURN_FALSE;
} else {
@@ -1889,7 +1889,7 @@ PHP_FUNCTION(strripos)
p = haystack_dup + offset;
e = haystack_dup + haystack_len - needle_len;
} else {
- if (-offset > haystack_len) {
+ if (-offset > haystack_len || -offset < 0) {
efree(needle_dup);
efree(haystack_dup);
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Offset is greater than the length of haystack string");
diff --git a/ext/standard/tests/strings/strripos_offset.phpt b/ext/standard/tests/strings/strripos_offset.phpt
new file mode 100644
index 0000000000..daa917e79f
--- /dev/null
+++ b/ext/standard/tests/strings/strripos_offset.phpt
@@ -0,0 +1,45 @@
+--TEST--
+strripos() offset integer overflow
+--FILE--
+<?php
+
+var_dump(strripos("t", "t", PHP_INT_MAX+1));
+var_dump(strripos("tttt", "tt", PHP_INT_MAX+1));
+var_dump(strripos(100, 101, PHP_INT_MAX+1));
+var_dump(strripos(1024, 1024, PHP_INT_MAX+1));
+var_dump(strripos(array(), array(), PHP_INT_MAX+1));
+var_dump(strripos(1024, 1024, -PHP_INT_MAX));
+var_dump(strripos(1024, "te", -PHP_INT_MAX));
+var_dump(strripos(1024, 1024, -PHP_INT_MAX-1));
+var_dump(strripos(1024, "te", -PHP_INT_MAX-1));
+
+echo "Done\n";
+?>
+--EXPECTF--
+Notice: strripos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+
+Notice: strripos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+
+Notice: strripos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+
+Notice: strripos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+
+Warning: strripos() expects parameter 1 to be string, array given in %s on line %d
+bool(false)
+
+Notice: strripos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+
+Notice: strripos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+
+Notice: strripos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+
+Notice: strripos(): Offset is greater than the length of haystack string in %s on line %d
+bool(false)
+Done