バグ: マルチサイト環境wp_site_cacheテーブル名生成誤り

TOP Forums バグ報告と提案(Requests and Feedback) バグ: マルチサイト環境wp_site_cacheテーブル名生成誤り

バグ: マルチサイト環境wp_site_cacheテーブル名生成誤り

Viewing 0 reply threads
  • Author
    Posts
    • #1642
      saltyorange
      Participant

        最新の kusanagi でドロップイン生成される SiteManagerAdvancedCache.php に、条件節に比較における型の不一致バグを発見しました。
        バグが顕在化するのはマルチサイト環境で、ほぼ間違いなく実装者が意図しない動作と認識しています。

        バグによる動作不具合は、メインサイトの常時Internal Server Errorです。

        【環境】

        - さくらインターネット VPS: KUSANAGI 9 for さくらのVPS
        - Kusanagi バージョン
        $ sudo dnf list | grep kusanagi.noarch
        kusanagi.noarch 9.8.9-1.el9 @kusanagi

        【問題個所】

        $add_prefix を生成する処理で、条件比較に型の不一致バグがあり、メインサイトにおいては本来 $add_prefix = '' となるべきところ、'1_' が生成されています。

        
        $add_prefix = isset( $this->sites[ $_SERVER['SERVER_NAME'] ] )
                && 1 !== $this->sites[ $_SERVER['SERVER_NAME'] ]
                ? $this->sites[ $_SERVER['SERVER_NAME'] ] . '_'
                : '';
        
        

        【希望する修正】
        生成元側で $sites の値を数値として出力するか、比較側を (int) キャストしてください。

        【発生している事象】
        $this->sites[ $_SERVER['SERVER_NAME']
        の値は、冒頭の $sites の定義により常に文字列です。
        PHP では、 1 !== '1' が true であり、結果としてメインサイトでも $add_prefix = '1_' になり、
        サイトキャッシュ参照先テーブル名称が本来の
        wp_site_cache
        ではなく、
        wp_1_site_cache
        として生成されています。

        現在、Wordpress kusanagi プラグインの 「advanced-cache.php を再生成する」ボタンをUIから押下するたびに

        PHP message: PHP Fatal error: Uncaught mysqli_sql_exception: Table 'wp_database.wp_1_site_cache' doesn't exist

        がメインサイトに対して発生する状態になっているので、運用でボタンに触らない手順としていますが非常にリスキーです。

        ----

        以下、実際のコードの関連個所をもう少し長く抜粋してインラインでコメント追加しています。

        <?php
        if ( ! defined( 'ABSPATH' ) ) {
                exit;
        }
        if ( is_admin() ) {
                return;
        }
        
        // phpcs:disable WordPress.DB.RestrictedFunctions
        class SiteManagerAdvancedCache {
                private $device_regexes = array(
        
                );
                private $sites = array(
                        'subdomain1.example.com' => '1', // 文字列型で site_id が定義されている
                        'subdomain1.example.com' => '2',
        
                );
                private $allowed_query_keys;
                private $site_mode               = 'domain';
                private $theme_switcher_disabled = true;
                private $replace_class_file;
        
                public function __construct() {
        // (中略)
                        switch ( $this->site_mode ) {
                                case 'domain':
                                        $add_prefix               = isset( $this->sites[ $_SERVER['SERVER_NAME'] ] ) && 1 !== $this->sites[ $_SERVER['SERVER_NAME'] ] ? $this->sites[ $_SERVER['SERVER_NAME'] ] . '_' : ''; // $this->sites[ $_SERVER['SERVER_NAME'] ] は文字列 '1' または '2' だが、数値の 1 と比較しているので $add_prefix は '1_' または '2_' となる
                                        $site_id                  = isset( $this->sites[ $_SERVER['SERVER_NAME'] ] ) ? $this->sites[ $_SERVER['SERVER_NAME'] ] : '';
                                        $table                    = $table_prefix . $add_prefix;
                                        $this->replace_class_file = WP_CONTENT_DIR . '/replace-class-' . $site_id . '.php';
                                        break;
                                case 'directory':
                                        $key = '/';
                                        if ( trim( $_SERVER['REQUEST_URI'], '/' ) ) {
                                                $dirs = explode( '/', trim( $_SERVER['REQUEST_URI'], '/' ), 2 );
                                                $key .= array_shift( $dirs ) . '/';
                                                unset( $dirs );
                                        }
                                        $add_prefix               = isset( $this->sites[ $key ] ) && 1 !== $this->sites[ $key ] ? $this->sites[ $key ] . '_' : ''; // 私の環境では利用していないが、同じ不具合がある
                                        $site_id                  = isset( $this->sites[ $key ] ) ? $this->sites[ $key ] : BLOG_ID_CURRENT_SITE;
                                        $table                    = $table_prefix . $add_prefix;
                                        $this->replace_class_file = WP_CONTENT_DIR . '/replace-class-' . $site_id . '.php';
                                        break;
                                default:
                                        $table   = $table_prefix;
                                        $site_id = '';
                        }
        
        // 以下略
        

        連休中の報告、恐縮ですが、早期に修正されることを希望します。

    Viewing 0 reply threads
    • You must be logged in to reply to this topic.

    Next article

    フォーラムについて