Function JIT: wrong result (null) from a string-scanning loop with strcspn() after a comment-start byte
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 54/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- php
- Lĩnh vực
- performance
Hướng nghiên cứu
Start by reducing the provided reproducer to isolate the strcspn() scanning loop under opcache.jit=function, then compare its result with tracing and disabled JIT modes. The issue names no PHP source files or tests, so first locate the function JIT implementation and its tests for string scanning. Done means both inputs return their full expected strings in function JIT mode, with the other modes still behaving correctly.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Description
With opcache.jit=function, the static method Repro::interpolate() below returns null for two inputs that it handles correctly with opcache.jit=tracing and opcache.jit=disable. The two inputs contain a byte that may start a comment (- or /) but no placeholder, so the scanner should copy the whole string.
The following code:
<?php
declare(strict_types=1);
final class Repro {
public static function skipComment(string $sql, int $position): int {
$byte = $sql[$position]; $next = $sql[$position + 1] ?? '';
if ($byte === '/' && $next === '*') { $end = strpos($sql, '*/', $position + 2); return $end === false ? strlen($sql) : $end + 2; }
$dashes = $byte === '-' && $next === '-' && strspn($sql[$position + 2] ?? "\n", " \t\r\n") === 1;
if ($byte !== '#' && !$dashes) return $position; $end = strpos($sql, "\n", $position);
return $end === false ? strlen($sql) : $end + 1; }
public static function skipQuoted(string $sql, int $position): int {
$quote = $sql[$position]; $length = strlen($sql); $stops = $quote === '`' ? '`' : $quote . '\\'; $position++;
while ($position < $length) { $position += strcspn($sql, $stops, $position); if ($position >= $length) break;
if ($sql[$position] === '\\') $position += 2; elseif (($sql[$position + 1] ?? '') === $quote) $position += 2; else return $position + 1; }
return $length; }
public static function literal(mixed $value): ?string {
if ($value === null) return 'NULL'; if (is_bool($value)) return $value ? '1' : '0'; if (is_int($value)) return (string) $value;
if (is_float($value)) return is_finite($value) ? var_export($value, true) : null; if (!is_string($value)) return null;
return $value === '' ? "''" : "'" . addslashes($value) . "'"; }
public static function interpolate(string $sql, array $params): ?string {
if (count($params) > 65535 || !array_is_list($params)) return null;
$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 === '?') { $literal = $used < $count ? self::literal(value: $params[$used]) : null; if ($literal === null) return null;
$text .= substr($sql, $copied, $position - $copied) . $literal; $used++; $position++; $copied = $position;
} elseif ($byte === "'" || $byte === '"' || $byte === '`') $position = self::skipQuoted(sql: $sql, position: $position);
else { $after = self::skipComment(sql: $sql, position: $position); $position = $after === $position ? $position + 1 : $after; }
}
return $used === $count ? $text . substr($sql, $copied) : null;
}
}
echo json_encode([Repro::interpolate('SELECT ? AS v', [3]), Repro::interpolate('SELECT 5 -', []), Repro::interpolate('SELECT 5 / 2', [])]), "\n";
Run with:
php -d opcache.enable_cli=1 -d opcache.file_update_protection=0 -d opcache.jit=function repro.php
Resulted in this output:
["SELECT 3 AS v",null,null]
But I expected this output instead (what opcache.jit=tracing and opcache.jit=disable print):
["SELECT 3 AS v","SELECT 5 -","SELECT 5 \/ 2"]
Reproduces on PHP 8.5.12 and on master (8.7.0-dev, da7da45a44eb07ac999f5183b232a40d5f857131). The script is a reduced version of a SQL placeholder interpolator.
PHP Version
PHP 8.5.12 (cli) (NTS), built from source; also master 8.7.0-dev at da7da45a44eb07ac999f5183b232a40d5f857131
Operating System
Amazon Linux 2023, aarch64 (container)
- Ngôn ngữ chính
- C
- Star
- 40.7k
- Fork
- 8.3k
- Merge trung bình
- 2 ngày 20 giờ
- Pull request đã merge (30 ngày)
- 147
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của php/php-src
-
sapi/fpm/tests/tester.inc can send SIGUSR2 to pid 0, killing run-tests.phpCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởBug Status: Needs Triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
zend_set_local_var() overwrites existing compiled variable (CV) zval without calling zval_ptr_dtor()Có thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởBug Status: Needs Triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Case-insensitive substr_compare, ksort, krsort are still locale-dependentCó thể đã có người làm @lazerg đã nhận 4 ngày trước. Đang mởBug Extension: standard Status: Verified
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
php/php-src#24552 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
master: part of the mbstring bailout fix got lost in a mergeCó thể đã có người làm @lazerg đã nhận 4 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
HexaCluster/credcheck#86 ·
-
Wheels for Python 3.15Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
mongodb/winkerberos#175 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 63/100
raspberrypi/linux#7718 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
AOMediaCodec/SVT-AV1#3320 ·