ppkarwasz opened a new issue, #4343:
URL: https://github.com/apache/logging-log4j2/issues/4343
## Description
`ThrowableAttributeConverter` (`log4j-jpa`) cannot round-trip a `Throwable`
whose message contains line breaks.
`convertToDatabaseColumn` writes `Throwable.toString()` verbatim, one stack
trace frame per line.
`convertToEntityAttribute` splits the column on line breaks and interprets
it by line prefix:
- any line starting with `Caused by ` starts a new cause, whose class is
loaded by name;
- every other line is parsed as a stack trace frame by
`StackTraceElementAttributeConverter`.
Since exception messages are arbitrary text, a message such as
```text
first line
Caused by com.example.SomeClass: second line
```
is read back as a cause of type `com.example.SomeClass`, and other lines
make the frame parser throw.
Moreover, `getThrowable` loads the class with `LoaderUtil.loadClass`, which
**initializes** it
before checking that it is a `Throwable` subclass.
Expected behavior:
1. `convertToDatabaseColumn` escapes line breaks in the message (and
`convertToEntityAttribute` unescapes them),
so the column layout does not depend on the message content.
2. `getThrowable` loads the class without initializing it
(`Class.forName(name, false, loader)`)
and checks `Throwable.class.isAssignableFrom` before instantiating it.
3. A line that cannot be parsed as a stack trace frame does not fail the
whole conversion.
## Configuration
**Version:** 2.26.1 (and `2.x` at `d631e82`)
**Operating system:** any
**JDK:** any
## Logs
A message line that is neither a frame nor a `Caused by ` line makes
`StackTraceElementAttributeConverter.convertString` fail with a
`StringIndexOutOfBoundsException`.
## Reproduction
```java
@Test
void messageWithLineBreaksRoundTrips() {
final ThrowableAttributeConverter converter = new
ThrowableAttributeConverter();
final Throwable original = new IllegalStateException("first line\nCaused
by java.lang.Error: second line");
final Throwable restored =
converter.convertToEntityAttribute(converter.convertToDatabaseColumn(original));
assertThat(restored).isInstanceOf(IllegalStateException.class);
assertThat(restored.getMessage()).isEqualTo(original.getMessage());
assertThat(restored.getCause()).isNull();
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]