Skip to content

Commit d34bc17

Browse files
committed
Fix map entry wrapping with limiting and adjust exceptions
1 parent e05332e commit d34bc17

6 files changed

Lines changed: 64 additions & 11 deletions

File tree

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ public void serialize(
3636
new CharArrayWriter(),
3737
remainingLength
3838
);
39-
objectWriter.writeValue(
40-
new SizeLimitingWriter(new CharArrayWriter(), remainingLength),
41-
entry.getValue()
42-
);
39+
objectWriter.writeValue(sizeLimitingWriter, entry.getValue());
4340
value = sizeLimitingWriter.toString();
4441
} else {
4542
key = PyishObjectMapper.PYISH_OBJECT_WRITER.writeValueAsString(entry.getKey());

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.fasterxml.jackson.databind.module.SimpleModule;
1010
import com.hubspot.jinjava.interpret.DeferredValueException;
1111
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
12+
import com.hubspot.jinjava.interpret.OutputTooBigException;
1213
import com.hubspot.jinjava.util.WhitespaceUtils;
1314
import java.io.CharArrayWriter;
1415
import java.io.IOException;
@@ -48,7 +49,21 @@ public static String getAsPyishString(Object val) {
4849
return getAsPyishStringOrThrow(val);
4950
} catch (IOException e) {
5051
if (e instanceof SizeLimitingJsonProcessingException) {
51-
throw new DeferredValueException(String.format("%s: %s", e.getMessage(), val));
52+
if (
53+
JinjavaInterpreter
54+
.getCurrentMaybe()
55+
.map(
56+
interpreter -> interpreter.getConfig().getExecutionMode().useEagerParser()
57+
)
58+
.orElse(false)
59+
) {
60+
throw new DeferredValueException(String.format("%s: %s", e.getMessage(), val));
61+
} else {
62+
throw new OutputTooBigException(
63+
((SizeLimitingJsonProcessingException) e).getMaxSize(),
64+
((SizeLimitingJsonProcessingException) e).getAttemptedSize()
65+
);
66+
}
5267
}
5368
return Objects.toString(val, "");
5469
}

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,26 @@
33
import com.fasterxml.jackson.core.JsonProcessingException;
44

55
public class SizeLimitingJsonProcessingException extends JsonProcessingException {
6+
private final int maxSize;
7+
private final int attemptedSize;
68

79
protected SizeLimitingJsonProcessingException(int maxSize, int attemptedSize) {
8-
super("Max length of {} chars reached when serializing. {} chars attempted.");
10+
super(
11+
String.format(
12+
"Max length of %d chars reached when serializing. %d chars attempted.",
13+
maxSize,
14+
attemptedSize
15+
)
16+
);
17+
this.maxSize = maxSize;
18+
this.attemptedSize = attemptedSize;
19+
}
20+
21+
public int getAttemptedSize() {
22+
return attemptedSize;
23+
}
24+
25+
public int getMaxSize() {
26+
return maxSize;
927
}
1028
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ public void write(String str, int off, int len)
4343
private void checkMaxSize(int extra) throws SizeLimitingJsonProcessingException {
4444
if (remainingLength.addAndGet(extra * -1) < 0) {
4545
throw new SizeLimitingJsonProcessingException(
46-
charArrayWriter.size() + extra,
47-
startingLength
46+
startingLength,
47+
charArrayWriter.size() + extra
4848
);
4949
}
5050
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22

33
import static org.assertj.core.api.Assertions.assertThat;
44
import static org.assertj.core.api.Assertions.assertThatThrownBy;
5-
import static org.mockito.Mockito.*;
5+
import static org.mockito.Mockito.any;
6+
import static org.mockito.Mockito.mock;
7+
import static org.mockito.Mockito.when;
68

79
import com.hubspot.jinjava.BaseInterpretingTest;
810
import com.hubspot.jinjava.JinjavaConfig;
911
import com.hubspot.jinjava.interpret.DeferredValue;
1012
import com.hubspot.jinjava.interpret.DeferredValueException;
1113
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
1214
import com.hubspot.jinjava.interpret.OutputTooBigException;
13-
import com.hubspot.jinjava.interpret.TemplateError.ErrorReason;
1415
import com.hubspot.jinjava.lib.fn.ELFunctionDefinition;
1516
import com.hubspot.jinjava.lib.tag.Tag;
1617
import com.hubspot.jinjava.mode.EagerExecutionMode;
@@ -124,7 +125,7 @@ public void itLimitsTagLength() {
124125
() ->
125126
eagerTagDecorator.getEagerTagImage((TagToken) tagNode.getMaster(), interpreter)
126127
)
127-
.isInstanceOf(OutputTooBigException.class);
128+
.isInstanceOf(DeferredValueException.class);
128129
}
129130

130131
@Test

src/test/java/com/hubspot/jinjava/objects/serialization/PyishObjectMapperTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
import com.fasterxml.jackson.core.JsonProcessingException;
77
import com.google.common.collect.ImmutableMap;
8+
import com.hubspot.jinjava.Jinjava;
9+
import com.hubspot.jinjava.JinjavaConfig;
10+
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
811
import com.hubspot.jinjava.objects.collections.SizeLimitingPyMap;
912
import java.util.ArrayList;
1013
import java.util.HashMap;
@@ -33,6 +36,25 @@ public void itSerializesMapEntrySet() throws JsonProcessingException {
3336
.isEqualTo("[fn:map_entry('bar', {'foobar': []} ), fn:map_entry('foo', 'bar')]");
3437
}
3538

39+
@Test
40+
public void itSerializesMapEntrySetWithLimit() throws JsonProcessingException {
41+
SizeLimitingPyMap map = new SizeLimitingPyMap(new HashMap<>(), 10);
42+
map.put("foo", "bar");
43+
map.put("bar", ImmutableMap.of("foobar", new ArrayList<>()));
44+
45+
Jinjava jinjava = new Jinjava(
46+
JinjavaConfig.newBuilder().withMaxOutputSize(10000).build()
47+
);
48+
try {
49+
JinjavaInterpreter.pushCurrent(jinjava.newInterpreter());
50+
String result = PyishObjectMapper.getAsPyishString(map.items());
51+
assertThat(result)
52+
.isEqualTo("[fn:map_entry('bar', {'foobar': []} ), fn:map_entry('foo', 'bar')]");
53+
} finally {
54+
JinjavaInterpreter.popCurrent();
55+
}
56+
}
57+
3658
@Test
3759
public void itSerializesMapWithNullValues() {
3860
Map<String, Object> map = new SizeLimitingPyMap(new HashMap<>(), 10);

0 commit comments

Comments
 (0)