[php-src] master: SCCP: Evaluate negative string offset (#24095)
| From: | Nora Dossche via GitHub | Date: | Sun, 04 Oct 2026 08:01:30 +0000 |
| Subject: | [php-src] master: SCCP: Evaluate negative string offset (#24095) | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-141910@lists.php.net to get a copy of this message | ||
Author: Nora Dossche (ndossche)
Committer: GitHub (web-flow)
Pusher: ndossche
Date: 2026-10-04T10:01:27+02:00
Commit: https://github.com/php/php-src/commit/caffec98939e8281e17461af9cb3a9661ef75c39
Raw diff: https://github.com/php/php-src/commit/caffec98939e8281e17461af9cb3a9661ef75c39.diff
SCCP: Evaluate negative string offset (#24095)
Changed paths:
A ext/opcache/tests/opt/sccp_043.phpt
M Zend/Optimizer/sccp.c
Diff:
diff --git a/Zend/Optimizer/sccp.c b/Zend/Optimizer/sccp.c
index 01ba8e6ba676..e2e01251edb4 100644
--- a/Zend/Optimizer/sccp.c
+++ b/Zend/Optimizer/sccp.c
@@ -399,6 +399,11 @@ static inline zend_result ct_eval_fetch_dim(zval *result, const zval *op1,
const
if (zval_to_string_offset(&index, op2) == FAILURE) {
return FAILURE;
}
+
+ if (index < 0) {
+ index += (zend_long) Z_STRLEN_P(op1);
+ }
+
if (index >= 0 && index < Z_STRLEN_P(op1)) {
ZVAL_CHAR(result, Z_STRVAL_P(op1)[index]);
return SUCCESS;
diff --git a/ext/opcache/tests/opt/sccp_043.phpt b/ext/opcache/tests/opt/sccp_043.phpt
new file mode 100644
index 000000000000..5c6ce526714a
--- /dev/null
+++ b/ext/opcache/tests/opt/sccp_043.phpt
@@ -0,0 +1,60 @@
+--TEST--
+SCCP 043: Negative string offsets are evaluated
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.opt_debug_level=0x20000
+--EXTENSIONS--
+opcache
+--FILE--
+<?php
+
+function foo1() {
+ return "abc"[-1];
+}
+
+function foo2() {
+ return "abc"[-2];
+}
+
+function foo3() {
+ return "abc"[-3];
+}
+
+function foo4() {
+ return "abc"[-4];
+}
+
+?>
+--EXPECTF--
+$_main:
+ ; (lines=1, args=0, vars=0, tmps=%d)
+ ; (after optimizer)
+ ; %s.php:%s
+0000 RETURN int(1)
+
+foo1:
+ ; (lines=1, args=0, vars=0, tmps=%d)
+ ; (after optimizer)
+ ; %s.php:%s
+0000 RETURN string("c")
+
+foo2:
+ ; (lines=1, args=0, vars=0, tmps=%d)
+ ; (after optimizer)
+ ; %s.php:%s
+0000 RETURN string("b")
+
+foo3:
+ ; (lines=1, args=0, vars=0, tmps=%d)
+ ; (after optimizer)
+ ; %s.php:%s
+0000 RETURN string("a")
+
+foo4:
+ ; (lines=2, args=0, vars=0, tmps=%d)
+ ; (after optimizer)
+ ; %s.php:%s
+0000 T0 = FETCH_DIM_R string("abc") int(-4)
+0001 RETURN T0