Skip to content

Commit a2046b7

Browse files
committed
Merge branch 'master' of github.com:HubSpot/jinjava into always-add-spacing
2 parents ba6433e + 23cf9af commit a2046b7

10 files changed

Lines changed: 85 additions & 84 deletions

File tree

src/main/java/com/hubspot/jinjava/interpret/JinjavaInterpreter.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@ public JinjavaInterpreter(JinjavaInterpreter orig) {
126126
scopeDepth = orig.getScopeDepth() + 1;
127127
}
128128

129+
public static void checkOutputSize(String string) {
130+
Optional<Long> maxStringLength = getCurrentMaybe()
131+
.map(interpreter -> interpreter.getConfig().getMaxOutputSize())
132+
.filter(max -> max > 0);
133+
if (
134+
maxStringLength.map(max -> string != null && string.length() > max).orElse(false)
135+
) {
136+
throw new OutputTooBigException(maxStringLength.get(), string.length());
137+
}
138+
}
139+
129140
/**
130141
* @deprecated use {{@link #getConfig()}}
131142
*/

src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerForTag.java

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
import com.hubspot.jinjava.interpret.DeferredValueException;
88
import com.hubspot.jinjava.interpret.InterpretException;
99
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
10-
import com.hubspot.jinjava.interpret.OutputTooBigException;
11-
import com.hubspot.jinjava.interpret.TemplateError;
12-
import com.hubspot.jinjava.interpret.TemplateSyntaxException;
1310
import com.hubspot.jinjava.lib.tag.ForTag;
1411
import com.hubspot.jinjava.tree.TagNode;
1512
import com.hubspot.jinjava.tree.parse.TagToken;
@@ -37,7 +34,7 @@ public EagerForTag(ForTag forTag) {
3734
}
3835

3936
@Override
40-
public String interpret(TagNode tagNode, JinjavaInterpreter interpreter) {
37+
public String innerInterpret(TagNode tagNode, JinjavaInterpreter interpreter) {
4138
Set<DeferredToken> addedTokens = new HashSet<>();
4239
EagerExecutionResult result = EagerReconstructionUtils.executeInChildContext(
4340
eagerInterpreter -> {
@@ -51,42 +48,28 @@ public String interpret(TagNode tagNode, JinjavaInterpreter interpreter) {
5148
interpreter,
5249
EagerChildContextConfig.newBuilder().withCheckForContextChanges(true).build()
5350
);
54-
try {
55-
if (
56-
result.getResult().getResolutionState() == ResolutionState.NONE ||
57-
(
58-
!result.getResult().isFullyResolved() &&
59-
!result.getSpeculativeBindings().isEmpty()
60-
)
61-
) {
62-
EagerIfTag.resetBindingsForNextBranch(interpreter, result);
63-
interpreter.getContext().removeDeferredTokens(addedTokens);
64-
throw new DeferredValueException(
65-
result.getResult().getResolutionState() == ResolutionState.NONE
66-
? result.getResult().toString()
67-
: "Modification inside partially evaluated for loop"
68-
);
69-
}
70-
if (result.getResult().isFullyResolved()) {
71-
return result.getResult().toString(true);
72-
} else {
73-
return EagerReconstructionUtils.wrapInChildScope(
74-
result.getResult().toString(true),
75-
interpreter
76-
);
77-
}
78-
} catch (DeferredValueException | TemplateSyntaxException e) {
79-
try {
80-
return EagerReconstructionUtils.wrapInAutoEscapeIfNeeded(
81-
eagerInterpret(tagNode, interpreter, e),
82-
interpreter
83-
);
84-
} catch (OutputTooBigException e1) {
85-
interpreter.addError(TemplateError.fromOutputTooBigException(e1));
86-
throw new DeferredValueException(
87-
String.format("Output too big for eager execution: %s", e1.getMessage())
88-
);
89-
}
51+
if (
52+
result.getResult().getResolutionState() == ResolutionState.NONE ||
53+
(
54+
!result.getResult().isFullyResolved() &&
55+
!result.getSpeculativeBindings().isEmpty()
56+
)
57+
) {
58+
EagerIfTag.resetBindingsForNextBranch(interpreter, result);
59+
interpreter.getContext().removeDeferredTokens(addedTokens);
60+
throw new DeferredValueException(
61+
result.getResult().getResolutionState() == ResolutionState.NONE
62+
? result.getResult().toString()
63+
: "Modification inside partially evaluated for loop"
64+
);
65+
}
66+
if (result.getResult().isFullyResolved()) {
67+
return result.getResult().toString(true);
68+
} else {
69+
return EagerReconstructionUtils.wrapInChildScope(
70+
result.getResult().toString(true),
71+
interpreter
72+
);
9073
}
9174
}
9275

src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerIfTag.java

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import com.hubspot.jinjava.interpret.DeferredValueException;
55
import com.hubspot.jinjava.interpret.InterpretException;
66
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
7-
import com.hubspot.jinjava.interpret.OutputTooBigException;
8-
import com.hubspot.jinjava.interpret.TemplateError;
97
import com.hubspot.jinjava.interpret.TemplateSyntaxException;
108
import com.hubspot.jinjava.lib.tag.ElseIfTag;
119
import com.hubspot.jinjava.lib.tag.ElseTag;
@@ -33,22 +31,8 @@ public EagerIfTag(IfTag ifTag) {
3331
}
3432

3533
@Override
36-
public String interpret(TagNode tagNode, JinjavaInterpreter interpreter) {
37-
try {
38-
return getTag().interpret(tagNode, interpreter);
39-
} catch (DeferredValueException | TemplateSyntaxException e) {
40-
try {
41-
return EagerReconstructionUtils.wrapInAutoEscapeIfNeeded(
42-
eagerInterpret(tagNode, interpreter, e),
43-
interpreter
44-
);
45-
} catch (OutputTooBigException e1) {
46-
interpreter.addError(TemplateError.fromOutputTooBigException(e1));
47-
throw new DeferredValueException(
48-
String.format("Output too big for eager execution: %s", e1.getMessage())
49-
);
50-
}
51-
}
34+
public String innerInterpret(TagNode tagNode, JinjavaInterpreter interpreter) {
35+
return getTag().interpret(tagNode, interpreter);
5236
}
5337

5438
@Override

src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerIncludeTag.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ public EagerIncludeTag(IncludeTag tag) {
1717
}
1818

1919
@Override
20-
public String interpret(TagNode tagNode, JinjavaInterpreter interpreter) {
20+
public String innerInterpret(TagNode tagNode, JinjavaInterpreter interpreter) {
2121
int numDeferredTokensStart = interpreter.getContext().getDeferredTokens().size();
22-
String output = super.interpret(tagNode, interpreter);
22+
String output = super.innerInterpret(tagNode, interpreter);
2323
if (interpreter.getContext().getDeferredTokens().size() > numDeferredTokensStart) {
2424
HelperStringTokenizer helper = new HelperStringTokenizer(tagNode.getHelpers());
2525
String path = StringUtils.trimToEmpty(helper.next());

src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerStateChangingTag.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public EagerStateChangingTag(T tag) {
1818
}
1919

2020
@Override
21-
public String interpret(TagNode tagNode, JinjavaInterpreter interpreter) {
21+
public String innerInterpret(TagNode tagNode, JinjavaInterpreter interpreter) {
2222
return eagerInterpret(tagNode, interpreter, null);
2323
}
2424

src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerTagDecorator.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import com.hubspot.jinjava.interpret.InterpretException;
77
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
88
import com.hubspot.jinjava.interpret.OutputTooBigException;
9-
import com.hubspot.jinjava.interpret.TemplateError;
109
import com.hubspot.jinjava.interpret.TemplateSyntaxException;
1110
import com.hubspot.jinjava.lib.tag.Tag;
1211
import com.hubspot.jinjava.tree.Node;
@@ -34,24 +33,35 @@ public T getTag() {
3433
}
3534

3635
@Override
37-
public String interpret(TagNode tagNode, JinjavaInterpreter interpreter) {
36+
public final String interpret(TagNode tagNode, JinjavaInterpreter interpreter) {
3837
try {
39-
return tag.interpret(tagNode, interpreter);
40-
} catch (DeferredValueException | TemplateSyntaxException e) {
38+
String output = innerInterpret(tagNode, interpreter);
39+
JinjavaInterpreter.checkOutputSize(output);
40+
return output;
41+
} catch (DeferredValueException | TemplateSyntaxException | OutputTooBigException e) {
4142
try {
4243
return EagerReconstructionUtils.wrapInAutoEscapeIfNeeded(
43-
eagerInterpret(tagNode, interpreter, e),
44+
eagerInterpret(
45+
tagNode,
46+
interpreter,
47+
e instanceof InterpretException
48+
? (InterpretException) e
49+
: new InterpretException("Exception with default render", e)
50+
),
4451
interpreter
4552
);
4653
} catch (OutputTooBigException e1) {
47-
interpreter.addError(TemplateError.fromOutputTooBigException(e1));
4854
throw new DeferredValueException(
4955
String.format("Output too big for eager execution: %s", e1.getMessage())
5056
);
5157
}
5258
}
5359
}
5460

61+
protected String innerInterpret(TagNode tagNode, JinjavaInterpreter interpreter) {
62+
return tag.interpret(tagNode, interpreter);
63+
}
64+
5565
@Override
5666
public String getName() {
5767
return tag.getName();
@@ -166,6 +176,7 @@ public String renderChildren(TagNode tagNode, JinjavaInterpreter interpreter) {
166176
* @return The image of the token which has been evaluated as much as possible.
167177
*/
168178
public final String getEagerImage(Token token, JinjavaInterpreter interpreter) {
179+
interpreter.setLineNumber(token.getLineNumber());
169180
String eagerImage;
170181
if (token instanceof TagToken) {
171182
eagerImage = getEagerTagImage((TagToken) token, interpreter);

src/main/java/com/hubspot/jinjava/objects/serialization/PyishObjectMapper.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@
99
import com.fasterxml.jackson.databind.SerializerProvider;
1010
import com.fasterxml.jackson.databind.module.SimpleModule;
1111
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
12-
import com.hubspot.jinjava.interpret.OutputTooBigException;
1312
import com.hubspot.jinjava.util.WhitespaceUtils;
1413
import java.io.IOException;
1514
import java.util.Objects;
16-
import java.util.Optional;
1715

1816
public class PyishObjectMapper {
1917
public static final ObjectWriter PYISH_OBJECT_WRITER;
@@ -50,13 +48,7 @@ public static String getAsPyishString(Object val) {
5048
public static String getAsPyishStringOrThrow(Object val)
5149
throws JsonProcessingException {
5250
String string = PYISH_OBJECT_WRITER.writeValueAsString(val);
53-
Optional<JinjavaInterpreter> interpreterMaybe = JinjavaInterpreter.getCurrentMaybe();
54-
Optional<Long> maxStringLength = interpreterMaybe
55-
.map(interpreter -> interpreter.getConfig().getMaxStringLength())
56-
.filter(max -> max > 0);
57-
if (maxStringLength.map(max -> string.length() > max).orElse(false)) {
58-
throw new OutputTooBigException(maxStringLength.get(), string.length());
59-
}
51+
JinjavaInterpreter.checkOutputSize(string);
6052
return string;
6153
}
6254

src/main/java/com/hubspot/jinjava/util/EagerExpressionResolver.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.hubspot.jinjava.el.ext.ExtendedParser;
88
import com.hubspot.jinjava.interpret.DeferredValueException;
99
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
10+
import com.hubspot.jinjava.interpret.OutputTooBigException;
1011
import com.hubspot.jinjava.interpret.TemplateSyntaxException;
1112
import com.hubspot.jinjava.interpret.UnknownTokenException;
1213
import com.hubspot.jinjava.objects.serialization.PyishObjectMapper;
@@ -107,7 +108,7 @@ public static String getValueAsJinjavaStringSafe(Object val) {
107108
return pyishString;
108109
}
109110
}
110-
} catch (JsonProcessingException ignored) {}
111+
} catch (JsonProcessingException | OutputTooBigException ignored) {}
111112
throw new DeferredValueException("Can not convert deferred result to string");
112113
}
113114

src/test/java/com/hubspot/jinjava/lib/tag/eager/EagerForTagTest.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,37 @@ public void itHandlesNestedDeferredForLoop() {
8787

8888
@Test
8989
public void itLimitsLength() {
90-
interpreter.render(
90+
String out = interpreter.render(
9191
String.format(
9292
"{%% for item in (range(1000, %s)) + deferred %%}{%% endfor %%}",
9393
MAX_OUTPUT_SIZE
9494
)
9595
);
96-
assertThat(interpreter.getErrors()).hasSize(1);
97-
assertThat(interpreter.getErrors().get(0).getReason())
98-
.isEqualTo(ErrorReason.OUTPUT_TOO_BIG);
96+
assertThat(interpreter.getContext().getDeferredTokens()).hasSize(1);
97+
}
98+
99+
@Test
100+
public void itUsesDeferredExecutionModeWhenChildrenAreLarge() {
101+
assertThat(
102+
interpreter.render(
103+
String.format(
104+
"{%% for item in range(%d) %%}1234567890{%% endfor %%}",
105+
MAX_OUTPUT_SIZE / 10 - 1
106+
)
107+
)
108+
)
109+
.hasSize((int) MAX_OUTPUT_SIZE - 10);
110+
assertThat(interpreter.getContext().getDeferredTokens()).isEmpty();
111+
assertThat(interpreter.getContext().getDeferredNodes()).isEmpty();
112+
assertThat(interpreter.getErrors()).isEmpty();
113+
String tooBigInput = String.format(
114+
"{%% for item in range(%d) %%}1234567890{%% endfor %%}",
115+
MAX_OUTPUT_SIZE / 10 + 1
116+
);
117+
assertThat(interpreter.render(tooBigInput)).isEqualTo(tooBigInput);
118+
assertThat(interpreter.getContext().getDeferredTokens()).hasSize(1);
119+
assertThat(interpreter.getContext().getDeferredNodes()).isEmpty();
120+
assertThat(interpreter.getErrors()).isEmpty();
99121
}
100122

101123
@Test

src/test/java/com/hubspot/jinjava/lib/tag/eager/EagerTagDecoratorTest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,6 @@ public void itLimitsInterpretLength() {
113113
);
114114
assertThatThrownBy(() -> eagerTagDecorator.interpret(tagNode, interpreter))
115115
.isInstanceOf(DeferredValueException.class);
116-
assertThat(interpreter.getErrors()).hasSize(1);
117-
assertThat(interpreter.getErrors().get(0).getReason())
118-
.isEqualTo(ErrorReason.OUTPUT_TOO_BIG);
119116
}
120117

121118
@Test

0 commit comments

Comments
 (0)