Skip to content

Commit

Permalink
#214 tags in HTML attribute strings are ignored
Browse files Browse the repository at this point in the history
  • Loading branch information
casid committed Apr 26, 2023
1 parent 7171519 commit fc59606
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
15 changes: 12 additions & 3 deletions jte/src/main/java/gg/jte/compiler/TemplateParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ private void interceptHtmlTags() {
outputPrevented = false;
}
}
} else if (!currentHtmlTag.attributesProcessed && regionMatches("/>")) {
} else if (!currentHtmlTag.attributesProcessed && !currentHtmlTag.isInAttributeString() && regionMatches("/>")) {
if (currentHtmlTag.intercepted) {
extractTextPart(i - 1, null);
lastIndex = i - 1;
Expand All @@ -713,7 +713,7 @@ private void interceptHtmlTags() {
currentHtmlTag.attributesProcessed = true;

popHtmlTag();
} else if (!currentHtmlTag.attributesProcessed && currentChar == '>') {
} else if (!currentHtmlTag.attributesProcessed && !currentHtmlTag.isInAttributeString() && currentChar == '>') {
if (tagClosed) {
tagClosed = false;
} else {
Expand All @@ -728,7 +728,7 @@ private void interceptHtmlTags() {
popHtmlTag();
}
}
} else if (regionMatches("</")) {
} else if (currentHtmlTag.attributesProcessed && regionMatches("</")) {
if (templateCode.startsWith(currentHtmlTag.name, i + 1)) {
if (!currentHtmlTag.bodyIgnored) {
if (currentHtmlTag.intercepted) {
Expand Down Expand Up @@ -1158,6 +1158,15 @@ public boolean isInAttribute() {
return currentAttribute != null && currentAttribute.quoteCount < 2;
}

public boolean isInAttributeString() {
if (attributesProcessed) {
return false;
}

HtmlAttribute currentAttribute = getCurrentAttribute();
return currentAttribute != null && currentAttribute.quoteCount == 1;
}

public boolean isInStringLiteral() {
return stringLiteralQuote != 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,42 @@ void unclosedTag() {
assertThat(throwable).isInstanceOf(TemplateException.class).hasMessage("Failed to compile unclosed.jte, error at line 1: Unclosed tag <a>, expected </a>, got </span>.");
}

@Test
void unclosedTag_worksWithHyperScript() {
codeResolver.givenCode("closed.jte", "<body>\n" +
"<p _=\"on load log 'hello world from console'\">Hello world</p>\n" +
"\n" +
"<form action=\"/login\" method=\"post\" _=\"on submit toggle @disabled on <button[type='submit']/>\">\n" +
" <input type=\"email\" name=\"username\">\n" +
" <input type=\"password\" name=\"password\">\n" +
"\n" +
" <button type=\"submit\">Login</button>\n" +
"</form>\n" +
"</body>");

Throwable throwable = catchThrowable(() -> templateEngine.render("closed.jte", null, output));

assertThat(throwable).isNull();
}

@Test
void unclosedTag_worksWithHtmlInAttribute() {
codeResolver.givenCode("closed.jte", "<form><input name=\">\" disabled=\"${true}\"></form>");

templateEngine.render("closed.jte", null, output);

assertThat(output.toString()).isEqualTo("<form><input name=\">\" disabled></form>"); // tag processing must not end after name=">", otherwise disabled="true" instead of just disabled would be the output.
}

@Test
void unclosedTag_worksWithClosingHtmlInAttribute() {
codeResolver.givenCode("closed.jte", "<form><input text=\"</form>\"></form>");

templateEngine.render("closed.jte", null, output);

assertThat(output.toString()).isEqualTo("<form><input text=\"</form>\"></form>");
}

@Test
void codeInTag() {
codeResolver.givenCode("template.jte", "@param String tag\n\n<span><${tag}/></span>");
Expand Down

0 comments on commit fc59606

Please sign in to comment.