You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by vy...@apache.org on 2024/11/18 19:25:01 UTC
(logging-log4j2) branch fix/2.24.x/JTL-StackTraceStringResolver created (now 0061cfe2fa)
This is an automated email from the ASF dual-hosted git repository.
vy pushed a change to branch fix/2.24.x/JTL-StackTraceStringResolver
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
at 0061cfe2fa Simplify line start matching
This branch includes the following new commits:
new f9402ed2f7 Fix off-by-one in `StackTraceStringResolver` (#3194)
new 0061cfe2fa Simplify line start matching
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(logging-log4j2) 01/02: Fix off-by-one in `StackTraceStringResolver` (#3194)
Posted by vy...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
vy pushed a commit to branch fix/2.24.x/JTL-StackTraceStringResolver
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit f9402ed2f72aa0dba6fe6b2f3a796a1e7c16e6fb
Author: Volkan Yazıcı <vo...@yazi.ci>
AuthorDate: Mon Nov 18 09:31:19 2024 +0100
Fix off-by-one in `StackTraceStringResolver` (#3194)
---
.../resolver/StackTraceStringResolverTest.java | 63 ++++++++++++++++++++++
.../json/resolver/StackTraceStringResolver.java | 5 +-
.../3211_fix_JTL_StackTraceStringResolver.xml | 8 +++
3 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolverTest.java b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolverTest.java
index 430d6de646..dd3b371e10 100644
--- a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolverTest.java
+++ b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolverTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.logging.log4j.layout.template.json.resolver;
+import static java.util.Collections.singletonList;
import static org.apache.logging.log4j.layout.template.json.TestHelpers.CONFIGURATION;
import static org.apache.logging.log4j.layout.template.json.TestHelpers.JAVA_BASE_PREFIX;
import static org.apache.logging.log4j.layout.template.json.TestHelpers.asMap;
@@ -40,6 +41,7 @@ import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.layout.template.json.JsonTemplateLayout;
import org.apache.logging.log4j.layout.template.json.JsonTemplateLayoutDefaults;
+import org.apache.logging.log4j.layout.template.json.util.TruncatingBufferedPrintWriter;
import org.apache.logging.log4j.util.Constants;
import org.assertj.core.api.AbstractStringAssert;
import org.junit.jupiter.api.Nested;
@@ -593,6 +595,67 @@ class StackTraceStringResolverTest {
private String matchingRegex(final String string) {
return "[" + string.charAt(0) + "]" + Pattern.quote(string.substring(1));
}
+
+ @Test
+ void should_not_fail_on_truncated_output_not_ending_with_newline() {
+
+ // Try to find an exception whose truncated stack trace does not end with a newline
+ final int maxStringLength = 100;
+ final float maxByteCountPerChar =
+ JsonTemplateLayoutDefaults.getCharset().newEncoder().maxBytesPerChar();
+ final int maxStringByteCount =
+ Math.toIntExact(Math.round(Math.ceil(maxByteCountPerChar * maxStringLength)));
+ final TruncatingBufferedPrintWriter writer = TruncatingBufferedPrintWriter.ofCapacity(maxStringByteCount);
+ Exception exception;
+ String message = "m";
+ do {
+ exception = new Exception(message);
+ exception.printStackTrace(writer);
+ if (writer.truncated() && writer.buffer()[writer.length() - 1] != '\n') {
+ break;
+ }
+ writer.close();
+ message += "m";
+ } while (true);
+
+ // Create the event template
+ final String eventTemplate = writeJson(asMap(
+ "ex",
+ asMap(
+ "$resolver",
+ "exception",
+ "field",
+ "stackTrace",
+ "stackTrace",
+ asMap(
+ "stringified",
+ asMap(
+ "truncation",
+ asMap(
+ "suffix",
+ TRUNCATION_SUFFIX,
+ "pointMatcherStrings",
+ singletonList("this string shouldn't match with anything")))))));
+
+ // Create the layout
+ final JsonTemplateLayout layout = JsonTemplateLayout.newBuilder()
+ .setConfiguration(CONFIGURATION)
+ .setEventTemplate(eventTemplate)
+ .setMaxStringLength(maxStringLength)
+ .setStackTraceEnabled(true)
+ .build();
+
+ // Create the log event
+ final LogEvent logEvent =
+ Log4jLogEvent.newBuilder().setThrown(exception).build();
+
+ // Check the serialized event
+ usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
+ final int expectedStackTraceLength = maxStringLength + TRUNCATION_SUFFIX.length();
+ final String stackTrace = accessor.getString("ex");
+ assertThat(stackTrace).hasSizeLessThan(expectedStackTraceLength);
+ });
+ }
}
@Test
diff --git a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolver.java b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolver.java
index ebd34a3a47..077bf3d359 100644
--- a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolver.java
+++ b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolver.java
@@ -251,13 +251,14 @@ final class StackTraceStringResolver implements StackTraceResolver {
private static int findLineStartIndex(final CharSequence buffer, final int startIndex, final int endIndex) {
char prevChar = '-';
- for (int i = startIndex; i <= endIndex; i++) {
+ int i = startIndex;
+ for (; i < endIndex; i++) {
if (prevChar == '\n') {
return i;
}
prevChar = buffer.charAt(i);
}
- return -1;
+ return prevChar == '\n' ? i : -1;
}
private static int findMatchingIndex(
diff --git a/src/changelog/.2.x.x/3211_fix_JTL_StackTraceStringResolver.xml b/src/changelog/.2.x.x/3211_fix_JTL_StackTraceStringResolver.xml
new file mode 100644
index 0000000000..e28bdbc207
--- /dev/null
+++ b/src/changelog/.2.x.x/3211_fix_JTL_StackTraceStringResolver.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://logging.apache.org/xml/ns"
+ xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
+ type="fixed">
+ <issue id="3211" link="https://github.com/apache/logging-log4j2/pull/3211"/>
+ <description format="asciidoc">Fix `ArrayIndexOutOfBoundsException` in JSON Template Layout truncated exception resolver</description>
+</entry>
(logging-log4j2) 02/02: Simplify line start matching
Posted by vy...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
vy pushed a commit to branch fix/2.24.x/JTL-StackTraceStringResolver
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 0061cfe2faf64a5f575302139a9221065c1faf3b
Author: Volkan Yazıcı <vo...@yazi.ci>
AuthorDate: Mon Nov 18 11:27:04 2024 +0100
Simplify line start matching
---
.../json/resolver/StackTraceStringResolver.java | 28 ++++++++++------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolver.java b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolver.java
index 077bf3d359..7a4634a86f 100644
--- a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolver.java
+++ b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolver.java
@@ -119,7 +119,7 @@ final class StackTraceStringResolver implements StackTraceResolver {
for (; ; ) {
// Find the next label start, if present.
- final int labeledLineStartIndex = findLabeledLineStartIndex(srcWriter, startIndex, srcWriter.length());
+ final int labeledLineStartIndex = findLabeledLineStartIndex(srcWriter, startIndex);
final int endIndex = labeledLineStartIndex >= 0 ? labeledLineStartIndex : srcWriter.length();
// Copy up to the truncation point, if it matches.
@@ -195,26 +195,27 @@ final class StackTraceStringResolver implements StackTraceResolver {
return -1;
}
- private static int findLabeledLineStartIndex(final CharSequence buffer, final int startIndex, final int endIndex) {
+ private static int findLabeledLineStartIndex(final CharSequence buffer, final int startIndex) {
// Note that the index arithmetic in this method is not guarded.
// That is, there are no `Math.addExact()` or `Math.subtractExact()` usages.
// Since we know a priori that we are already operating within buffer limits.
- for (int bufferIndex = startIndex; bufferIndex < endIndex; ) {
+ final int bufferLength = buffer.length();
+ for (int bufferIndex = startIndex; bufferIndex < bufferLength; ) {
// Find the next line start, if exists.
- final int lineStartIndex = findLineStartIndex(buffer, bufferIndex, endIndex);
+ final int lineStartIndex = findLineStartIndex(buffer, bufferIndex);
if (lineStartIndex < 0) {
break;
}
bufferIndex = lineStartIndex;
// Skip tabs.
- while (bufferIndex < endIndex && '\t' == buffer.charAt(bufferIndex)) {
+ while (bufferIndex < bufferLength && '\t' == buffer.charAt(bufferIndex)) {
bufferIndex++;
}
// Search for the `Caused by: ` occurrence.
- if (bufferIndex < (endIndex - 11)
+ if (bufferIndex < (bufferLength - 11)
&& buffer.charAt(bufferIndex) == 'C'
&& buffer.charAt(bufferIndex + 1) == 'a'
&& buffer.charAt(bufferIndex + 2) == 'u'
@@ -230,7 +231,7 @@ final class StackTraceStringResolver implements StackTraceResolver {
}
// Search for the `Suppressed: ` occurrence.
- else if (bufferIndex < (endIndex - 12)
+ else if (bufferIndex < (bufferLength - 12)
&& buffer.charAt(bufferIndex) == 'S'
&& buffer.charAt(bufferIndex + 1) == 'u'
&& buffer.charAt(bufferIndex + 2) == 'p'
@@ -249,16 +250,13 @@ final class StackTraceStringResolver implements StackTraceResolver {
return -1;
}
- private static int findLineStartIndex(final CharSequence buffer, final int startIndex, final int endIndex) {
- char prevChar = '-';
- int i = startIndex;
- for (; i < endIndex; i++) {
- if (prevChar == '\n') {
- return i;
+ private static int findLineStartIndex(final CharSequence buffer, final int startIndex) {
+ for (int bufferIndex = startIndex; bufferIndex < buffer.length(); bufferIndex++) {
+ if (buffer.charAt(bufferIndex) == '\n' && (bufferIndex + 1) < buffer.length()) {
+ return bufferIndex + 1;
}
- prevChar = buffer.charAt(i);
}
- return prevChar == '\n' ? i : -1;
+ return -1;
}
private static int findMatchingIndex(