]> granicus.if.org Git - php/commitdiff
Avoid signed integer overflow in string offset check
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 19 Dec 2019 10:46:14 +0000 (11:46 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 19 Dec 2019 10:47:50 +0000 (11:47 +0100)
Cast to size_t before performing operations instead of afterwards.

Zend/tests/string_offset_int_min_max.phpt [new file with mode: 0644]
Zend/zend_execute.c

diff --git a/Zend/tests/string_offset_int_min_max.phpt b/Zend/tests/string_offset_int_min_max.phpt
new file mode 100644 (file)
index 0000000..b8bd4bc
--- /dev/null
@@ -0,0 +1,16 @@
+--TEST--
+Accessing PHP_INT_MAX and PHP_INT_MIN as string offsets
+--FILE--
+<?php
+
+$str = "";
+var_dump($str[PHP_INT_MAX]);
+var_dump($str[PHP_INT_MIN]);
+
+?>
+--EXPECTF--
+Notice: Uninitialized string offset: %d in %s on line %d
+string(0) ""
+
+Notice: Uninitialized string offset: -%d in %s on line %d
+string(0) ""
index 3b980e87763ad4fa3ca771ce269a520b2c35f2e3..9ae73caae1fd254964aec6388bb74a08129a79cf 100644 (file)
@@ -2369,7 +2369,7 @@ try_string_offset:
                        offset = Z_LVAL_P(dim);
                }
 
-               if (UNEXPECTED(Z_STRLEN_P(container) < (size_t)((offset < 0) ? -offset : (offset + 1)))) {
+               if (UNEXPECTED(Z_STRLEN_P(container) < ((offset < 0) ? -(size_t)offset : ((size_t)offset + 1)))) {
                        if (type != BP_VAR_IS) {
                                zend_error(E_NOTICE, "Uninitialized string offset: " ZEND_LONG_FMT, offset);
                                ZVAL_EMPTY_STRING(result);