Skip to content

Commit

Permalink
fix: ignore else expressions and superfluous blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
jg-rp committed Feb 10, 2024
1 parent e3fdeae commit e148c41
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 16 deletions.
37 changes: 29 additions & 8 deletions src/builtin/tags/if.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class IfTag implements Tag {
TOKEN_EOF,
]);
protected static END_ELSEIF_BLOCK = new Set([TAG_ENDIF, TAG_ELSIF, TAG_ELSE]);
protected static END_ELSE_BLOCK = new Set([TAG_ENDIF]);
protected static END_ELSE_BLOCK = new Set([TAG_ENDIF, TAG_ELSIF, TAG_ELSE]);

readonly block = true;
readonly name: string = TAG_IF;
Expand Down Expand Up @@ -71,24 +71,45 @@ export class IfTag implements Tag {
});
}

let alternative: BlockNode | undefined = undefined;

if (
stream.current.kind === TOKEN_TAG &&
stream.current.value === TAG_ELSE
) {
return new this.nodeClass(
token,
condition,
consequence,
conditionalAlternatives,
parser.parseBlock(stream, IfTag.END_ELSE_BLOCK, stream.next()),
);
const tok = stream.next();
// @ts-expect-error: stream.current has changed, so `kind` will have changed too.
if (stream.current.kind === TOKEN_EXPRESSION) {
// Superfluous expressions inside an `else` tag are ignored.
stream.next();
}

alternative = parser.parseBlock(stream, IfTag.END_ELSE_BLOCK, tok);
}

// Extraneous `else` and `elsif` blocks are ignored.
if (
!(stream.current.kind === TOKEN_TAG && stream.current.value === TAG_ENDIF)
) {
while (stream.current.kind !== TOKEN_EOF) {
if (
stream.current.kind === TOKEN_TAG &&
stream.current.value === TAG_ENDIF
) {
break;
}
stream.next();
}
}

stream.expectTag(TAG_ENDIF);

return new this.nodeClass(
token,
condition,
consequence,
conditionalAlternatives,
alternative,
);
}
}
Expand Down
44 changes: 36 additions & 8 deletions src/builtin/tags/unless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,18 @@ export class UnlessTag implements Tag {
TAG_ELSE,
TOKEN_EOF,
]);

protected static END_ELSEIF_BLOCK = new Set([
TAG_ENDUNLESS,
TAG_ELSIF,
TAG_ELSE,
]);
protected static END_ELSE_BLOCK = new Set([TAG_ENDUNLESS]);

protected static END_ELSE_BLOCK = new Set([
TAG_ENDUNLESS,
TAG_ELSIF,
TAG_ELSE,
]);

readonly block = true;
readonly name: string = TAG_UNLESS;
Expand Down Expand Up @@ -79,24 +85,46 @@ export class UnlessTag implements Tag {
});
}

let alternative: BlockNode | undefined = undefined;

if (
stream.current.kind === TOKEN_TAG &&
stream.current.value === TAG_ELSE
) {
return new this.nodeClass(
token,
condition,
consequence,
conditionalAlternatives,
parser.parseBlock(stream, UnlessTag.END_ELSE_BLOCK, stream.next()),
);
const tok = stream.next();
// @ts-expect-error: stream.current has changed, so `kind` will have changed too.
if (stream.current.kind === TOKEN_EXPRESSION) {
// Superfluous expressions inside an `else` tag are ignored.
stream.next();
}

alternative = parser.parseBlock(stream, UnlessTag.END_ELSE_BLOCK, tok);
}

// Extraneous `else` and `elsif` blocks are ignored.
if (
!(
stream.current.kind === TOKEN_TAG &&
stream.current.value === TAG_ENDUNLESS
)
) {
while (stream.current.kind !== TOKEN_EOF) {
if (
stream.current.kind === TOKEN_TAG &&
stream.current.value === TAG_ENDUNLESS
) {
break;
}
stream.next();
}
}

return new this.nodeClass(
token,
condition,
consequence,
conditionalAlternatives,
alternative,
);
}
}
Expand Down
54 changes: 54 additions & 0 deletions tests/golden/golden_liquid.json
Original file line number Diff line number Diff line change
Expand Up @@ -3865,6 +3865,33 @@
"error": false,
"strict": false
},
{
"name": "else tag expressions are ignored",
"template": "{% if false %}1{% else nonsense %}2{% endif %}",
"want": "2",
"context": {},
"partials": {},
"error": false,
"strict": true
},
{
"name": "extra else blocks are ignored",
"template": "{% if false %}1{% else %}2{% else %}3{% endif %}",
"want": "2",
"context": {},
"partials": {},
"error": false,
"strict": true
},
{
"name": "extra elsif blocks are ignored",
"template": "{% if false %}1{% else %}2{% elsif true %}3{% endif %}",
"want": "2",
"context": {},
"partials": {},
"error": false,
"strict": true
},
{
"name": "int does not equal string",
"template": "{% if 1 == '1' %}true{% else %}false{% endif %}",
Expand Down Expand Up @@ -9335,6 +9362,33 @@
"error": false,
"strict": false
},
{
"name": "else tag expressions are ignored",
"template": "{% unless true %}1{% else nonsense %}2{% endunless %}",
"want": "2",
"context": {},
"partials": {},
"error": false,
"strict": true
},
{
"name": "extra else blocks are ignored",
"template": "{% unless true %}1{% else %}2{% else %}3{% endunless %}",
"want": "2",
"context": {},
"partials": {},
"error": false,
"strict": true
},
{
"name": "extra elsif blocks are ignored",
"template": "{% unless true %}1{% else %}2{% elsif true %}3{% endunless %}",
"want": "2",
"context": {},
"partials": {},
"error": false,
"strict": true
},
{
"name": "literal false condition",
"template": "{% unless false %}foo{% endunless %}",
Expand Down

0 comments on commit e148c41

Please sign in to comment.