Skip to content

Commit 88372a0

Browse files
committed
389622 - Escaping special characters in sections is not working
1 parent 48e98c5 commit 88372a0

File tree

5 files changed

+191
-46
lines changed

5 files changed

+191
-46
lines changed

src/System.Web.Razor/Parser/HtmlMarkupParser.Section.cs

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -62,33 +62,24 @@ private void NestingSection(Tuple<string, string> nestingSequences)
6262
int nesting = 1;
6363
while (nesting > 0 && !EndOfFile)
6464
{
65+
SkipToAndParseCode(sym =>
66+
sym.Type == HtmlSymbolType.Text ||
67+
sym.Type == HtmlSymbolType.OpenAngle);
6568
if (At(HtmlSymbolType.Text))
6669
{
6770
nesting += ProcessTextToken(nestingSequences, nesting);
71+
if (CurrentSymbol != null)
72+
{
73+
AcceptAndMoveNext();
74+
}
75+
else if (nesting > 0)
76+
{
77+
NextToken();
78+
}
6879
}
69-
else if (At(HtmlSymbolType.Transition))
70-
{
71-
PutCurrentBack();
72-
Output(SpanKind.Markup);
73-
OtherParserBlock();
74-
continue;
75-
}
76-
else if (At(HtmlSymbolType.RazorCommentTransition))
77-
{
78-
RazorComment();
79-
}
80-
else if (ScanTagInDocumentContext())
81-
{
82-
continue;
83-
}
84-
85-
if (CurrentSymbol != null)
86-
{
87-
AcceptAndMoveNext();
88-
}
89-
else if (nesting > 0)
80+
else
9081
{
91-
NextToken();
82+
ScanTagInDocumentContext();
9283
}
9384
}
9485
}

test/System.Web.Razor.Test/Parser/Html/HtmlBlockTest.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,6 @@ public void ParseBlockStopsParsingSingleLineBlockAtEOFIfNoEOLReached()
112112
));
113113
}
114114

115-
[Fact]
116-
public void ParseBlockTreatsTwoAtSignsAsEscapeSequence()
117-
{
118-
HtmlParserTestUtils.RunSingleAtEscapeTest(ParseBlockTest);
119-
}
120-
121-
[Fact]
122-
public void ParseBlockTreatsPairsOfAtSignsAsEscapeSequence()
123-
{
124-
HtmlParserTestUtils.RunMultiAtEscapeTest(ParseBlockTest);
125-
}
126-
127115
[Fact]
128116
public void ParseBlockStopsAtMatchingCloseTagToStartTag()
129117
{

test/System.Web.Razor.Test/Parser/Html/HtmlDocumentTest.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -192,18 +192,6 @@ public void ParseDocumentNoLongerSupportsDollarOpenBraceCombination()
192192
Factory.Markup("<foo>${bar}</foo>")));
193193
}
194194

195-
[Fact]
196-
public void ParseDocumentTreatsTwoAtSignsAsEscapeSequence()
197-
{
198-
HtmlParserTestUtils.RunSingleAtEscapeTest(ParseDocumentTest, lastSpanAcceptedCharacters: AcceptedCharacters.Any);
199-
}
200-
201-
[Fact]
202-
public void ParseDocumentTreatsPairsOfAtSignsAsEscapeSequence()
203-
{
204-
HtmlParserTestUtils.RunMultiAtEscapeTest(ParseDocumentTest, lastSpanAcceptedCharacters: AcceptedCharacters.Any);
205-
}
206-
207195
[Fact]
208196
public void ParseDocumentIgnoresTagsInContentsOfScriptTag()
209197
{

test/System.Web.Razor.Test/Parser/Html/HtmlToCodeSwitchTest.cs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,67 @@ public void ParseBlockGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLi
195195
Factory.Markup(" </ul>").Accepts(AcceptedCharacters.None)));
196196
}
197197

198+
[Fact]
199+
public void ParseDocumentGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine()
200+
{
201+
ParseDocumentTest(@" <ul>
202+
@foreach(var p in Products) {
203+
<li>Product: @p.Name</li>
204+
}
205+
</ul>",
206+
new MarkupBlock(
207+
Factory.Markup(" <ul>\r\n"),
208+
new StatementBlock(
209+
Factory.Code(" ").AsStatement(),
210+
Factory.CodeTransition(),
211+
Factory.Code("foreach(var p in Products) {\r\n").AsStatement(),
212+
new MarkupBlock(
213+
Factory.Markup(" <li>Product: "),
214+
new ExpressionBlock(
215+
Factory.CodeTransition(),
216+
Factory.Code("p.Name")
217+
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
218+
.Accepts(AcceptedCharacters.NonWhiteSpace)),
219+
Factory.Markup("</li>\r\n").Accepts(AcceptedCharacters.None)),
220+
Factory.Code(" }\r\n").AsStatement().Accepts(AcceptedCharacters.None)),
221+
Factory.Markup(" </ul>")));
222+
}
223+
224+
[Fact]
225+
public void SectionContextGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine()
226+
{
227+
ParseDocumentTest(@"@section foo {
228+
<ul>
229+
@foreach(var p in Products) {
230+
<li>Product: @p.Name</li>
231+
}
232+
</ul>
233+
}",
234+
new MarkupBlock(
235+
Factory.EmptyHtml(),
236+
new SectionBlock(new SectionCodeGenerator("foo"),
237+
Factory.CodeTransition(),
238+
Factory.MetaCode("section foo {").AutoCompleteWith(null, atEndOfSpan: true),
239+
new MarkupBlock(
240+
Factory.Markup("\r\n <ul>\r\n"),
241+
new StatementBlock(
242+
Factory.Code(" ").AsStatement(),
243+
Factory.CodeTransition(),
244+
Factory.Code("foreach(var p in Products) {\r\n").AsStatement(),
245+
new MarkupBlock(
246+
Factory.Markup(" <li>Product: "),
247+
new ExpressionBlock(
248+
Factory.CodeTransition(),
249+
Factory.Code("p.Name")
250+
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
251+
.Accepts(AcceptedCharacters.NonWhiteSpace)),
252+
Factory.Markup("</li>\r\n").Accepts(AcceptedCharacters.None)),
253+
Factory.Code(" }\r\n").AsStatement().Accepts(AcceptedCharacters.None)),
254+
Factory.Markup(" </ul>\r\n")),
255+
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
256+
Factory.EmptyHtml()));
257+
}
258+
198259
[Fact]
199260
public void CSharpCodeParserDoesNotAcceptLeadingOrTrailingWhitespaceInDesignMode()
200261
{
@@ -218,5 +279,72 @@ public void CSharpCodeParserDoesNotAcceptLeadingOrTrailingWhitespaceInDesignMode
218279
Factory.Markup("\r\n </ul>").Accepts(AcceptedCharacters.None)),
219280
designTimeParser: true);
220281
}
282+
283+
// Tests for "@@" escape sequence:
284+
[Fact]
285+
public void ParseBlockTreatsTwoAtSignsAsEscapeSequence()
286+
{
287+
HtmlParserTestUtils.RunSingleAtEscapeTest(ParseBlockTest);
288+
}
289+
290+
[Fact]
291+
public void ParseBlockTreatsPairsOfAtSignsAsEscapeSequence()
292+
{
293+
HtmlParserTestUtils.RunMultiAtEscapeTest(ParseBlockTest);
294+
}
295+
296+
[Fact]
297+
public void ParseDocumentTreatsTwoAtSignsAsEscapeSequence()
298+
{
299+
HtmlParserTestUtils.RunSingleAtEscapeTest(ParseDocumentTest, lastSpanAcceptedCharacters: AcceptedCharacters.Any);
300+
}
301+
302+
[Fact]
303+
public void ParseDocumentTreatsPairsOfAtSignsAsEscapeSequence()
304+
{
305+
HtmlParserTestUtils.RunMultiAtEscapeTest(ParseDocumentTest, lastSpanAcceptedCharacters: AcceptedCharacters.Any);
306+
}
307+
308+
[Fact]
309+
public void SectionBodyTreatsTwoAtSignsAsEscapeSequence()
310+
{
311+
ParseDocumentTest("@section Foo { <foo>@@bar</foo> }",
312+
new MarkupBlock(
313+
Factory.EmptyHtml(),
314+
new SectionBlock(new SectionCodeGenerator("Foo"),
315+
Factory.CodeTransition(),
316+
Factory.MetaCode("section Foo {").AutoCompleteWith(null, atEndOfSpan: true),
317+
new MarkupBlock(
318+
Factory.Markup(" <foo>"),
319+
Factory.Markup("@").Hidden(),
320+
Factory.Markup("@bar</foo> ")),
321+
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
322+
Factory.EmptyHtml()));
323+
}
324+
325+
[Fact]
326+
public void SectionBodyTreatsPairsOfAtSignsAsEscapeSequence()
327+
{
328+
ParseDocumentTest("@section Foo { <foo>@@@@@bar</foo> }",
329+
new MarkupBlock(
330+
Factory.EmptyHtml(),
331+
new SectionBlock(new SectionCodeGenerator("Foo"),
332+
Factory.CodeTransition(),
333+
Factory.MetaCode("section Foo {").AutoCompleteWith(null, atEndOfSpan: true),
334+
new MarkupBlock(
335+
Factory.Markup(" <foo>"),
336+
Factory.Markup("@").Hidden(),
337+
Factory.Markup("@"),
338+
Factory.Markup("@").Hidden(),
339+
Factory.Markup("@"),
340+
new ExpressionBlock(
341+
Factory.CodeTransition(),
342+
Factory.Code("bar")
343+
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
344+
.Accepts(AcceptedCharacters.NonWhiteSpace)),
345+
Factory.Markup("</foo> ")),
346+
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
347+
Factory.EmptyHtml()));
348+
}
221349
}
222350
}

test/System.Web.Razor.Test/Parser/VB/VBSectionTest.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,5 +221,55 @@ public void ParseSectionAllowsEndSectionInVBExpression()
221221
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
222222
Factory.EmptyHtml()));
223223
}
224+
225+
// These are tests that are normally in HtmlToCodeSwitchTest, but we want to verify them for VB
226+
// since VB has slightly different section terminating behavior which follow slightly different
227+
// code paths
228+
229+
[Fact]
230+
public void SectionBodyTreatsTwoAtSignsAsEscapeSequence()
231+
{
232+
ParseDocumentTest(@"@Section Foo
233+
<foo>@@bar</foo>
234+
End Section",
235+
new MarkupBlock(
236+
Factory.EmptyHtml(),
237+
new SectionBlock(new SectionCodeGenerator("Foo"),
238+
Factory.CodeTransition(),
239+
Factory.MetaCode("Section Foo").AutoCompleteWith(null),
240+
new MarkupBlock(
241+
Factory.Markup("\r\n <foo>"),
242+
Factory.Markup("@").Hidden(),
243+
Factory.Markup("@bar</foo>\r\n")),
244+
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
245+
Factory.EmptyHtml()));
246+
}
247+
248+
[Fact]
249+
public void SectionBodyTreatsPairsOfAtSignsAsEscapeSequence()
250+
{
251+
ParseDocumentTest(@"@Section Foo
252+
<foo>@@@@@bar</foo>
253+
End Section",
254+
new MarkupBlock(
255+
Factory.EmptyHtml(),
256+
new SectionBlock(new SectionCodeGenerator("Foo"),
257+
Factory.CodeTransition(),
258+
Factory.MetaCode("Section Foo").AutoCompleteWith(null),
259+
new MarkupBlock(
260+
Factory.Markup("\r\n <foo>"),
261+
Factory.Markup("@").Hidden(),
262+
Factory.Markup("@"),
263+
Factory.Markup("@").Hidden(),
264+
Factory.Markup("@"),
265+
new ExpressionBlock(
266+
Factory.CodeTransition(),
267+
Factory.Code("bar")
268+
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
269+
.Accepts(AcceptedCharacters.NonWhiteSpace)),
270+
Factory.Markup("</foo>\r\n")),
271+
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
272+
Factory.EmptyHtml()));
273+
}
224274
}
225275
}

0 commit comments

Comments
 (0)