21

HTML解析で病的なケースに遭遇しました。<script>タグは最初の終了タグまで実行されるといつも思っていました</script>。しかし、これが常に当てはまるとは限りません

これは有効です:

<script><!--
alert('<script></script>');
--></script>

そしてこれも有効です:

<script><!--
alert('<script></script>');
</script>

しかし、これはそうではありません:

<script><!--
alert('</script>');
--></script>

そして、これもそうではありません:

<script>
alert('<script></script>');
</script>

この動作はFirefoxとChromeで一貫しています。したがって、信じがたいことですが、ブラウザは、スクリプトタグ内のhtmlコメント内でopen+closeスクリプトタグを受け入れるようです。では、問題は、ブラウザが実際にスクリプトタグをどのように解析するのかということです。これが重要なのは、私が使用しているHTML解析ライブラリであるNokogiriが、最初の終了タグまでの明らかな(ただし正しくない)ルールを想定し、このエッジケースを処理しなかったためです。他のほとんどのライブラリもそれを処理しないと思います。

4

4 に答える 4

10

ティム とジュッカによって与えられたリンクを熟考した後、私は次の答えに到達しました:

  • 開始<script>タグの後、パーサーはdata1状態になります
  • data1<!--状態で発生した場合は、 data2状態に切り替えます
  • -->いずれかの状態で遭遇した場合は、 data1状態に切り替えます
  • data2状態で検出された場合<script[\s/>]は、 data3状態に切り替えます
  • data3状態で検出された場合</script[\s/>]は、 data2状態に切り替えます
  • </script[\s/>]他の状態で遭遇した場合は、解析を停止します
于 2013-01-30T16:01:30.730 に答える
5

HTML 4.01仕様に従って、すべての例は無効です。のコンテンツはscriptとして宣言されてCDATAおり、の説明CDATA次のようになっています。

「STYLE要素とSCRIPT要素はデータモデルにCDATAを使用しますが、これらの要素の場合、CDATAはユーザーエージェントによって異なる方法で処理される必要があります。マークアップとエンティティは生のテキストとして扱われ、そのままアプリケーションに渡される必要があります。文字シーケンス""(end-tag open delimiter)の最初の出現は</、要素のコンテンツの終わりを終了するものとして扱われます。有効なドキュメントでは、これが要素の終了タグになります。」</ p>

ご覧のとおり、状況によっては、ブラウザがこのルールを適用せず、代わりに開始タグと終了タグのペアを認識する場合があります。仕様の観点からは、これは無効なドキュメントの処理、つまりエラー処理です。彼らがここで何をしているのか、そしてその理由は明らかではありません。の存在に依存しているようですが<!--、HTML 4.01の解析には影響しないはずです(コンテンツのコメントオープナーではありません)。CDATA

XHTMLでは、要素<!--のコンテンツ内でコメントを開くため、部分的に異なるルールが適用されます。script

余談ですが、のtype属性がないため、すべての例は無効なHTML4.01と無効なXHTMLscriptです。この属性は必要ありませんが(ブラウザーはデフォルトでコンテンツをJavaScriptとして処理します)、これらの仕様では必須です。

HTML5では、他のルールが適用されます。それらはかなり複雑で、ブラウザの動作を説明することになっています。HTML5は、コンテンツに制限を課す(たとえば<!--、一致せずに禁止する)ことに加えて、解析ルールも指定します。-->

于 2013-01-29T06:42:44.720 に答える
1

タグのコンテンツは、HTMLでないものとしてマークしない限り、HTMLのままです。HTMLでは、<word>はタグと見なされ、この動作を回避<するように記述する必要があります。または、テキストノード&lt;のコンテンツを作成することもできます。<script>次の式を使用します。

<script type="text/javascript">
//<![CDATA[
  // your code, with < and & and "", woohoo!
//]]>
</script>

<![CDATA[ ... ]]>ドキュメントの一部をマークアップなしの純粋なテキストとして描写します。JavaScriptが混乱しないように、スラッシュがあります。スラッシュの最初のセットはCDATAの外にありますが、HTMLセーフであるため、問題はありません。

編集:質問はHTMLの記述ではなく、構文解析に関するものであることに気づきました。おっと。

于 2013-01-29T02:16:57.017 に答える
1

仮に、タグが最初に解析され、コメントが後で解析される場合、HTMLパーサーはそれらの結果を提供します。

(これが必ずしも当てはまるわけではなく、考えられる説明にすぎません。)

1番目のケース

<script><!--
alert('<script></script>');
--></script>

<script></script>別の中にセットがあり<script></script>ます。パーサーは最初にタグの名前を無視し、それらのタグの適切な開閉をチェックするだけです。次に、コメントを解析します。

<script><!--
--></script>

したがって、これは有効です。

2番目のケース

<script><!--
alert('<script></script>');
</script>

<script></script>別の中にセットがあり<script></script>ます。次に、コメントを解析します。

<script><!--

コメントは、ドキュメントの最後まで拡張されます。これは厳密には有効ではありませんが、ブラウザは正しく処理します。

3番目のケース

<script><!--
alert('</script>');
--></script>

のセット内に単一の終了タグがあり<script></script>ます。</script>コメントとして解析する前に無効になります。

4番目のケース

<script>
alert('<script></script>');
</script>

<script></script>別の中にセットがあり<script></script>、コメントはありません。最初のパスは有効ですが、実際にタグを調べてタグが何であるかを確認します。別のタグ内のタグのペアを受け入れない可能性がある<script>ため、ケースが無効になります。

于 2013-01-29T02:32:21.697 に答える