Use separate Ragel machines for script/style tags

Previously a single Ragel machine was used for processing HTML
script and style tags. This had the unfortunate side-effect that the
following was not parsed correctly (while being valid HTML):

    <script>
    var foo = "</style>";
    </script>

The same applied to style tags:

    <style>
    /* </script> */
    </style>

By using separate machines we can work around the above issue. The
downside is that this can produce multiple T_TEXT nodes, which have to
be stitched back together in the parser.
This commit is contained in:
Yorick Peterse committed 2015-04-16 01:45:39 +02:00
1 parent 2d43e459a1
commit 73fbbfbdbd
7 files changed
+118 -54

No files matched your search

+16 -2
View File
@@ -3,10 +3,24 @@ require 'spec_helper'
describe Oga::XML::Lexer do
describe 'HTML script elements' do
it 'treats the content of a script tag as plain text' do
lex('<script>foo <bar</script>', :html => true).should == [
lex_html('<script>foo <bar</script>').should == [
[:T_ELEM_START, nil, 1],
[:T_ELEM_NAME, 'script', 1],
[:T_TEXT, 'foo <bar', 1],
[:T_TEXT, 'foo ', 1],
[:T_TEXT, '<', 1],
[:T_TEXT, 'bar', 1],
[:T_ELEM_END, nil, 1]
]
end
it 'treats style tags inside script tags as text' do
lex_html('<script><style></style></script>').should == [
[:T_ELEM_START, nil, 1],
[:T_ELEM_NAME, 'script', 1],
[:T_TEXT, '<', 1],
[:T_TEXT, 'style>', 1],
[:T_TEXT, '<', 1],
[:T_TEXT, '/style>', 1],
[:T_ELEM_END, nil, 1]
]
end
+19 -7
View File
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Oga::XML::Lexer do
describe 'HTML style elements' do
it 'lexes an empty <style> tag' do
lex('<style></style>', :html => true).should == [
lex_html('<style></style>').should == [
[:T_ELEM_START, nil, 1],
[:T_ELEM_NAME, 'style', 1],
[:T_ELEM_END, nil, 1]
@@ -11,16 +11,30 @@ describe Oga::XML::Lexer do
end
it 'treats the content of a style tag as plain text' do
lex('<style>foo <bar</style>', :html => true).should == [
lex_html('<style>foo <bar</style>').should == [
[:T_ELEM_START, nil, 1],
[:T_ELEM_NAME, 'style', 1],
[:T_TEXT, 'foo <bar', 1],
[:T_TEXT, 'foo ', 1],
[:T_TEXT, '<', 1],
[:T_TEXT, 'bar', 1],
[:T_ELEM_END, nil, 1]
]
end
it 'treats script tags inside style tags as text' do
lex_html('<style><script></script></style>').should == [
[:T_ELEM_START, nil, 1],
[:T_ELEM_NAME, 'style', 1],
[:T_TEXT, '<', 1],
[:T_TEXT, 'script>', 1],
[:T_TEXT, '<', 1],
[:T_TEXT, '/script>', 1],
[:T_ELEM_END, nil, 1]
]
end
it 'lexes a multi-line <style> tag using a String as the input' do
lex("<style>foo\nbar</style>", :html => true).should == [
lex_html("<style>foo\nbar</style>").should == [
[:T_ELEM_START, nil, 1],
[:T_ELEM_NAME, 'style', 1],
[:T_TEXT, "foo\nbar", 1],
@@ -29,9 +43,7 @@ describe Oga::XML::Lexer do
end
it 'lexes a multi-line <style> tag using an IO as the input' do
io = StringIO.new("<style>foo\nbar</style>")
lex(io, :html => true).should == [
lex_stringio("<style>foo\nbar</style>", :html => true).should == [
[:T_ELEM_START, nil, 1],
[:T_ELEM_NAME, 'style', 1],
[:T_TEXT, "foo\n", 1],