<?php

declare(strict_types=1);

namespace Acms\Services\Template\Twig\Mail;

/**
 * メールフォーム本文 (運営者の管理画面入力) を Twig サンドボックスで評価するときの「基本許可リスト」。
 *
 * 文字列直接入力経路の Twig サービス (`template.mail.twig.sandboxed`) は信頼境界が
 * 「サイト運営者の管理画面入力」となるため、SSTI 防止に SandboxExtension を組み合わせる。
 * ここで定義した基本集合に、AcmsExtension 由来 / extendsTwig 由来のフィルタ・関数名を
 * {@see \Acms\Services\Template\Twig::buildSandboxPolicy()} が合成して最終的な許可リストを作る。
 *
 * メソッド呼び出しとプロパティアクセスは全面禁止 (Twig サービス側で空配列を渡す)。変数辞書は
 * フラット化した連想配列で渡す想定で、テンプレ側からはトップレベルのキーへのアクセスしか発生しない。
 *
 * `extends` (および `use`) は Twig\Sandbox\SecurityPolicy の後方互換仕様上、この配列に
 * 入れていなくても strict モード無効時は常に許可されてしまう (Twig 3.12 で非推奨化、4.0 で廃止予定)。
 * このリストから除外した意図を実効化するため、Twig サービス側で必ず SecurityPolicy::setStrict(true)
 * を呼ぶこと ({@see \Acms\Services\Template\Twig::buildSandboxPolicy()})。運営者入力に
 * `{% extends "自身の論理名" %}` のような自己参照を書かれると、strict 化していない場合
 * 無限再帰でメモリ枯渇 (Fatal Error) に至ることを実機検証済み。
 */
final class SecurityPolicy
{
    /** @var list<string> */
    public const ALLOWED_TAGS = [
        'if',
        'for',
        'set',
        'block',
    ];

    /** @var list<string> */
    public const ALLOWED_FILTERS = [
        'escape',
        'e',
        'raw',
        'nl2br',
        'default',
        'upper',
        'lower',
        'trim',
        'replace',
        'length',
        'format',
        'date',
        'striptags',
        'url_encode',
        'join',
        'split',
    ];

    /**
     * range を含まない (基本許可関数なし)。
     *
     * range(1, 巨大な数) や同義の `..` 演算子は、運営者入力のフォーム本文で実行すると
     * メモリ枯渇の Fatal Error に至ることを実機検証済み。上限を設けずに許可すると DoS になるため、
     * 運営者入力からは組込み関数を許可しない。
     *
     * @var list<string>
     */
    public const ALLOWED_FUNCTIONS = [];
}
