php / php/php-src

Incorrect base64 encoding in PHP-FPM with opcache.file_cache_only=1 and sodium

Offen
#17,733 25 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bug Category: Engine Status: Verified
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.1k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

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

  1. 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
  1. 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
  1. 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

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Reproduziere den Fehler mit den bereitgestellten PHP-FPM- und CLI-Befehlen gegen public/index.php, mit und ohne opcache.file_cache_only=1 und optimization_level=0. Lies das mit PR #16551 eingeführte file_cache_only-Verhalten und verfolge die Interaktion mit sodium während der Kompilierung. Als erledigt gilt die Aufgabe, wenn das Skript unter den gemeldeten Konfigurationen konsistent "SGVsbG8gd29ybGQh" zurückgibt, ohne das normale opcache-Verhalten zu beeinträchtigen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
linux, php
Bereich
backend, performance
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
32/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.