WikiChree.COM 新規   編集   添付   管理  



トップ   編集 編集〔GUI〕 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS   ログイン

Pkript/設定/old の変更点

#author("2026-08-31T22:17:22+09:00","default:guide","guide")
* Pkript/設定 [#z9ac4e6a]

Pkript の設定項目、直接呼び出し、セキュリティの解説です。

#contents


** 設定定数 (plugin/pkript.inc.php) [#yff3000b]

plugin/pkript.inc.php 内の定数を編集して動作を調整できます。

*** スクリプトの置き場所 [#u3a5c118]
|~定数名|~既定値|~説明|
|PKRIPT_SCRIPT_DIR|'plugin/pkript/script/'|スクリプトの配置ディレクトリ|
|PKRIPT_SCRIPT_EXT|'pks,js'|受け付ける拡張子(カンマ区切り、優先順)|
|PKRIPT_ALLOW_PAGE_SCRIPT|1|:config/pkript/script/ ページからの実行を許可するか|
|PKRIPT_PAGE_SCRIPT_FROZEN_ONLY|0|ページ実行を凍結ページのみに限定するか|
|PKRIPT_PAGE_PREFIX|':config/pkript/script/'|ページスクリプトのページ名接頭辞|
|PKRIPT_ALLOW_DATA|1|data.* によるデータ保存を有効にするか|
|PKRIPT_DATA_PREFIX|':config/pkript/data/'|データを置くページ名の接頭辞|
|PKRIPT_DATA_MIN_TRUST|PKRIPT_WRITE_MIN_TRUST|data.set() に必要な信頼度|
|PKRIPT_BIND|1|#hello のように、スクリプト名で直接呼び出せるようにするか|

PKRIPT_BIND を 0 にすると #pkript(hello) と &pkript(hello); だけになり、#hello は未定義のプラグイン扱いになります。下の「#aaa による直接呼び出し」も参照してください。

*** 文法 [#uf807887]
|~定数名|~既定値|~説明|
|PKRIPT_JSX|1|JSX記法(<p>{name}</p>)を使えるようにするか|
|PKRIPT_REGEX|1|正規表現リテラル(/[a-z]+/i)を使えるようにするか|
|PKRIPT_REGEX_BACKTRACK|100000|1回の照合で許すバックトラック量|
|PKRIPT_MAX_REGEX|512|パターンの最大バイト数|

PKRIPT_JSX を 0 にすると < は比較演算子としてだけ働きます。詳しくは [[Pkript/文法/JSX]] を参照してください。

PKRIPT_REGEX を 0 にすると / は除算としてだけ働きます。PKRIPT_REGEX_BACKTRACK は暴走するパターン(ReDoS)を止めるための上限で、PHPの既定値1,000,000より大幅に低く設定しています。詳しくは [[Pkript/文法/正規表現]] を参照してください。

*** 1リクエストあたりの上限 [#nfa67e6d]
1ページに #pkript をいくつ書いても、wiki.convert の入れ子で別のスクリプトが動いても、下の値が1リクエストの合計です。

|~定数名|~既定値|~説明|
|PKRIPT_MAX_STEPS|1000000|評価ステップ数|
|PKRIPT_MAX_TIME|3|実行時間(秒)。Pkript の中で過ごした時間の合計です|
|PKRIPT_MAX_MEMORY|memory_limit の3/4|メモリ使用量|
|PKRIPT_MAX_CONVERT|32|wiki.convert の呼び出し回数|
|PKRIPT_MAX_READS|5000|ページの参照回数(wiki.exists / source / pages / link)|
|PKRIPT_MAX_WRITES|4|ページの書き込み回数|

*** 1回の実行・1つの値の上限 [#yddc2152]
|~定数名|~既定値|~説明|
|PKRIPT_MAX_DEPTH|64|関数の最大呼び出し深度|
|PKRIPT_MAX_LOOP|100000|1ループの最大繰り返し回数|
|PKRIPT_MAX_STRING|1048576|文字列の最大バイト数(1MB)|
|PKRIPT_MAX_ARRAY|10000|配列の最大要素数|
|PKRIPT_MAX_PAGES|1000|wiki.pages が返せる最大ページ数|
|PKRIPT_MAX_PAGE_BYTES|524288|書き込めるページの最大バイト数(512KB)|
|PKRIPT_MAX_IMPORTS|16|import できる最大スクリプト数|
|PKRIPT_MAX_IMPORT_DEPTH|4|import の最大深度|

*** 権限とキャッシュ [#m57a6d0e]
|~定数名|~既定値|~説明|
|PKRIPT_WRITE_MIN_TRUST|PKRIPT_TRUST_FILE|ページを書き込める最低の信頼度|
|PKRIPT_IMPORT_LOWER_TRUST|0|自分より信頼度の低いスクリプトの import を許すか|
|PKRIPT_SECRET_FILE|CACHE_DIR . 'pkript_secret.dat'|CSRFトークンの秘密鍵の置き場所|
|PKRIPT_AST_CACHE|1|解析済みスクリプトを cache/ に保存するか|
|PKRIPT_DEBUG|1|エラーに行番号と列番号を出すか、console.log の内容を出すか|
|PKRIPT_MAX_LOG|100|console.log で残せる行数|
|PKRIPT_MAX_LOG_BYTES|8192|console.log 全体のバイト数|

これらは pukiwiki.ini.php で define すれば上書きできます。


** #aaa による直接呼び出し [#fbcc3589]

#pkript(hello) ではなく #hello と書いて直接呼び出せます。lib/plugin.php の exist_plugin が''実在するPHPプラグインを探して見つからなかったときだけ''、同名のスクリプトを探してラッパー関数を生成します。したがって同名のPHPプラグインは常に優先され、#edit や #attach をスクリプトに乗っ取らせることはできません。

 #hello(World)
 &hello(World);

この動作は PKRIPT_BIND で切り替えます。0 にするとラッパーの生成をやめ、#pkript(hello) と &pkript(hello); だけが呼び出し口になり、#hello は未定義のプラグイン扱いに戻ります。

 // pukiwiki.ini.php
 define('PKRIPT_BIND', 0);   // 既定は 1

lib/plugin.php を自分で改造している場合など、フォールバックが入っていない環境では exist_plugin 関数に以下を追加してください。

 if (file_exists(PLUGIN_DIR . 'pkript.inc.php')) {
     require_once(PLUGIN_DIR . 'pkript.inc.php');
     if (function_exists('plugin_pkript_bind') && plugin_pkript_bind($name)) {
         $exist[$name] = TRUE;
         $count[$name] = 1;
         return TRUE;
     }
 }


** セキュリティ [#je4eecaa]

*** 信頼度 [#w3340f80]
スクリプトをどこに置いたかで権限が決まります。

|~置き場所|~信頼度|~ページの書き込み|h
|ファイル(plugin/pkript/script/)|PKRIPT_TRUST_FILE|できます|
|凍結ページ(:config/pkript/script/)|PKRIPT_TRUST_FROZEN|できません|
|編集可能ページ(:config/pkript/script/)|PKRIPT_TRUST_PAGE|できません|

読み出し、表示、計算はどの信頼度でも同じように使えます。差が出るのはページの書き込みだけです。

**** import と信頼度 [#r705c984]
import しても権限は増えません。

- 実行全体が、関わったスクリプトのうち''一番低い信頼度''で動きます。凍結ページがファイルのライブラリを読み込んでも、その中の wiki.write は凍結ページの信頼度で判定されます。
- 自分より信頼度の低いスクリプトは読み込めません。編集可能なページの書き手が、凍結ページにコードを差し込めてしまうためです。PKRIPT_IMPORT_LOWER_TRUST を 1 にすると許可されますが、その場合も実行全体は低いほうに落ちます。

**** CSRFトークン [#u31b1f04]
wiki.write と wiki.append は wiki.token() のトークンを要求します。トークンは''ログイン中のユーザーに紐付きます''。

認証を設定していないWikiでは紐付ける相手がいないため、トークンはサイト共通の値でしかありません。Wikiを読める人はトークンも読めます。誰でも編集できるWikiでの書き込み制限は、トークンではなく $edit_auth_pages で行ってください。

*** HTMLサニタイザ [#i13629b8]
スクリプトが出力したHTMLは自動で検査され、危険なタグや属性は無害化されます。

- script, iframe 等の危険なタグは無効化されます。
- onclick 等のイベント属性は除去されます。
- href, src の javascript: や data: スキームは除去されます。
- class や id には自動で pkript- 接頭辞が付与されます。

*** style属性で使えるCSS [#mc19c12c]

プロパティのホワイトリストと、値のパターン検査の二段構えです。見た目のためのプロパティは広く通します。

|~分類|~通すもの|h
|色・文字|color, background-color, font-*, text-*, line-height, letter-spacing, word-spacing, white-space, word-break, overflow-wrap, list-style*|
|箱|margin*, padding*, border*, box-shadow, box-sizing, width, height, min-*, max-*, display, vertical-align, opacity, visibility, overflow*, float, clear, cursor|
|表|border-collapse, border-spacing, table-layout, caption-side, outline*|
|Flexbox|flex*, justify-*, align-*, order, gap, row-gap, column-gap|
|Grid|grid-template-*, grid-auto-*, grid-area, grid-column, grid-row, place-*|
|動き|transition*, animation*, transform, transform-origin, will-change, filter|

 <div style="transform:rotate(3deg); transition:all 0.3s ease-in-out">

''通さないもの''は、見た目ではなく''位置''に関わるものです。

- position と z-index は通しません(fixed / absolute でWiki自身の上に重ねられるため)
- ビューポート単位(vw / vh)は通しません(ウィンドウに対して自分を大きくするのはオーバーレイの第一歩であるため)
- url(...) を含む値は通しません。したがって background-image も通しません
- expression(...)、javascript:、@import、\、/* を含む値は通しません
- 関数はホワイトリスト制です。rgb / rgba / hsl / hsla、translate* / scale* / rotate* / skew* / matrix / perspective、cubic-bezier / steps、repeat / minmax / fit-content、blur などのfilter系のみで、引数も同じ規則で検査します。calc() はまだ通していません

値が規則に合わないプロパティは、そのプロパティだけ黙って消えます(要素は残ります)。

animation-name が指すキーフレームは''スクリプトからは定義できません''。<style> は書けず、書いてもサニタイザが落とすため、参照できるのはスキンが既に定義しているものだけです。