Incorrect base64 encoding in PHP-FPM with opcache.file_cache_only=1 and sodium
オープン
まだ誰も着手していません。
Bug
Category: Engine
Status: Verified
- 主要言語
- C
- スター
- 40.4k
- フォーク
- 8.2k
- 平均マージ
- 2日 13時間
- マージ済み PR(30日)
- 96
説明
Description
The following code:
<?php
final class SodiumBase64Polyfill
{
public const SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING = 3;
public const SODIUM_BASE64_VARIANT_URLSAFE = 5;
public const SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING = 7;
public static function bin2base64(string $decoded, int $variant): string
{
if (! function_exists('sodium_bin2base64')) {
return self::bin2base64Fallback($decoded, $variant);
}
return sodium_bin2base64($decoded, $variant);
}
public static function bin2base64Fallback(string $decoded, int $variant): string
{
$encoded = base64_encode($decoded);
if (
$variant === self::SODIUM_BASE64_VARIANT_URLSAFE
|| $variant === self::SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING
) {
$encoded = strtr($encoded, '+/', '-_');
}
if (
$variant === self::SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING
|| $variant === self::SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING
) {
$encoded = rtrim($encoded, '=');
}
return $encoded;
}
}
var_dump(SodiumBase64Polyfill::bin2base64("Hello world!", SodiumBase64Polyfill::SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING));
Resulted in this output:
"Hello world!�"
But I expected this output instead:
"SGVsbG8gd29ybGQh"
Steps to reproduce
- Run PHP-FPM with the following php.ini settings:
zend_extension=opcache.so
extension=sodium.so
opcache.enable = 1
opcache.enable_cli = 1
; Tune opcache for read-only application files
opcache.revalidate_freq=0
opcache.validate_timestamps=false
opcache.enable_file_override=1
; Enable pre-warmed opcache
opcache.file_cache = "/var/cache/opcache"
opcache.file_cache_read_only=1
opcache.file_cache_consistency_checks=0
; Enable log
opcache.error_log=/dev/stderr
opcache.log_verbosity_level = 4
- Compile and run the script using:
php -d zend_extension=opcache.so \
-d extension=sodium.so \
-d opcache.enable=1 \
-d opcache.enable_cli=1 \
-d opcache.jit=disable \
-d opcache.file_cache=/var/cache/opcache \
-d opcache.file_cache_only=1 \
-d opcache.file_cache_read_only=0 ./public/index.php
- Send request php-fpm
Additional information
- The issue disappears when opcache.optimization_level=0 is set.
- The bug is tested with the file_cache_only feature introduced in PR #16551, but the issue also reproduces in PHP 8.4.
PHP Version
master, 8.4
Operating System
linux x86 or aarch64
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
提供された PHP-FPM および CLI コマンドを使い、public/index.php に対して opcache.file_cache_only=1 と optimization_level=0 の有無それぞれで障害を再現します。PR #16551 で導入された file_cache_only の動作を読み、コンパイル中の sodium との相互作用を追跡します。完了条件は、報告された構成でスクリプトが一貫して "SGVsbG8gd29ybGQh" を返し、通常の opcache の動作を後退させないことです。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- linux, php
- 領域
- backend, performance
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 32/100