Skip to content

Commit 521a463

Browse files
committed
#57 Fix out-of-bounds exception thrown while rendering stack traces.
1 parent 6bc9a22 commit 521a463

File tree

5 files changed

+64
-2
lines changed

5 files changed

+64
-2
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
### (2020-??-??) v1.0.2
2+
3+
- Fix `ArrayIndexOutOfBoundsException` thrown when `stackTrace:text` produces
4+
an output violating the truncation limit. (#57)
5+
16
### (2020-01-21) v1.0.1
27

38
- Fix NPE in `StringTruncatingGeneratorDelegate`. (#53)

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ Let us try to answer some common questions:
538538

539539
- [bakomchik](https://github.com/bakomchik)
540540
- [chrissydee](https://github.com/chrissydee)
541+
- [Daniel Lundsgaard Skovenborg](https://github.com/waldeinburg)
541542
- [Eric Schwartz](https://github.com/emschwar)
542543
- [Felix Barnsteiner](https://github.com/felixbarny)
543544
- [Johann Schmitz](https://github.com/ercpe)

layout/src/main/java/com/vlkan/log4j2/logstash/layout/util/BufferedPrintWriter.java

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ public int getCapacity() {
4444
return bufferedWriter.getCapacity();
4545
}
4646

47+
public boolean isOverflow() {
48+
return bufferedWriter.isOverflow();
49+
}
50+
4751
@Override
4852
public void close() {
4953
bufferedWriter.close();

layout/src/main/java/com/vlkan/log4j2/logstash/layout/util/BufferedWriter.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ public final class BufferedWriter extends Writer {
2424

2525
private int position;
2626

27+
private boolean overflow;
28+
2729
BufferedWriter(int capacity) {
2830
this.buffer = new char[capacity];
2931
this.position = 0;
32+
this.overflow = false;
3033
}
3134

3235
char[] getBuffer() {
@@ -41,10 +44,23 @@ int getCapacity() {
4144
return buffer.length;
4245
}
4346

47+
boolean isOverflow() {
48+
return overflow;
49+
}
50+
4451
@Override
4552
public void write(char[] source, int offset, int length) {
46-
System.arraycopy(source, offset, buffer, position, length);
47-
position += length;
53+
if (!overflow) {
54+
int limit = buffer.length - position;
55+
if (length > limit) {
56+
overflow = true;
57+
System.arraycopy(source, offset, buffer, position, limit);
58+
position = buffer.length;
59+
} else {
60+
System.arraycopy(source, offset, buffer, position, length);
61+
position += length;
62+
}
63+
}
4864
}
4965

5066
@Override
@@ -53,6 +69,7 @@ public void flush() {}
5369
@Override
5470
public void close() {
5571
position = 0;
72+
overflow = false;
5673
}
5774

5875
}

layout/src/test/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutTest.java

+35
Original file line numberDiff line numberDiff line change
@@ -1407,4 +1407,39 @@ private static LogEvent createLogEventAtInstant(String formattedInstant) {
14071407
.build();
14081408
}
14091409

1410+
@Test
1411+
public void test_StackTraceTextResolver_with_maxStringLength() throws Exception {
1412+
1413+
// Create the event template.
1414+
ObjectNode eventTemplateRootNode = JSON_NODE_FACTORY.objectNode();
1415+
eventTemplateRootNode.put("stackTrace", "${json:exception:stackTrace:text}");
1416+
String eventTemplate = eventTemplateRootNode.toString();
1417+
1418+
// Create the layout.
1419+
int maxStringLength = eventTemplate.length();
1420+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
1421+
LogstashLayout layout = LogstashLayout
1422+
.newBuilder()
1423+
.setConfiguration(configuration)
1424+
.setEventTemplate(eventTemplate)
1425+
.setMaxStringLength(maxStringLength)
1426+
.setStackTraceEnabled(true)
1427+
.build();
1428+
1429+
// Create the log event.
1430+
SimpleMessage message = new SimpleMessage("foo");
1431+
LogEvent logEvent = Log4jLogEvent
1432+
.newBuilder()
1433+
.setLoggerName(LogstashLayoutTest.class.getSimpleName())
1434+
.setMessage(message)
1435+
.setThrown(NonAsciiUtf8MethodNameContainingException.INSTANCE)
1436+
.build();
1437+
1438+
// Check the serialized event.
1439+
String serializedLogEvent = layout.toSerializable(logEvent);
1440+
JsonNode rootNode = OBJECT_MAPPER.readTree(serializedLogEvent);
1441+
assertThat(point(rootNode, "stackTrace").asText()).isNotBlank();
1442+
1443+
}
1444+
14101445
}

0 commit comments

Comments
 (0)