From dc4533260317b1cd07439d927ece46d310de8bc1 Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Wed, 11 Nov 2026 17:32:15 +0100 Subject: [PATCH 1/3] Add regression test for GH-24578 --- ext/opcache/tests/jit/gh24578.phpt | 86 ++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 ext/opcache/tests/jit/gh24578.phpt diff --git a/ext/opcache/tests/jit/gh24578.phpt b/ext/opcache/tests/jit/gh24578.phpt new file mode 100644 index 000000000000..8be89bdb46be --- /dev/null +++ b/ext/opcache/tests/jit/gh24578.phpt @@ -0,0 +1,86 @@ +--TEST-- +GH-24578 (Function JIT produces an incorrect result in a string-scanning loop) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=64M +opcache.jit=function +--EXTENSIONS-- +opcache +--FILE-- += $length) { + break; + } + if ($sql[$position] === '\\') { + $position += 2; + } elseif (($sql[$position + 1] ?? '') === $quote) { + $position += 2; + } else { + return $position + 1; + } + } + return $length; + } + + public static function interpolate(string $sql, array $params): ?string { + $length = strlen($sql); + $count = count($params); + $text = ''; + $used = 0; + $copied = 0; + $position = 0; + while ($position < $length) { + $position += strcspn($sql, "?'\"`#-/", $position); + if ($position >= $length) { + break; + } + $byte = $sql[$position]; + if ($byte === '?') { + $text .= substr($sql, $copied, $position - $copied) . (string) $params[$used]; + $used++; + $position++; + $copied = $position; + } elseif ($byte === "'" || $byte === '"' || $byte === '`') { + $position = self::skipQuoted($sql, $position); + } else { + $after = self::skipComment($sql, $position); + $position = $after === $position ? $position + 1 : $after; + } + } + return $used === $count ? $text . substr($sql, $copied) : null; + } +} + +var_dump(Repro::interpolate('SELECT ? AS v', [3])); +var_dump(Repro::interpolate('SELECT 5 -', [])); +var_dump(Repro::interpolate('SELECT 5 / 2', [])); +?> +--EXPECT-- +string(13) "SELECT 3 AS v" +string(10) "SELECT 5 -" +string(12) "SELECT 5 / 2" From 12d2551167a43b7d82ff61a4dfd19df0c0cb4607 Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Thu, 12 Nov 2026 00:26:39 +0100 Subject: [PATCH 2/3] Clarify JIT scanner regression case --- ext/opcache/tests/jit/gh24578.phpt | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/opcache/tests/jit/gh24578.phpt b/ext/opcache/tests/jit/gh24578.phpt index 8be89bdb46be..79a634736a34 100644 --- a/ext/opcache/tests/jit/gh24578.phpt +++ b/ext/opcache/tests/jit/gh24578.phpt @@ -76,6 +76,7 @@ final class Repro { } } +// A minus or slash without a following comment delimiter must not make the scanner stop. var_dump(Repro::interpolate('SELECT ? AS v', [3])); var_dump(Repro::interpolate('SELECT 5 -', [])); var_dump(Repro::interpolate('SELECT 5 / 2', [])); From 465c69b81bde17b2f5016ad8cd46ec4287b0e02a Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Wed, 11 Nov 2026 23:26:04 +0100 Subject: [PATCH 3/3] Run i386 test suite outside container seccomp --- .github/actions/apt-x32/action.yml | 6 +++--- .github/actions/install-linux-x32/action.yml | 16 ++++++++-------- .github/workflows/test-suite.yml | 13 ++++++------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.github/actions/apt-x32/action.yml b/.github/actions/apt-x32/action.yml index 14182e768795..0f27b88497ac 100644 --- a/.github/actions/apt-x32/action.yml +++ b/.github/actions/apt-x32/action.yml @@ -9,10 +9,10 @@ runs: OPCACHE_TLS_TESTS_DEPS="gcc clang lld" export DEBIAN_FRONTEND=noninteractive - dpkg --add-architecture i386 - apt-get update -y | true + sudo dpkg --add-architecture i386 + sudo env DEBIAN_FRONTEND=noninteractive apt-get update -y | true # TODO: Reenable postgresql + postgresql-contrib packages once they work again. - apt-get install -y \ + sudo env DEBIAN_FRONTEND=noninteractive apt-get install -y \ autoconf \ bison \ curl \ diff --git a/.github/actions/install-linux-x32/action.yml b/.github/actions/install-linux-x32/action.yml index 4ef87ee03fd3..95d7fc738b1c 100644 --- a/.github/actions/install-linux-x32/action.yml +++ b/.github/actions/install-linux-x32/action.yml @@ -5,11 +5,11 @@ runs: - shell: bash run: | set -x - make install - mkdir -p /etc/php.d - chmod 777 /etc/php.d - echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini - echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini - echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini - echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini - echo opcache.preload_user=root >> /etc/php.d/opcache.ini + sudo make install + sudo mkdir -p /etc/php.d + sudo chmod 777 /etc/php.d + echo mysqli.default_socket=/var/run/mysqld/mysqld.sock | sudo tee /etc/php.d/mysqli.ini > /dev/null + echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock | sudo tee /etc/php.d/pdo_mysql.ini > /dev/null + echo opcache.enable_cli=1 | sudo tee /etc/php.d/opcache.ini > /dev/null + echo opcache.protect_memory=1 | sudo tee -a /etc/php.d/opcache.ini > /dev/null + echo opcache.preload_user=root | sudo tee -a /etc/php.d/opcache.ini > /dev/null diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index a02097f03298..ccb847029588 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -230,15 +230,14 @@ jobs: fail-fast: false matrix: ${{ fromJson(inputs.branch).jobs.LINUX_X32.matrix }} name: "LINUX_X32_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" - runs-on: ubuntu-latest + # The container seccomp profile blocks i386 socket syscalls used by the test suite. + runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} timeout-minutes: 180 - container: - image: ubuntu:${{ fromJson(inputs.branch).config.ubuntu_version }} env: - MYSQL_TEST_HOST: mysql - PDO_MYSQL_TEST_DSN: mysql:host=mysql;dbname=test - PDO_MYSQL_TEST_HOST: mysql - PDO_FIREBIRD_TEST_DSN: firebird:dbname=firebird:test.fdb + MYSQL_TEST_HOST: 127.0.0.1 + PDO_MYSQL_TEST_DSN: mysql:host=127.0.0.1;dbname=test + PDO_MYSQL_TEST_HOST: 127.0.0.1 + PDO_FIREBIRD_TEST_DSN: firebird:dbname=localhost:test.fdb services: mysql: image: mysql:8.4