Fix crash with simple string literal if-elif-else template
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 42/100
Research direction
Read jinja2cpp/src/template_parser.h, especially the expression and statement closing logic around the shown previous-character checks. Reproduce the reported templates, including literals containing %}, through the existing load and render path. Done means these cases load and render like Python Jinja2 without breaking ordinary statement and expression closing.
Written by the indexing model from the issue text.
Description
The following template loads and renders fine with Python jinja2, but crashes with jinja2cpp.
{% if 'foo' == 'bar'%}
1
{% elif 'foo' == 'foo' %}
2
{% else %}
3
{% endif %}
Note that removing elif, else will instead result in a load error (not a crash).
LOAD ERROR: noname.j2tpl:2:8: error: Expected expression, got: 'foo'
{% if 'foo' == 'bar'%}
Adding a space before '%}' on the first line will make the template actually function correctly.
Ideally, jinja2cpp would be able to handle this template just fine, like Python jinja2.
This looks like it fixes the crash and this example behaves correctly, although it's unclear to me whether this change might introduce other bugs. I noticed there was a similar check during end of expression for "'" (single quote) as well, so I remove that one too.
diff --git a/jinja2cpp/src/template_parser.h b/jinja2cpp/src/template_parser.h
--- a/jinja2cpp/src/template_parser.h
+++ b/jinja2cpp/src/template_parser.h
@@ -466,7 +466,7 @@
FinishCurrentLine(match.position() + 2);
return MakeParseError(ErrorCode::UnexpectedExprEnd, MakeToken(Token::ExprEnd, { matchStart, matchStart + 2 }));
}
- else if (m_currentBlockInfo.type != TextBlockType::Expression || (*m_template)[match.position() - 1] == '\'')
+ else if (m_currentBlockInfo.type != TextBlockType::Expression)
break;
m_currentBlockInfo.range.startOffset = FinishCurrentBlock(matchStart, TextBlockType::RawText);
@@ -480,7 +480,7 @@
FinishCurrentLine(match.position() + 2);
return MakeParseError(ErrorCode::UnexpectedStmtEnd, MakeToken(Token::StmtEnd, { matchStart, matchStart + 2 }));
}
- else if (m_currentBlockInfo.type != TextBlockType::Statement || (*m_template)[match.position() - 1] == '\'')
+ else if (m_currentBlockInfo.type != TextBlockType::Statement)
break;
m_currentBlockInfo.range.startOffset = FinishCurrentBlock(matchStart, TextBlockType::RawText);
Yeah, looks like string parsing is not handled fully correctly. Things like this appear to work fine in Python jinja2, but don't work in jinja2cpp (regardless of the code change above).
works in jinja2cpp without code change above but fails without
{% if '%}' == '%}' %}
1
{% endif %}
fails in jinja2cpp with or without code change above
{% if 'foo%}' == 'foo%}' %}
2
{% endif %}
It seems that the "check previous char" logic does not fully handle statement closing handling correctly, so removing that logic feels like the right thing to do.
Seems like we need to somehow detect that we are "inside a string literal" and ignore closing statement in such cases.
- Dominant language
- C++
- Stars
- 602
- Forks
- 115
- Avg merge
- 1h 46m
- Merged PRs (30d)
- 206
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from jinja2cpp/Jinja2Cpp
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
jinja2cpp/Jinja2Cpp#395 · 17 comments ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 65/100
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 74/100
Maintainers usually reply within 1 day
All issues in jinja2cpp/Jinja2Cpp
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 91/100
FujiNetWIFI/fujinet-firmware#2045 ·
Maintainers usually reply within 1 day
-
(S1 - Need confirmation)
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
CleverRaven/Cataclysm-DDA#89159 ·
Maintainers usually reply within 1 day
-
area:libnvmpi bug P3
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
gjrtimmer/jetson-nvmpi#33 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Maintainers usually reply within 1 day
-
bug(wasi_crypto): ArrayOutput::pull reports the wrong all-pulled flagPossibly taken @Yashbhu claimed this today. Open
Difficulty 1/5 Under an hour Newbie friendliness 84/100
Maintainers usually reply within 1 day