github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/html/template/error.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package template 6 7 import ( 8 "github.com/shogo82148/std/text/template/parse" 9 ) 10 11 // Errorは、テンプレートのエスケープ処理中に遭遇した問題を説明します。 12 type Error struct { 13 // ErrorCodeはエラーの種類を説明します。 14 ErrorCode ErrorCode 15 // Nodeは問題を引き起こしたノードです(もし分かる場合)。 16 // nilでない場合、NameとLineを上書きします。 17 Node parse.Node 18 // Nameはエラーが発生したテンプレートの名前です。 19 Name string 20 // Lineはテンプレートソース内のエラーの行番号、または0です。 21 Line int 22 // Descriptionは問題の人間が読める説明です。 23 Description string 24 } 25 26 // ErrorCodeはエラーの種類を表すコードです。 27 type ErrorCode int 28 29 // テンプレートをエスケープする際に現れる各エラーに対してコードを定義していますが、 30 // エスケープされたテンプレートは実行時にも失敗する可能性があります。 31 // 32 // 出力: "ZgotmplZ" 33 // 例: 34 // 35 // <img src="{{.X}}"> 36 // ここで {{.X}} は `javascript:...` に評価されます 37 // 38 // 議論: 39 // 40 // "ZgotmplZ" は、実行時に安全でないコンテンツがCSSまたはURLのコンテキストに到達したことを示す特別な値です。 41 // 例の出力は 42 // <img src="#ZgotmplZ"> 43 // になります。 44 // データが信頼できるソースから来る場合は、フィルタリングから免除するためにコンテンツタイプを使用します:URL(`javascript:...`)。 45 const ( 46 // OKはエラーがないことを示します。 47 OK ErrorCode = iota 48 49 // ErrAmbigContext: "...はURL内の曖昧なコンテキストに現れます" 50 // 例: 51 // <a href=" 52 // {{if .C}} 53 // /path/ 54 // {{else}} 55 // /search?q= 56 // {{end}} 57 // {{.X}} 58 // "> 59 // 議論: 60 // {{.X}}は曖昧なURLコンテキストにあります。なぜなら、{{.C}}によって、 61 // URLの接尾辞かクエリパラメータのどちらかになる可能性があるからです。 62 // {{.X}}を条件の中に移動すると曖昧さがなくなります: 63 // <a href="{{if .C}}/path/{{.X}}{{else}}/search?q={{.X}}"> 64 ErrAmbigContext 65 66 // ErrBadHTML: "スペース、属性名、またはタグの終わりを期待していましたが、...が得られました", 67 // "...は引用符で囲まれていない属性内にあります", "...は属性名内にあります" 68 // 例: 69 // <a href = /search?q=foo> 70 // <href=foo> 71 // <form na<e=...> 72 // <option selected< 73 // 議論: 74 // これは、HTML要素のタイプミスが原因であることが多いですが、一部のルーンは、 75 // パーサーの曖昧さを引き起こす可能性があるため、タグ名、属性名、引用符で囲まれていない属性値で禁止されています。 76 // すべての属性を引用符で囲むのが最善の方針です。 77 ErrBadHTML 78 79 // ErrBranchEnd: "{{if}}の分岐が異なるコンテキストで終わります" 80 // 例: 81 // {{if .C}}<a href="{{end}}{{.X}} 82 // 議論: 83 // パッケージhtml/templateは、{{if}}、{{range}}、または{{with}}を通じて各パスを静的に調べ、 84 // その後のパイプラインをエスケープします。例は曖昧です。なぜなら、{{.X}}はHTMLテキストノードであるか、 85 // HTML属性のURLプレフィックスである可能性があるからです。{{.X}}のコンテキストは、それをどのようにエスケープするかを 86 // 理解するために使用されますが、そのコンテキストは実行時の{{.C}}の値に依存し、それは静的には知られていません。 87 // 88 // 問題は通常、引用符や角括弧が欠けているなどの問題であり、または、2つのコンテキストをif、range、withの 89 // 異なる分岐にリファクタリングすることで回避できます。問題が空であるべきではないコレクションに対する{{range}}にある場合、 90 // ダミーの{{else}}を追加すると役立つことがあります。 91 ErrBranchEnd 92 93 // ErrEndContext: "...は非テキストコンテキストで終わります: ..." 94 // 例: 95 // <div 96 // <div title="閉じ引用符なし> 97 // <script>f() 98 // 議論: 99 // 実行されたテンプレートはHTMLのDocumentFragmentを生成するべきです。 100 // 閉じタグなしで終わるテンプレートはこのエラーを引き起こします。 101 // HTMLコンテキストで使用すべきでないテンプレート、または不完全なFragmentを生成するテンプレートは、 102 // 直接実行すべきではありません。 103 // 104 // {{define "main"}} <script>{{template "helper"}}</script> {{end}} 105 // {{define "helper"}} document.write(' <div title=" ') {{end}} 106 // 107 // "helper"は有効なドキュメントフラグメントを生成しないため、直接実行すべきではありません。 108 ErrEndContext 109 110 // ErrNoSuchTemplate: "そのようなテンプレートは存在しません ..." 111 // 例: 112 // {{define "main"}}<div {{template "attrs"}}>{{end}} 113 // {{define "attrs"}}href="{{.URL}}"{{end}} 114 // 議論: 115 // パッケージhtml/templateはテンプレート呼び出しを見てコンテキストを計算します。 116 // ここでは、"attrs"の{{.URL}}は"main"から呼び出されたときにURLとして扱われなければなりませんが、 117 // "main"が解析されたときに"attrs"が定義されていない場合、このエラーが発生します。 118 ErrNoSuchTemplate 119 120 // ErrOutputContext: "テンプレート...の出力コンテキストを計算できません" 121 // 例: 122 // {{define "t"}}{{if .T}}{{template "t" .T}}{{end}}{{.H}}",{{end}} 123 // 議論: 124 // 再帰的なテンプレートは、開始したときと同じコンテキストで終わらないため、 125 // 信頼性のある出力コンテキストを計算することはできません。 126 // 名前付きテンプレートのタイプミスを探してみてください。 127 // もしテンプレートが名前付きの開始コンテキストで呼び出されるべきでないなら、 128 // 予期しないコンテキストでそのテンプレートへの呼び出しを探してみてください。 129 // 再帰的なテンプレートを再帰的でないようにリファクタリングすることも考えてみてください。 130 ErrOutputContext 131 132 // ErrPartialCharset: "未完成のJS正規表現文字セットが...に存在します" 133 // 例: 134 // <script>var pattern = /foo[{{.Chars}}]/</script> 135 // 議論: 136 // パッケージhtml/templateは、正規表現リテラルの文字セットへの補間をサポートしていません。 137 ErrPartialCharset 138 139 // ErrPartialEscape: "未完成のエスケープシーケンスが...に存在します" 140 // 例: 141 // <script>alert("\{{.X}}")</script> 142 // 議論: 143 // パッケージhtml/templateは、バックスラッシュの後に続くアクションをサポートしていません。 144 // これは通常、エラーであり、より良い解決策があります。例えば、 145 // <script>alert("{{.X}}")</script> 146 // は動作するはずで、もし{{.X}}が"xA0"のような部分的なエスケープシーケンスであれば、 147 // 全体を安全なコンテンツとしてマークします:JSStr(`\xA0`) 148 ErrPartialEscape 149 150 // ErrRangeLoopReentry: "範囲ループの再入時に: ..." 151 // 例: 152 // <script>var x = [{{range .}}'{{.}},{{end}}]</script> 153 // 議論: 154 // 範囲を通じた反復が、以前のパスと異なるコンテキストで終わるような場合、単一のコンテキストは存在しません。 155 // 例では、引用符が欠けているため、{{.}}がJS文字列の内部にあるのか、JS値のコンテキストにあるのかが明確ではありません。 156 // 2回目の反復では、次のようなものが生成されます。 157 // 158 // <script>var x = ['firstValue,'secondValue]</script> 159 ErrRangeLoopReentry 160 161 // ErrSlashAmbig: "'/'は除算または正規表現を開始する可能性があります" 162 // 例: 163 // <script> 164 // {{if .C}}var x = 1{{end}} 165 // /-{{.N}}/i.test(x) ? doThis : doThat(); 166 // </script> 167 // 議論: 168 // 上記の例では、最初の'/'が数学的な除算演算子である`var x = 1/-2/i.test(s)...`を生成するか、 169 // 最初の'/'が正規表現リテラルを開始する`/-2/i.test(s)`を生成する可能性があります。 170 // 分岐内のセミコロンが欠けていないか確認し、どちらの解釈を意図しているか明確にするために 171 // 括弧を追加することを検討してみてください。 172 ErrSlashAmbig 173 174 // ErrPredefinedEscaper: "テンプレートで禁止されている事前定義されたエスケーパー..." 175 // 例: 176 // <div class={{. | html}}>Hello<div> 177 // 議論: 178 // パッケージhtml/templateは、すべてのパイプラインをコンテキストに応じてエスケープして、 179 // コードインジェクションに対して安全なHTML出力を生成します。事前定義されたエスケーパー"html"または"urlquery"を 180 // 使用してパイプライン出力を手動でエスケープすることは不要であり、Go 1.8以前ではエスケープされたパイプライン出力の 181 // 正確さや安全性に影響を与える可能性があります。 182 // 183 // ほとんどの場合、例えば上記の例のような場合、このエラーはパイプラインから事前定義されたエスケーパーを単純に削除し、 184 // コンテキスト自動エスケーパーがパイプラインのエスケープを処理することで解決できます。他の場合、事前定義されたエスケーパーが 185 // パイプラインの中間に存在し、後続のコマンドがエスケープされた入力を期待する場合、例えば 186 // {{.X | html | makeALink}} 187 // ここでmakeALinkは 188 // return `<a href="`+input+`">link</a>` 189 // を行う場合、周囲のテンプレートをリファクタリングしてコンテキスト自動エスケーパーを利用するように考えてみてください。つまり、 190 // <a href="{{.X}}">link</a> 191 // 192 // Go 1.9以降への移行を容易にするために、"html"と"urlquery"はパイプラインの最後のコマンドとして引き続き許可されます。 193 // ただし、パイプラインが引用符で囲まれていない属性値のコンテキストで発生する場合、"html"は禁止されます。 194 // 新しいテンプレートでは"html"と"urlquery"を全く使用しないようにしてください。 195 ErrPredefinedEscaper 196 197 // ErrJSTemplate: "...はJSテンプレートリテラル内に存在します" 198 // 例: 199 // <script>var tmpl = `{{.Interp}}`</script> 200 // 議論: 201 // パッケージhtml/templateは、JSテンプレートリテラル内のアクションをサポートしていません。 202 // 203 // Deprecated: JSテンプレートリテラル内にアクションが存在する場合、ErrJSTemplateはもはや返されません。 204 // JSテンプレートリテラル内のアクションは、現在予想通りにエスケープされます。 205 ErrJSTemplate 206 ) 207 208 func (e *Error) Error() string