Skip to content

Commit

Permalink
Avoid XStream causing illegal access issues for internal JDK collections
Browse files Browse the repository at this point in the history
Relates to: quarkusio#24492
  • Loading branch information
geoand committed Apr 11, 2022
1 parent 4298deb commit 8a78359
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.quarkus.test.junit.internal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import com.thoughtworks.xstream.converters.collections.CollectionConverter;
import com.thoughtworks.xstream.mapper.Mapper;

/**
* A custom List converter that always uses ArrayList for unmarshalling.
* This is probably not semantically correct 100% of the time, but it's likely fine
* for all the cases where we are using marshalling / unmarshalling.
*
* The reason for doing this is to avoid XStream causing illegal access issues
* for internal JDK lists
*/
public class CustomListConverter extends CollectionConverter {

// if we wanted to be 100% sure, we'd list all the List.of methods, but I think it's pretty safe to say
// that the JDK won't add custom implementations for the other classes
private final Set<String> SUPPORTED_CLASS_NAMES = Set.of(
List.of().getClass().getName(),
List.of(new Object()).getClass().getName(),
Arrays.asList(new Object()).getClass().getName(),
Collections.emptyList().getClass().getName());

public CustomListConverter(Mapper mapper) {
super(mapper);
}

@Override
public boolean canConvert(Class type) {
return (type != null) && SUPPORTED_CLASS_NAMES.contains(type.getName());
}

@Override
protected Object createCollection(Class type) {
return new ArrayList<>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.quarkus.test.junit.internal;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import com.thoughtworks.xstream.converters.collections.CollectionConverter;
import com.thoughtworks.xstream.mapper.Mapper;

/**
* A custom Set converter that always uses HashSet for unmarshalling.
* This is probably not semantically correct 100% of the time, but it's likely fine
* for all the cases where we are using marshalling / unmarshalling.
*
* The reason for doing this is to avoid XStream causing illegal access issues
* for internal JDK sets
*/
public class CustomSetConverter extends CollectionConverter {

// if we wanted to be 100% sure, we'd list all the Set.of methods, but I think it's pretty safe to say
// that the JDK won't add custom implementations for the other classes
private final Set<String> SUPPORTED_CLASS_NAMES = Set.of(
Set.of().getClass().getName(),
Set.of(new Object()).getClass().getName(),
Collections.emptySet().getClass().getName());

public CustomSetConverter(Mapper mapper) {
super(mapper);
}

@Override
public boolean canConvert(Class type) {
return (type != null) && SUPPORTED_CLASS_NAMES.contains(type.getName());
}

@Override
protected Object createCollection(Class type) {
return new HashSet<>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ class XStreamDeepClone implements DeepClone {
// avoid doing any work eagerly since the cloner is rarely used
xStreamSupplier = () -> {
XStream result = new XStream();
XStream.setupDefaultSecurity(result);
result.allowTypesByRegExp(new String[] { ".*" });
result.setClassLoader(classLoader);
result.registerConverter(new CustomListConverter(result.getMapper()));
result.registerConverter(new CustomSetConverter(result.getMapper()));
return result;
};
}
Expand Down

0 comments on commit 8a78359

Please sign in to comment.