Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions log4j-1.2-api/src/main/java/org/apache/log4j/Level.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.io.Serializable;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.logging.log4j.util.Strings;
import org.apache.logging.log4j.util.internal.SerializationUtil;

/**
* Defines the minimum set of levels recognized by the system, that is
Expand Down Expand Up @@ -214,6 +215,7 @@ public static Level toLevel(final String sArg, final Level defaultLevel) {
* @throws ClassNotFoundException if class not found.
*/
private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException {
SerializationUtil.assertFiltered(s);
s.defaultReadObject();
level = s.readInt();
syslogEquivalent = s.readInt();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.Collection;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.util.Constants;
import org.apache.logging.log4j.util.FilteredObjectInputStream;

/**
* Utiities for serialization tests.
Expand Down Expand Up @@ -103,11 +108,23 @@ public static void assertStreamEquals(
* @throws Exception thrown on IO or deserialization exception.
*/
public static Object deserializeStream(final String witness) throws Exception {
try (final ObjectInputStream objIs = new ObjectInputStream(new FileInputStream(witness))) {
try (final ObjectInputStream objIs = newObjectInputStream(new FileInputStream(witness))) {
return objIs.readObject();
}
}

private static ObjectInputStream newObjectInputStream(final InputStream in) throws IOException {
if (Constants.JAVA_MAJOR_VERSION == 8) {
// FilteredObjectInputStream's default allow-list covers `org.apache.logging.log4j.` but
// not the `org.apache.log4j.` 1.2-compatibility namespace, so we have to enumerate the
// 1.2 classes that the tests in this module deserialize on Java 8.
final Collection<String> allowedLog4j12Classes =
Arrays.asList("org.apache.log4j.Level", "org.apache.log4j.LevelTest$CustomLevel");
return new FilteredObjectInputStream(in, allowedLog4j12Classes);
}
return new ObjectInputStream(in);
}

/**
* Creates a clone by serializing object and deserializing byte stream.
*
Expand All @@ -123,7 +140,7 @@ public static Object serializeClone(final Object obj) throws IOException, ClassN
}

final ByteArrayInputStream src = new ByteArrayInputStream(memOut.toByteArray());
final ObjectInputStream objIs = new ObjectInputStream(src);
final ObjectInputStream objIs = newObjectInputStream(src);

return objIs.readObject();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import static org.hamcrest.core.IsInstanceOf.any;

import java.io.Serializable;
import org.apache.commons.lang3.SerializationUtils;
import java.util.Collection;
import java.util.Collections;
import org.apache.logging.log4j.test.junit.SerialUtil;
import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;

Expand All @@ -32,10 +34,19 @@
public final class SerializableMatchers {

public static <T extends Serializable> Matcher<T> serializesRoundTrip(final Matcher<T> matcher) {
return serializesRoundTrip(matcher, Collections.emptySet());
}

/**
* Same as {@link #serializesRoundTrip(Matcher)} but extends the default deserialization
* allow-list on Java 8 (see {@link SerialUtil#deserialize(byte[], Collection)}).
*/
public static <T extends Serializable> Matcher<T> serializesRoundTrip(
final Matcher<T> matcher, final Collection<String> allowedExtraClasses) {
return new FeatureMatcher<T, T>(matcher, "serializes round trip", "serializes round trip") {
@Override
protected T featureValueOf(final T actual) {
return SerializationUtils.roundtrip(actual);
return SerialUtil.deserialize(SerialUtil.serialize(actual), allowedExtraClasses);
}
};
}
Expand All @@ -52,5 +63,13 @@ public static Matcher<? super Serializable> serializesRoundTrip() {
return serializesRoundTrip(any(Serializable.class));
}

/**
* Same as {@link #serializesRoundTrip()} but extends the default deserialization allow-list on
* Java 8 (see {@link SerialUtil#deserialize(byte[], Collection)}).
*/
public static Matcher<? super Serializable> serializesRoundTrip(final Collection<String> allowedExtraClasses) {
return serializesRoundTrip(any(Serializable.class), allowedExtraClasses);
}

private SerializableMatchers() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import org.apache.logging.log4j.test.internal.annotation.SuppressFBWarnings;
import org.apache.logging.log4j.util.Constants;
import org.apache.logging.log4j.util.FilteredObjectInputStream;
Expand Down Expand Up @@ -68,11 +70,25 @@ public static byte[] serialize(final Serializable... objs) {
* @param data byte array representing the serialized object
* @return the deserialized object
*/
@SuppressWarnings("unchecked")
@SuppressFBWarnings("OBJECT_DESERIALIZATION")
public static <T> T deserialize(final byte[] data) {
return deserialize(data, Collections.emptySet());
}

/**
* Deserialize an object from the specified byte array using a {@link FilteredObjectInputStream}
* extended with the supplied allow-list (Java 8 only — Java 9+ uses the JVM's serialization
* filter, so the allow-list is ignored).
* @param data byte array representing the serialized object
* @param allowedExtraClasses fully-qualified class names to add to {@link
* FilteredObjectInputStream}'s default allow-list on Java 8
* @return the deserialized object
*/
@SuppressWarnings("unchecked")
@SuppressFBWarnings("OBJECT_DESERIALIZATION")
public static <T> T deserialize(final byte[] data, final Collection<String> allowedExtraClasses) {
try {
final ObjectInputStream ois = getObjectInputStream(data);
final ObjectInputStream ois = getObjectInputStream(data, allowedExtraClasses);
return (T) ois.readObject();
} catch (final Exception ex) {
throw new IllegalStateException("Could not deserialize", ex);
Expand All @@ -86,8 +102,18 @@ public static <T> T deserialize(final byte[] data) {
*/
@SuppressFBWarnings("OBJECT_DESERIALIZATION")
public static ObjectInputStream getObjectInputStream(final byte[] data) throws IOException {
return getObjectInputStream(data, Collections.emptySet());
}

/**
* Creates an {@link ObjectInputStream} adapted to the current Java version, extended with the
* supplied allow-list on Java 8.
*/
@SuppressFBWarnings("OBJECT_DESERIALIZATION")
public static ObjectInputStream getObjectInputStream(
final byte[] data, final Collection<String> allowedExtraClasses) throws IOException {
final ByteArrayInputStream bas = new ByteArrayInputStream(data);
return getObjectInputStream(bas);
return getObjectInputStream(bas, allowedExtraClasses);
}

/**
Expand All @@ -97,8 +123,18 @@ public static ObjectInputStream getObjectInputStream(final byte[] data) throws I
*/
@SuppressFBWarnings("OBJECT_DESERIALIZATION")
public static ObjectInputStream getObjectInputStream(final InputStream stream) throws IOException {
return getObjectInputStream(stream, Collections.emptySet());
}

/**
* Creates an {@link ObjectInputStream} adapted to the current Java version, extended with the
* supplied allow-list on Java 8.
*/
@SuppressFBWarnings("OBJECT_DESERIALIZATION")
public static ObjectInputStream getObjectInputStream(
final InputStream stream, final Collection<String> allowedExtraClasses) throws IOException {
return Constants.JAVA_MAJOR_VERSION == 8
? new FilteredObjectInputStream(stream)
? new FilteredObjectInputStream(stream, allowedExtraClasses)
: new ObjectInputStream(stream);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the license.
*/
@Export
@Version("2.25.3")
@Version("2.26.0")
package org.apache.logging.log4j.test.junit;

import org.osgi.annotation.bundle.Export;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the license.
*/
@Export
@Version("2.25.3")
@Version("2.26.0")
package org.apache.logging.log4j.test;

import org.osgi.annotation.bundle.Export;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Locale;
import org.apache.logging.log4j.test.junit.Mutable;
import org.apache.logging.log4j.test.junit.SerialUtil;
import org.apache.logging.log4j.util.Constants;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.ResourceAccessMode;
Expand Down Expand Up @@ -158,15 +154,9 @@ void testSafeAfterGetFormattedMessageIsCalled() { // LOG4J2-763
}

@Test
void testSerialization() throws IOException, ClassNotFoundException {
void testSerialization() {
final FormattedMessage expected = new FormattedMessage("Msg", "a", "b", "c");
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (final ObjectOutputStream out = new ObjectOutputStream(baos)) {
out.writeObject(expected);
}
final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
final ObjectInputStream in = new ObjectInputStream(bais);
final FormattedMessage actual = (FormattedMessage) in.readObject();
final FormattedMessage actual = SerialUtil.deserialize(SerialUtil.serialize(expected));
assertEquals(expected, actual);
assertEquals(expected.getFormat(), actual.getFormat());
assertEquals(expected.getFormattedMessage(), actual.getFormattedMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.Serializable;
import java.util.Locale;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.logging.log4j.test.junit.Mutable;
import org.apache.logging.log4j.test.junit.SerialUtil;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.ResourceAccessMode;
import org.junit.jupiter.api.parallel.ResourceLock;
Expand All @@ -33,8 +32,8 @@
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
class LocalizedMessageTest {

private <T extends Serializable> T roundtrip(final T msg) {
return SerializationUtils.roundtrip(msg);
private LocalizedMessage roundtrip(final LocalizedMessage msg) {
return SerialUtil.deserialize(SerialUtil.serialize(msg));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.apache.logging.log4j.test.junit.SerialUtil;
import org.junit.jupiter.api.Test;

/**
Expand All @@ -38,4 +39,16 @@ void testGetParameters() {
void testGetThrowable() {
assertNull(OBJECT_ARRAY_MESSAGE.getThrowable());
}

/**
* Round-trips through a filtered stream (see {@link SerialUtil#getObjectInputStream})
* to verify that {@code readObject}'s new {@code SerializationUtil.assertFiltered}
* check accepts streams that carry a filter.
*/
@Test
void testSerializableRoundTripThroughFilteredStream() {
final ObjectArrayMessage original = new ObjectArrayMessage("A", "B", "C");
final ObjectArrayMessage restored = SerialUtil.deserialize(SerialUtil.serialize(original));
assertArrayEquals(original.getParameters(), restored.getParameters());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,9 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Locale;
import org.apache.logging.log4j.test.junit.Mutable;
import org.apache.logging.log4j.test.junit.SerialUtil;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.ResourceAccessMode;
import org.junit.jupiter.api.parallel.ResourceLock;
Expand Down Expand Up @@ -115,15 +111,9 @@ void testSafeAfterGetFormattedMessageIsCalled() { // LOG4J2-763
}

@Test
void testSerialization() throws IOException, ClassNotFoundException {
void testSerialization() {
final StringFormattedMessage expected = new StringFormattedMessage("Msg", "a", "b", "c");
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (final ObjectOutputStream out = new ObjectOutputStream(baos)) {
out.writeObject(expected);
}
final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
final ObjectInputStream in = new ObjectInputStream(bais);
final StringFormattedMessage actual = (StringFormattedMessage) in.readObject();
final StringFormattedMessage actual = SerialUtil.deserialize(SerialUtil.serialize(expected));
assertEquals(expected, actual);
assertEquals(expected.getFormat(), actual.getFormat());
assertEquals(expected.getFormattedMessage(), actual.getFormattedMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Locale;
import org.apache.logging.log4j.util.internal.SerializationUtil;

/**
* Handles messages that contain a format String. Dynamically determines if the format conforms to
Expand Down Expand Up @@ -243,6 +244,7 @@ public int hashCode() {
}

private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
SerializationUtil.assertFiltered(in);
in.defaultReadObject();
formattedMessage = in.readUTF();
messagePattern = in.readUTF();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.internal.SerializationUtil;

/**
* Provides some level of compatibility with Log4j 1.x and convenience but is not the recommended way to Localize
Expand Down Expand Up @@ -283,6 +284,7 @@ private void writeObject(final ObjectOutputStream out) throws IOException {
}

private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
SerializationUtil.assertFiltered(in);
in.defaultReadObject();
formattedMessage = in.readUTF();
key = in.readUTF();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Locale;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.internal.SerializationUtil;

/**
* Handles messages that consist of a format string conforming to java.text.MessageFormat.
Expand Down Expand Up @@ -164,6 +165,7 @@ private void writeObject(final ObjectOutputStream out) throws IOException {
}

private void readObject(final ObjectInputStream in) throws IOException {
SerializationUtil.assertFiltered(in);
parameters = null;
throwable = null;
formattedMessage = in.readUTF();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.ObjectOutputStream;
import java.util.Arrays;
import org.apache.logging.log4j.util.Constants;
import org.apache.logging.log4j.util.internal.SerializationUtil;

/**
* Handles messages that contain an Object[].
Expand Down Expand Up @@ -117,6 +118,7 @@ public int hashCode() {
}

private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
SerializationUtil.assertFiltered(in);
in.defaultReadObject();
array = (Object[]) in.readObject();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.ObjectOutputStream;
import java.util.Objects;
import org.apache.logging.log4j.util.StringBuilderFormattable;
import org.apache.logging.log4j.util.internal.SerializationUtil;

/**
* The simplest possible implementation of Message. It just returns the String given as the constructor argument.
Expand Down Expand Up @@ -152,6 +153,7 @@ private void writeObject(final ObjectOutputStream out) throws IOException {
}

private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
SerializationUtil.assertFiltered(in);
in.defaultReadObject();
charSequence = message;
}
Expand Down
Loading