diff --git a/.travis.settings.xml b/.travis.settings.xml new file mode 100644 index 0000000..440f867 --- /dev/null +++ b/.travis.settings.xml @@ -0,0 +1,9 @@ + + + + central + http://repo1.maven.org/maven2 + * + + + diff --git a/.travis.yml b/.travis.yml index c424514..abdd4aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,32 @@ language: java sudo: false +addons: + apt: + packages: + - openjdk-6-jdk jdk: + - openjdk11 + - openjdk10 + - oraclejdk9 - oraclejdk8 - - oraclejdk7 + - openjdk7 - openjdk6 install: true script: - if ( `javac -version 2>&1 | grep '1\.8\.0' > /dev/null` ); then + if [ "$TRAVIS_JDK_VERSION" == "openjdk6" ]; then + wget https://archive.apache.org/dist/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.zip -P ./target; + unzip -qq ./target/apache-maven-3.2.5-bin.zip -d ./target; + export M2_HOME=$PWD/target/apache-maven-3.2.5; + export PATH=$M2_HOME/bin:$JAVA_HOME/bin:$PATH; + export SETTINGS="-s .travis.settings.xml"; + fi; + if [ "$TRAVIS_JDK_VERSION" == "oraclejdk8" ]; then mkdir -p xstream/profiles/coveralls; mkdir -p xstream-hibernate/profiles/coveralls; - mvn -V -B -e clean package cobertura:cobertura coveralls:report; + mvn -V -B -e clean package jacoco:report coveralls:report; else - mvn -V -B -e clean package; + mvn -V -B -e clean package $SETTINGS; fi cache: - directories: + directories: - $HOME/.m2 diff --git a/README.md b/README.md index a3fa9b3..aeb3044 100644 --- a/README.md +++ b/README.md @@ -14,16 +14,16 @@ ## Documentation Documentation can be found at [GitHub](http://x-stream.github.io). This includes: -* Introduction and tutorial -* JavaDoc -* Change log -* Frequently asked questions +* [Introduction](http://x-stream.github.io) and [Tutorials](http://x-stream.github.io/tutorial.html) +* [JavaDoc](http://x-stream.github.io/javadoc/index.html) +* [Change History](http://x-stream.github.io/changes.html) +* [Frequently Asked Questions](http://x-stream.github.io/faq.html) ## Source The complete source for XStream is bundled in the -src archive. This includes: * Main API [xstream/src/java] -* Unit tests [xstream/src/test] -* Maven build files [pom.xml] -* Hibernate module [xstream-hibernate] -* Web site [xstream-distribution] +* Unit Tests [xstream/src/test] +* Maven Build Files [pom.xml] +* Hibernate Module [xstream-hibernate] +* Website [xstream-distribution] diff --git a/README.txt b/README.txt index 01b7797..85a6f2a 100644 --- a/README.txt +++ b/README.txt @@ -17,20 +17,20 @@ Documentation can be found at http://x-stream.github.io. This includes: - * Introduction and tutorial + * Introduction and Tutorials * JavaDoc - * Change log - * Frequently asked questions + * Change History + * Frequently Asked Questions --[ Source ]------------------------------------------------- The complete source for XStream is bundled in the -src archive. This includes: * Main API [xstream/src/java] - * Unit tests [xstream/src/test] - * Maven build files [pom.xml] - * Hibernate module [xstream-hibernate] - * Web site [xstream-distribution] + * Unit Tests [xstream/src/test] + * Maven Build Files [pom.xml] + * Hibernate Module [xstream-hibernate] + * Website [xstream-distribution] ------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 9addc5b..5c682ad 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ @@ -710,7 +745,7 @@ ${javadoc.xdoclint} ${version.java.source} - ${link.javadoc.javase} + ${javadoc.link.javase} @@ -722,6 +757,11 @@ + + + org.apache.maven.plugins + maven-jxr-plugin + ${version.plugin.maven.jxr} org.apache.maven.plugins @@ -786,7 +826,6 @@ maven-surefire-plugin ${version.plugin.maven.surefire} - ${surefire.argline} once true false @@ -817,23 +856,6 @@ ${version.plugin.mojo.build-helper} - org.codehaus.mojo - cobertura-maven-plugin - ${version.plugin.mojo.cobertura} - - - - clean - - - - - - org.codehaus.mojo - jxr-maven-plugin - ${version.plugin.mojo.jxr} - - org.codehaus.xsite xsite-maven-plugin ${version.plugin.codehaus.xsite} @@ -860,6 +882,11 @@ org.eluder.coveralls coveralls-maven-plugin ${version.plugin.eluder.coveralls} + + + org.jacoco + jacoco-maven-plugin + ${version.plugin.jacoco} @@ -889,13 +916,6 @@ - - - org.apache.maven.wagon - wagon-webdav - ${version.org.apache.maven.wagon.webdev} - - @@ -923,6 +943,7 @@ UTF-8 + 1.5 1.5 1.5 [1.4,) @@ -940,27 +961,29 @@ 2.2 2.2 2.10 + 2.5 2.1 2.2 2.0-beta-6 2.1.2 2.4.3 1.5 - 2.7 - 2.0-beta-1 4.2.0 - - 1.0-beta-2 + 0.8.1 2.2 + 2.2 0.2 1.1 + 1.10 1.4 2.4 1.6.1 2.2.8 3.12.1.GA 1.1.1 + 1.3.2 + 2.3.1 1.0.1 1.6 3.8.1 @@ -972,7 +995,7 @@ 1.1.3 2.0.5 20080701 - 1.19 + 1.21 1.6.1 2.0.8 1.2.0 @@ -983,8 +1006,10 @@ 1.1 1.1.4c - http://docs.oracle.com/javase/8/docs/api/ - + http://docs.oracle.com/javase/8/docs/api/ + permit + + ${surefire.argline} diff --git a/xstream/pom.xml b/xstream/pom.xml index b36bcd4..01fbec4 100644 --- a/xstream/pom.xml +++ b/xstream/pom.xml @@ -1,7 +1,7 @@ xpp3 @@ -105,6 +107,12 @@ javax.activation activation + true + + + javax.xml.bind + jaxb-api + provided @@ -206,12 +214,36 @@ - jdk19-ge - - [9,) - + jdk11-ge + + [11,) + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + javax.xml.bind + jaxb-api + ${version.javax.xml.bind.api} + + + + + - --add-modules java.activation --permit-illegal-access + --illegal-access=${surefire.illegal.access} + + + + jdk9-ge-jdk10 + + [9,11) + + + --add-modules java.activation,java.xml.bind --illegal-access=${surefire.illegal.access} @@ -232,26 +264,40 @@ **/Lambda** **/time/** **/ISO8601JavaTimeConverter.java + **/annotations/* + **/AnnotationMapper* + **/enums/* + **/EnumMapper* + **/*15.java + **/PathConverter.java + **/Base64*Codec.java + **/Types.java + **/JDom2*.java **/Lambda** **/*18TypesTest.java + **/*17TypesTest.java + **/*15TypesTest.java + **/FieldDictionaryTest.java + **/annotations/* + **/enums/* - compile-jdk18 + compile-jdk15 - 1.8 - 1.8 - - foo - foo - foo + ${version.java.5} + ${version.java.5} + + **/Lambda** + **/time/** + **/ISO8601JavaTimeConverter.java - - foo - foo + + **/Lambda** + **/*18TypesTest.java @@ -259,6 +305,19 @@ testCompile + + compile-jdk18 + + 1.8 + 1.8 + + + + + compile + testCompile + + @@ -293,7 +352,7 @@ false 1.8 - ${link.javadoc.javase} + ${javadoc.link.javase} @@ -318,20 +377,30 @@ **/Lambda** **/time/** **/ISO8601JavaTimeConverter.java + **/Base64JavaUtilCodec.java **/Lambda** + **/Base64JavaUtilCodecTest.java **/*18TypesTest.java - - - - - jdk15-16 - - [1.5,1.7) + + org.apache.maven.plugins + maven-javadoc-plugin + + 1.7 + com.thoughtworks.xstream.core.util + + + + + + + jdk16 + + 1.6 @@ -347,10 +416,12 @@ **/extended/PathConverter* **/time/** **/ISO8601JavaTimeConverter.java + **/Base64JavaUtilCodec.java **/Lambda** **/extended/*17Test* + **/Base64JavaUtilCodecTest.java **/acceptance/Extended17TypesTest* **/acceptance/*18TypesTest.java @@ -360,9 +431,44 @@ - jdk15-ge - - [1.5,) + jdk15 + + 1.5 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -XDignore.symbol.file + + + **/Lambda** + **/extended/PathConverter* + **/time/** + **/ISO8601JavaTimeConverter.java + **/Base64JavaUtilCodec.java + **/Base64JAXBCodec.java + + + **/Lambda** + **/extended/*17Test* + **/Base64JavaUtilCodecTest.java + **/Base64JAXBCodecTest.java + **/acceptance/Extended17TypesTest* + **/acceptance/*18TypesTest.java + + + + + + + + jdk16-ge + + [1.6,) @@ -418,9 +524,12 @@ **/enums/* **/time/** **/ISO8601JavaTimeConverter.java + **/Base64JavaUtilCodec.java + **/Base64JAXBCodec.java **/basic/StringBuilder* **/basic/UUID* **/core/util/Types* + **/reflection/*15* **/extended/*15* **/extended/PathConverter* **/io/xml/JDom2* @@ -432,6 +541,8 @@ **/extended/*17Test* **/reflection/SunLimitedUnsafeReflectionProviderTest* **/reflection/PureJavaReflectionProvider15Test* + **/Base64JavaUtilCodecTest.java + **/Base64JAXBCodecTest.java **/io/xml/JDom2*Test* **/acceptance/Basic15TypesTest* **/acceptance/Concurrent15TypesTest* @@ -466,15 +577,23 @@ ${version.plugin.maven.surefire} - org.codehaus.mojo - cobertura-maven-plugin - ${version.plugin.mojo.cobertura} + org.jacoco + jacoco-maven-plugin + ${version.plugin.jacoco} + + + + report + + + !com.thoughtworks.xstream.core.util,com.thoughtworks.xstream.*;-noimport:=true + org.xmlpull.mxp1;resolution:=optional,org.xmlpull.v1;resolution:=optional,* diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java index 0c9c5b9..a088877 100644 --- a/xstream/src/java/com/thoughtworks/xstream/XStream.java +++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -338,7 +338,8 @@ private SecurityMapper securityMapper; private AnnotationConfiguration annotationConfiguration; - private transient boolean insecureWarning; + private transient boolean securityInitialized; + private transient boolean securityWarningGiven; public static final int NO_REFERENCES = 1001; public static final int ID_REFERENCES = 1002; @@ -611,19 +612,19 @@ mapper = new ArrayMapper(mapper); mapper = new DefaultImplementationsMapper(mapper); mapper = new AttributeMapper(mapper, converterLookup, reflectionProvider); - if (JVM.is15()) { + if (JVM.isVersion(5)) { mapper = buildMapperDynamically( "com.thoughtworks.xstream.mapper.EnumMapper", new Class[]{Mapper.class}, new Object[]{mapper}); } mapper = new LocalConversionMapper(mapper); mapper = new ImmutableTypesMapper(mapper); - if (JVM.is18()) { + if (JVM.isVersion(8)) { mapper = buildMapperDynamically("com.thoughtworks.xstream.mapper.LambdaMapper", new Class[]{Mapper.class}, new Object[]{mapper}); } mapper = new SecurityMapper(mapper); - if (JVM.is15()) { + if (JVM.isVersion(5)) { mapper = buildMapperDynamically(ANNOTATION_MAPPER_TYPE, new Class[]{ Mapper.class, ConverterRegistry.class, ConverterLookup.class, ClassLoaderReference.class, ReflectionProvider.class}, new Object[]{ @@ -696,7 +697,7 @@ } addPermission(AnyTypePermission.ANY); - insecureWarning = true; + securityInitialized = false; } /** @@ -711,7 +712,7 @@ * @since 1.4.10 */ public static void setupDefaultSecurity(final XStream xstream) { - if (xstream.insecureWarning) { + if (!xstream.securityInitialized) { xstream.addPermission(NoTypePermission.NONE); xstream.addPermission(NullPermission.NULL); xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); @@ -758,7 +759,7 @@ types.add(JVM.loadClassForName("java.sql.Time")); types.add(JVM.loadClassForName("java.sql.Date")); } - if (JVM.is18()) { + if (JVM.isVersion(8)) { xstream.allowTypeHierarchy(JVM.loadClassForName("java.time.Clock")); types.add(JVM.loadClassForName("java.time.Duration")); types.add(JVM.loadClassForName("java.time.Instant")); @@ -871,7 +872,7 @@ alias("locale", Locale.class); alias("gregorian-calendar", Calendar.class); - if (JVM.is14()) { + if (JVM.isVersion(4)) { aliasDynamically("auth-subject", "javax.security.auth.Subject"); alias("linked-hash-map", JVM.loadClassForName("java.util.LinkedHashMap")); alias("linked-hash-set", JVM.loadClassForName("java.util.LinkedHashSet")); @@ -880,7 +881,7 @@ aliasType("charset", JVM.loadClassForName("java.nio.charset.Charset")); } - if (JVM.is15()) { + if (JVM.isVersion(5)) { aliasDynamically("xml-duration", "javax.xml.datatype.Duration"); alias("concurrent-hash-map", JVM.loadClassForName("java.util.concurrent.ConcurrentHashMap")); alias("enum-set", JVM.loadClassForName("java.util.EnumSet")); @@ -889,11 +890,11 @@ alias("uuid", JVM.loadClassForName("java.util.UUID")); } - if (JVM.is17()) { + if (JVM.isVersion(7)) { aliasType("path", JVM.loadClassForName("java.nio.file.Path")); } - if (JVM.is18()) { + if (JVM.isVersion(8)) { alias("fixed-clock", JVM.loadClassForName("java.time.Clock$FixedClock")); alias("offset-clock", JVM.loadClassForName("java.time.Clock$OffsetClock")); alias("system-clock", JVM.loadClassForName("java.time.Clock$SystemClock")); @@ -1016,7 +1017,7 @@ registerConverter(new LocaleConverter(), PRIORITY_NORMAL); registerConverter(new GregorianCalendarConverter(), PRIORITY_NORMAL); - if (JVM.is14()) { + if (JVM.isVersion(4)) { // late bound converters - allows XStream to be compiled on earlier JDKs registerConverterDynamically( "com.thoughtworks.xstream.converters.extended.SubjectConverter", @@ -1039,7 +1040,7 @@ PRIORITY_NORMAL, null, null); } - if (JVM.is15()) { + if (JVM.isVersion(5)) { // late bound converters - allows XStream to be compiled on earlier JDKs if (JVM.loadClassForName("javax.xml.datatype.Duration") != null) { registerConverterDynamically( @@ -1066,11 +1067,11 @@ registerConverterDynamically("com.thoughtworks.xstream.converters.extended.ActivationDataFlavorConverter", PRIORITY_NORMAL, null, null); } - if (JVM.is17()) { + if (JVM.isVersion(7)) { registerConverterDynamically("com.thoughtworks.xstream.converters.extended.PathConverter", PRIORITY_NORMAL, null, null); } - if (JVM.is18()) { + if (JVM.isVersion(8)) { registerConverterDynamically("com.thoughtworks.xstream.converters.time.ChronologyConverter", PRIORITY_NORMAL, null, null); registerConverterDynamically("com.thoughtworks.xstream.converters.time.DurationConverter", PRIORITY_NORMAL, @@ -1176,7 +1177,7 @@ addImmutableType(File.class, false); addImmutableType(Class.class, false); - if (JVM.is17()) { + if (JVM.isVersion(7)) { Class type = JVM.loadClassForName("java.nio.file.Paths"); if (type != null) { Method methodGet; @@ -1200,13 +1201,13 @@ addImmutableTypeDynamically("java.awt.font.TextAttribute", false); } - if (JVM.is14()) { + if (JVM.isVersion(4)) { // late bound types - allows XStream to be compiled on earlier JDKs addImmutableTypeDynamically("java.nio.charset.Charset", true); addImmutableTypeDynamically("java.util.Currency", true); } - if (JVM.is15()) { + if (JVM.isVersion(5)) { addImmutableTypeDynamically("java.util.UUID", true); } @@ -1215,7 +1216,7 @@ addImmutableType(Collections.EMPTY_SET.getClass(), true); addImmutableType(Collections.EMPTY_MAP.getClass(), true); - if (JVM.is18()) { + if (JVM.isVersion(8)) { addImmutableTypeDynamically("java.time.Duration", false); addImmutableTypeDynamically("java.time.Instant", false); addImmutableTypeDynamically("java.time.LocalDate", false); @@ -1479,8 +1480,8 @@ */ public Object unmarshal(HierarchicalStreamReader reader, Object root, DataHolder dataHolder) { try { - if (insecureWarning) { - insecureWarning = false; + if (!securityInitialized && !securityWarningGiven) { + securityWarningGiven = true; System.err.println("Security framework of XStream not initialized, XStream is probably vulnerable."); } return marshallingStrategy.unmarshal( @@ -2359,7 +2360,7 @@ */ public void addPermission(TypePermission permission) { if (securityMapper != null) { - insecureWarning &= permission != NoTypePermission.NONE; + securityInitialized = true; securityMapper.addPermission(permission); } } @@ -2510,6 +2511,11 @@ denyPermission(new WildcardTypePermission(patterns)); } + private Object readResolve() { + securityWarningGiven = true; + return this; + } + /** * @deprecated As of 1.3, use {@link com.thoughtworks.xstream.InitializationException} * instead @@ -2538,7 +2544,7 @@ public boolean canConvert(final Class type) { return (type == void.class || type == Void.class) - || (insecureWarning + || (!securityInitialized && type != null && (type.getName().equals("java.beans.EventHandler") || type.getName().endsWith("$LazyIterator") diff --git a/xstream/src/java/com/thoughtworks/xstream/XStreamer.java b/xstream/src/java/com/thoughtworks/xstream/XStreamer.java index f950062..a4245a1 100644 --- a/xstream/src/java/com/thoughtworks/xstream/XStreamer.java +++ b/xstream/src/java/com/thoughtworks/xstream/XStreamer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2014, 2016, 2017 XStream Committers. + * Copyright (C) 2006, 2007, 2014, 2016, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -36,7 +36,6 @@ import com.thoughtworks.xstream.io.naming.NameCoder; import com.thoughtworks.xstream.io.xml.XppDriver; import com.thoughtworks.xstream.mapper.Mapper; -import com.thoughtworks.xstream.security.AnyTypePermission; import com.thoughtworks.xstream.security.TypeHierarchyPermission; import com.thoughtworks.xstream.security.TypePermission; import com.thoughtworks.xstream.security.WildcardTypePermission; @@ -252,7 +251,7 @@ */ public Object fromXML(final HierarchicalStreamDriver driver, final Reader xml) throws IOException, ClassNotFoundException { - return fromXML(driver, xml, new TypePermission[]{AnyTypePermission.ANY}); + return fromXML(driver, xml, PERMISSIONS); } /** diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java index 57a2014..4b1430e 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -22,7 +22,7 @@ public class BigDecimalConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(BigDecimal.class); + return type == BigDecimal.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java index e3113ed..e27dc27 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -21,7 +21,7 @@ public class BigIntegerConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(BigInteger.class); + return type == BigInteger.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/BooleanConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BooleanConverter.java index 7afb03b..5b1d982 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/BooleanConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BooleanConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004 Joe Walnes. - * Copyright (C) 2006, 2007, 2014 XStream Committers. + * Copyright (C) 2006, 2007, 2014, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -22,9 +22,7 @@ public class BooleanConverter extends AbstractSingleValueConverter { public static final BooleanConverter TRUE_FALSE = new BooleanConverter("true", "false", false); - public static final BooleanConverter YES_NO = new BooleanConverter("yes", "no", false); - public static final BooleanConverter BINARY = new BooleanConverter("1", "0", true); private final String positive; @@ -49,7 +47,7 @@ } public boolean canConvert(final Class type) { - return type.equals(boolean.class) || type.equals(Boolean.class); + return type == boolean.class || type == Boolean.class; } public Object fromString(final String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/ByteConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/ByteConverter.java index 46b168a..d059352 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/ByteConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/ByteConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -20,7 +20,7 @@ public class ByteConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(byte.class) || type.equals(Byte.class); + return type == byte.class || type == Byte.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/CharConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/CharConverter.java index 4f93310..0e10567 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/CharConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/CharConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -28,7 +28,7 @@ public class CharConverter implements Converter, SingleValueConverter { public boolean canConvert(Class type) { - return type.equals(char.class) || type.equals(Character.class); + return type == char.class || type == Character.class; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/DateConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/DateConverter.java index 5f0bffa..58c0521 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/DateConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/DateConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -201,7 +201,7 @@ } public boolean canConvert(Class type) { - return type.equals(Date.class); + return type == Date.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/DoubleConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/DoubleConverter.java index 1c5b6e3..e47cfab 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/DoubleConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/DoubleConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -20,7 +20,7 @@ public class DoubleConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(double.class) || type.equals(Double.class); + return type == double.class || type == Double.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/FloatConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/FloatConverter.java index 66a486f..ea045f4 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/FloatConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/FloatConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -20,7 +20,7 @@ public class FloatConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(float.class) || type.equals(Float.class); + return type == float.class || type == Float.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/IntConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/IntConverter.java index cc28fcd..49086a6 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/IntConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/IntConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2014, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -20,7 +20,7 @@ public class IntConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(int.class) || type.equals(Integer.class); + return type == int.class || type == Integer.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/LongConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/LongConverter.java index 88771f1..ac44dd6 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/LongConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/LongConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004 Joe Walnes. - * Copyright (C) 2006, 2007, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -19,7 +19,7 @@ public class LongConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(long.class) || type.equals(Long.class); + return type == long.class || type == Long.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/ShortConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/ShortConverter.java index df9c851..b8d11da 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/ShortConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/ShortConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -20,7 +20,7 @@ public class ShortConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(short.class) || type.equals(Short.class); + return type == short.class || type == Short.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java index 4bdaaab..1409a8f 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -23,6 +23,6 @@ } public boolean canConvert(Class type) { - return type.equals(StringBuffer.class); + return type == StringBuffer.class; } } diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBuilderConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBuilderConverter.java index d1557af..2262c0d 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBuilderConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBuilderConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 XStream Committers. + * Copyright (C) 2008, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -22,6 +22,6 @@ } public boolean canConvert(Class type) { - return type.equals(StringBuilder.class); + return type == StringBuilder.class; } } diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringConverter.java index 7ee0437..78a442b 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2011 XStream Committers. + * Copyright (C) 2006, 2007, 2011, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -81,7 +81,7 @@ } public boolean canConvert(final Class type) { - return type.equals(String.class); + return type == String.class; } public Object fromString(final String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/URIConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/URIConverter.java index 0661efd..5b31cc0 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/URIConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/URIConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 XStream Committers. + * Copyright (C) 2010, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -24,7 +24,7 @@ public class URIConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(URI.class); + return type == URI.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/URLConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/URLConverter.java index 8aee562..2d81897 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/URLConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/URLConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -24,7 +24,7 @@ public class URLConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(URL.class); + return type == URL.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/UUIDConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/UUIDConverter.java index a1d69d8..360070a 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/basic/UUIDConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/UUIDConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 XStream Committers. + * Copyright (C) 2008, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -23,7 +23,7 @@ public class UUIDConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(UUID.class); + return type == UUID.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java index a7e46d1..a9043ea 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -51,26 +51,102 @@ public abstract Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context); - - + /** + * @deprecated As of 1.4.11 use {@link #writeCompleteItem(Object, MarshallingContext, HierarchicalStreamWriter)} + * instead. + */ protected void writeItem(Object item, MarshallingContext context, HierarchicalStreamWriter writer) { // PUBLISHED API METHOD! If changing signature, ensure backwards compatibility. if (item == null) { // todo: this is duplicated in TreeMarshaller.start() - String name = mapper().serializedClass(null); - ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, Mapper.Null.class); - writer.endNode(); + writeNullItem(context, writer); } else { String name = mapper().serializedClass(item.getClass()); ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, item.getClass()); - context.convertAnother(item); + writeBareItem(item, context, writer); writer.endNode(); } } - protected Object readItem(HierarchicalStreamReader reader, UnmarshallingContext context, Object current) { + /** + * Write an item of the collection into the writer including surrounding tags. + * + * @param item the item to write + * @param context the current marshalling context + * @param writer the target writer + * @since 1.4.11 + */ + protected void writeCompleteItem(final Object item, final MarshallingContext context, + final HierarchicalStreamWriter writer) { + writeItem(item, context, writer); + } + + /** + * Write the bare item of the collection into the writer. + * + * @param item the item to write + * @param context the current marshalling context + * @param writer the target writer + * @since 1.4.11 + */ + protected void writeBareItem(final Object item, final MarshallingContext context, + final HierarchicalStreamWriter writer) { + context.convertAnother(item); + } + + /** + * Write a null item of the collection into the writer. The method readItem should be able to process the written + * data i.e. it has to write the tags or may not write anything at all. + * + * @param context the current marshalling context + * @param writer the target writer + * @since 1.4.11 + */ + protected void writeNullItem(final MarshallingContext context, final HierarchicalStreamWriter writer) { + final String name = mapper().serializedClass(null); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, Mapper.Null.class); + writer.endNode(); + } + + /** + * @deprecated As of 1.4.11 use {@link #readBareItem(HierarchicalStreamReader, UnmarshallingContext, Object)} or + * {@link #readCompleteItem(HierarchicalStreamReader, UnmarshallingContext, Object)} instead. + */ + protected Object readItem(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Object current) { + return readBareItem(reader, context, current); + } + + /** + * Read a bare item of the collection from the reader. + * + * @param reader the source reader + * @param context the unmarshalling context + * @param current the target collection (if already available) + * @return the read item + * @since 1.4.11 + */ + protected Object readBareItem(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Object current) { Class type = HierarchicalStreams.readClassType(reader, mapper()); return context.convertAnother(current, type); + } + + /** + * Read an item of the collection including the tags from the reader. + * + * @param reader the source reader + * @param context the unmarshalling context + * @param current the target collection (if already available) + * @return the read item + * @since 1.4.11 + */ + protected Object readCompleteItem(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Object current) { + reader.moveDown(); + final Object result = readItem(reader, context, current); + reader.moveUp(); + return result; } protected Object createCollection(Class type) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/ArrayConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/ArrayConverter.java index 25da0ce..a07b06f 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/collections/ArrayConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/ArrayConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -35,14 +35,14 @@ } public boolean canConvert(Class type) { - return type.isArray(); + return type != null && type.isArray(); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { int length = Array.getLength(source); for (int i = 0; i < length; i++) { - Object item = Array.get(source, i); - writeItem(item, context, writer); + final Object item = Array.get(source, i); + writeCompleteItem(item, context, writer); } } @@ -51,10 +51,8 @@ // read the items from xml into a list List items = new ArrayList(); while (reader.hasMoreChildren()) { - reader.moveDown(); - Object item = readItem(reader, context, null); // TODO: arg, what should replace null? + final Object item = readCompleteItem(reader, context, null); // TODO: arg, what should replace null? items.add(item); - reader.moveUp(); } // now convertAnother the list into an array // (this has to be done as a separate list as the array size is not diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/BitSetConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/BitSetConverter.java index 627ba8c..9ccebc0 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/collections/BitSetConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/BitSetConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -29,7 +29,7 @@ public class BitSetConverter implements Converter { public boolean canConvert(Class type) { - return type.equals(BitSet.class); + return type == BitSet.class; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java index 62e8332..7e76674 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -26,7 +26,7 @@ public class CharArrayConverter implements Converter { public boolean canConvert(Class type) { - return type.isArray() && type.getComponentType().equals(char.class); + return type != null && type.isArray() && type.getComponentType().equals(char.class); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java index 4c7e90d..9447419 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -13,7 +13,6 @@ import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; -import com.thoughtworks.xstream.core.JVM; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.mapper.Mapper; @@ -22,6 +21,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.Vector; @@ -64,14 +64,14 @@ || type.equals(HashSet.class) || type.equals(LinkedList.class) || type.equals(Vector.class) - || (JVM.is14() && type.getName().equals("java.util.LinkedHashSet")); + || type.equals(LinkedHashSet.class); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { Collection collection = (Collection) source; for (Iterator iterator = collection.iterator(); iterator.hasNext();) { Object item = iterator.next(); - writeItem(item, context, writer); + writeCompleteItem(item, context, writer); } } @@ -95,7 +95,7 @@ protected void addCurrentElementToCollection(HierarchicalStreamReader reader, UnmarshallingContext context, Collection collection, Collection target) { - Object item = readItem(reader, context, collection); + final Object item = readItem(reader, context, collection); // call readBareItem when deprecated method is removed target.add(item); } diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java index dccaca7..af007f9 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -75,8 +75,8 @@ Map.Entry entry = (Map.Entry) iterator.next(); ExtendedHierarchicalStreamWriterHelper.startNode(writer, entryName, entry.getClass()); - writeItem(entry.getKey(), context, writer); - writeItem(entry.getValue(), context, writer); + writeCompleteItem(entry.getKey(), context, writer); + writeCompleteItem(entry.getValue(), context, writer); writer.endNode(); } @@ -102,14 +102,8 @@ protected void putCurrentEntryIntoMap(HierarchicalStreamReader reader, UnmarshallingContext context, Map map, Map target) { - reader.moveDown(); - Object key = readItem(reader, context, map); - reader.moveUp(); - - reader.moveDown(); - Object value = readItem(reader, context, map); - reader.moveUp(); - + final Object key = readCompleteItem(reader, context, map); + final Object value = readCompleteItem(reader, context, map); target.put(key, value); } diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonCollectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonCollectionConverter.java index c56bc90..ba8c502 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonCollectionConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonCollectionConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 XStream Committers. + * Copyright (C) 2011, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -47,9 +47,7 @@ } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - reader.moveDown(); - Object item = readItem(reader, context, null); - reader.moveUp(); + final Object item = readCompleteItem(reader, context, null); return context.getRequiredType() == LIST ? (Object)Collections.singletonList(item) : (Object)Collections.singleton(item); diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonMapConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonMapConverter.java index 5656374..a9b26e6 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonMapConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonMapConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 XStream Committers. + * Copyright (C) 2011, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -46,13 +46,8 @@ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { reader.moveDown(); - reader.moveDown(); - Object key = readItem(reader, context, null); - reader.moveUp(); - - reader.moveDown(); - Object value = readItem(reader, context, null); - reader.moveUp(); + final Object key = readCompleteItem(reader, context, null); + final Object value = readCompleteItem(reader, context, null); reader.moveUp(); return Collections.singletonMap(key, value); diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java index 30a5c51..c41eae4 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -74,7 +74,7 @@ TreeMap result = comparatorField != null ? new TreeMap() : null; final Comparator comparator = unmarshalComparator(reader, context, result); if (result == null) { - result = comparator == null ? new TreeMap() : new TreeMap(comparator); + result = comparator == null || comparator == NULL_MARKER ? new TreeMap() : new TreeMap(comparator); } populateTreeMap(reader, context, result, comparator); return result; diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java index d22815c..137d8fc 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2014, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2014, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -150,7 +150,7 @@ protected void putCurrentEntryIntoMap(HierarchicalStreamReader reader, UnmarshallingContext context, Map map, Map target) { - Object key = readItem(reader, context, map); + final Object key = readItem(reader, context, map); // call readBareItem when deprecated method is removed target.put(key, key); } }; diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumConverter.java index 4b4a2ba..fd4fc42 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2009, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2009, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -31,7 +31,7 @@ public class EnumConverter implements Converter { public boolean canConvert(Class type) { - return type.isEnum() || Enum.class.isAssignableFrom(type); + return type != null && type.isEnum() || Enum.class.isAssignableFrom(type); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java index 2d39908..4bde13e 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -47,7 +47,7 @@ } public boolean canConvert(Class type) { - return typeField != null && EnumSet.class.isAssignableFrom(type); + return typeField != null && type != null && EnumSet.class.isAssignableFrom(type); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSingleValueConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSingleValueConverter.java index eb668a2..5dad317 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSingleValueConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSingleValueConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009, 2010, 2013 XStream Committers. + * Copyright (C) 2008, 2009, 2010, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -33,7 +33,7 @@ @Override public boolean canConvert(Class type) { - return enumType.isAssignableFrom(type); + return type != null && enumType.isAssignableFrom(type); } @Override diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java index 6a4e048..dbefce2 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013, 2016 XStream Committers. + * Copyright (C) 2013, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -78,7 +78,7 @@ @Override public boolean canConvert(Class type) { - return enumType.isAssignableFrom(type); + return type != null && enumType.isAssignableFrom(type); } @Override diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/CharsetConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/CharsetConverter.java index ca90bd1..dce3e28 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/CharsetConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/CharsetConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -23,7 +23,7 @@ public class CharsetConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return Charset.class.isAssignableFrom(type); + return type != null && Charset.class.isAssignableFrom(type); } public String toString(Object obj) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ColorConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ColorConverter.java index f7de926..93b2f65 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ColorConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ColorConverter.java @@ -33,7 +33,7 @@ public boolean canConvert(Class type) { // String comparison is used here because Color.class loads the class which in turns instantiates AWT, // which is nasty if you don't want it. - return type.getName().equals("java.awt.Color"); + return type != null && type.getName().equals("java.awt.Color"); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java index 1609f49..ffa83db 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -25,7 +25,7 @@ public class CurrencyConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(Currency.class); + return type == Currency.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/DurationConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/DurationConverter.java index e7f906d..dafffd1 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/DurationConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/DurationConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2011 XStream Committers. + * Copyright (C) 2007, 2008, 2011, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -48,8 +48,8 @@ this.factory = factory; } - public boolean canConvert(Class c) { - return factory != null && Duration.class.isAssignableFrom(c); + public boolean canConvert(Class type) { + return factory != null && type != null && Duration.class.isAssignableFrom(type); } public Object fromString(String s) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java index 9700c9a..94564b1 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2010, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2010, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -72,7 +72,7 @@ } public boolean canConvert(Class type) { - return type.equals(DynamicProxyMapper.DynamicProxy.class) || Proxy.isProxyClass(type); + return type != null && (type.equals(DynamicProxyMapper.DynamicProxy.class) || Proxy.isProxyClass(type)); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java index 6eb815d..eeaec6c 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java @@ -1,12 +1,12 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007, 2010 XStream Committers. + * Copyright (C) 2006, 2007, 2010, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD * style license a copy of which has been included with this distribution in * the LICENSE.txt file. - * + * * Created on 03. March 2004 by Joe Walnes */ package com.thoughtworks.xstream.converters.extended; @@ -16,7 +16,8 @@ import com.thoughtworks.xstream.converters.SingleValueConverter; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.converters.basic.ByteConverter; -import com.thoughtworks.xstream.core.util.Base64Encoder; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.StringCodec; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; @@ -25,18 +26,35 @@ import java.util.List; /** - * Converts a byte array to a single Base64 encoding string. + * Converts a byte array by default to a single Base64 encoding string. * * @author Joe Walnes * @author Jörg Schaible */ public class EncodedByteArrayConverter implements Converter, SingleValueConverter { - private static final Base64Encoder base64 = new Base64Encoder(); private static final ByteConverter byteConverter = new ByteConverter(); + private final StringCodec codec; + + /** + * Constructs an EncodedByteArrayConverter. Initializes the converter with a Base64 codec. + */ + public EncodedByteArrayConverter() { + this(JVM.getBase64Codec()); + } + + /** + * Constructs an EncodedByteArrayConverter with a provided string codec. + * + * @param stringCodec the codec to encode and decode the data as string + * @since 1.4.11 + */ + public EncodedByteArrayConverter(final StringCodec stringCodec) { + codec = stringCodec; + } public boolean canConvert(Class type) { - return type.isArray() && type.getComponentType().equals(byte.class); + return type != null && type.isArray() && type.getComponentType().equals(byte.class); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { @@ -73,11 +91,11 @@ return result; } - public String toString(Object obj) { - return base64.encode((byte[]) obj); + public String toString(final Object obj) { + return codec.encode((byte[])obj); } - public Object fromString(String str) { - return base64.decode(str); + public Object fromString(final String str) { + return codec.decode(str); } } diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/FileConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/FileConverter.java index 6003465..ff7e85c 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/FileConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/FileConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -24,7 +24,7 @@ public class FileConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(File.class); + return type == File.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java index c1703d8..e97d660 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -60,7 +60,8 @@ public boolean canConvert(Class type) { // String comparison is used here because Font.class loads the class which in turns instantiates AWT, // which is nasty if you don't want it. - return type.getName().equals("java.awt.Font") || type.getName().equals("javax.swing.plaf.FontUIResource"); + return type != null + && (type.getName().equals("java.awt.Font") || type.getName().equals("javax.swing.plaf.FontUIResource")); } public void marshal(Object source, HierarchicalStreamWriter writer, @@ -113,7 +114,7 @@ } else { attributes = Collections.EMPTY_MAP; } - if (!JVM.is16()) { + if (!JVM.isVersion(6)) { for (Iterator iter = attributes.values().iterator(); iter.hasNext(); ) { if (iter.next() == null) { iter.remove(); diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java index f8ed612..e2945fe 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java @@ -32,7 +32,7 @@ public class GregorianCalendarConverter implements Converter { public boolean canConvert(Class type) { - return type.equals(GregorianCalendar.class); + return type == GregorianCalendar.class; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java index 60109f7..075453d 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2017 XStream Committers. + * Copyright (C) 2006, 2007, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -29,7 +29,7 @@ private final ISO8601GregorianCalendarConverter converter = new ISO8601GregorianCalendarConverter(); public boolean canConvert(Class type) { - return type.equals(Date.class) && converter.canConvert(GregorianCalendar.class); + return type == Date.class && converter.canConvert(GregorianCalendar.class); } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java index 8fe14e9..301d7a7 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2011, 2013, 2014, 2015, 2016, 2017 XStream Committers. + * Copyright (C) 2006, 2007, 2011, 2013, 2014, 2015, 2016, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -35,7 +35,7 @@ public ISO8601GregorianCalendarConverter() { SingleValueConverter svConverter = null; - final Class type = JVM.loadClassForName(JVM.is18() + final Class type = JVM.loadClassForName(JVM.isVersion(8) ? "com.thoughtworks.xstream.core.util.ISO8601JavaTimeConverter" : "com.thoughtworks.xstream.core.util.ISO8601JodaTimeConverter"); try { @@ -54,7 +54,7 @@ } public boolean canConvert(final Class type) { - return converter != null && type.equals(GregorianCalendar.class); + return converter != null && type == GregorianCalendar.class; } public Object fromString(final String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java index b1367a4..b7d36e1 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2017 XStream Committers. + * Copyright (C) 2006, 2007, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -27,7 +27,7 @@ private final static String PADDING = "000000000"; public boolean canConvert(Class type) { - return type.equals(Timestamp.class) && super.canConvert(Date.class); + return type == Timestamp.class && super.canConvert(Date.class); } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaFieldConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaFieldConverter.java index 793a872..d6512df 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaFieldConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaFieldConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2013 XStream Committers. + * Copyright (C) 2009, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -61,7 +61,7 @@ } public boolean canConvert(Class type) { - return type.equals(Field.class); + return type == Field.class; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java index b91d2e9..33de8eb 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2009, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2009, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -61,7 +61,7 @@ } public boolean canConvert(Class type) { - return type.equals(Method.class) || type.equals(Constructor.class); + return type == Method.class || type == Constructor.class; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/LocaleConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/LocaleConverter.java index bcd9f83..13e6c55 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/LocaleConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/LocaleConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -24,7 +24,7 @@ public class LocaleConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(Locale.class); + return type == Locale.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/LookAndFeelConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/LookAndFeelConverter.java index 2315a33..290d5c5 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/LookAndFeelConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/LookAndFeelConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2013 XStream Committers. + * Copyright (C) 2007, 2008, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -41,6 +41,6 @@ } public boolean canConvert(Class type) { - return LookAndFeel.class.isAssignableFrom(type) && canAccess(type); + return type != null && LookAndFeel.class.isAssignableFrom(type) && canAccess(type); } } diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java index 3e5b798..3ba04c0 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 XStream Committers. + * Copyright (C) 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -62,8 +62,17 @@ this.type = itemType; } + protected void writeCompleteItem(final Object item, final MarshallingContext context, + final HierarchicalStreamWriter writer) { + writeItem(item, context, writer); + } + + /** + * @deprecated As of 1.4.11 use {@link #writeCompleteItem(Object, MarshallingContext, HierarchicalStreamWriter)} + * instead. + */ protected void writeItem(Object item, MarshallingContext context, HierarchicalStreamWriter writer) { - Class itemType = item == null ? Mapper.Null.class : item.getClass(); + final Class itemType = item == null ? Mapper.Null.class : item.getClass(); ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, itemType); if (!itemType.equals(type)) { String attributeName = mapper().aliasForSystemAttribute("class"); @@ -77,9 +86,10 @@ writer.endNode(); } - protected Object readItem(HierarchicalStreamReader reader, UnmarshallingContext context, Object current) { - String className = HierarchicalStreams.readClassAttribute(reader, mapper()); - Class itemType = className == null ? type : mapper().realClass(className); + protected Object readBareItem(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Object current) { + final String className = HierarchicalStreams.readClassAttribute(reader, mapper()); + final Class itemType = className == null ? type : mapper().realClass(className); if (Mapper.Null.class.equals(itemType)) { return null; } else { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java index b6fda6e..4c5ec9c 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013, 2016 XStream Committers. + * Copyright (C) 2013, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -208,7 +208,7 @@ this.keyAsAttribute = keyAsAttribute; this.valueAsAttribute = valueAsAttribute; this.lookup = lookup; - enumMapper = JVM.is15() ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null; + enumMapper = JVM.isVersion(5) ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null; if (keyType == null || valueType == null) { throw new IllegalArgumentException("Class types of key and value are mandatory"); diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/PathConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/PathConverter.java index 68fc400..b61ae4e 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/PathConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/PathConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 XStream Committers. + * Copyright (C) 2016, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -14,9 +14,11 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.file.FileSystems; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; +import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; @@ -30,20 +32,24 @@ @Override public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { - return Path.class.isAssignableFrom(type); + return type != null && Path.class.isAssignableFrom(type); } @Override public Path fromString(final String str) { try { - final URI uri = new URI(str); - if (uri.getScheme() == null) { + try { + final URI uri = new URI(str); + if (uri.getScheme() == null || uri.getScheme().length() == 1) { + return Paths.get(File.separatorChar != '/' ? str.replace('/', File.separatorChar) : str); + } else { + return Paths.get(uri); + } + } catch (final URISyntaxException e) { return Paths.get(str); - } else { - return Paths.get(uri); } - } catch (final URISyntaxException e) { - return Paths.get(str); + } catch (final InvalidPathException e) { + throw new ConversionException(e); } } diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java index 3bed0f6..3b0c238 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -40,7 +40,7 @@ } public boolean canConvert(final Class type) { - return type.equals(Pattern.class); + return type == Pattern.class; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java index f5d8e7f..6ee5bf1 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -23,7 +23,7 @@ public class SqlDateConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(Date.class); + return type == Date.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java index 3315f23..c8cee8b 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -23,7 +23,7 @@ public class SqlTimeConverter extends AbstractSingleValueConverter { public boolean canConvert(Class type) { - return type.equals(Time.class); + return type == Time.class; } public Object fromString(String str) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java index 533f774..78feb4b 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2003, 2004 Joe Walnes. - * Copyright (C) 2006, 2007, 2012, 2014, 2016, 2017 XStream Committers. + * Copyright (C) 2006, 2007, 2012, 2014, 2016, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -53,7 +53,7 @@ } public boolean canConvert(Class type) { - return type.equals(Timestamp.class); + return type == Timestamp.class; } public String toString(final Object obj) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java index c56b9e3..b7271da 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -36,7 +36,7 @@ private static final StackTraceElementFactory FACTORY; static { StackTraceElementFactory factory = null; - if (JVM.is15()) { + if (JVM.isVersion(5)) { Class factoryType = JVM.loadClassForName( "com.thoughtworks.xstream.converters.extended.StackTraceElementFactory15", false); diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SubjectConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SubjectConverter.java index bbb5890..a1e9e7b 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SubjectConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SubjectConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -39,7 +39,7 @@ } public boolean canConvert(Class type) { - return type.equals(Subject.class); + return type == Subject.class; } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { @@ -54,7 +54,7 @@ writer.startNode("principals"); for (final Iterator iter = principals.iterator(); iter.hasNext();) { final Object principal = iter.next(); // pre jdk 1.4 a Principal was also in javax.security - writeItem(principal, context, writer); + writeCompleteItem(principal, context, writer); } writer.endNode(); }; @@ -102,10 +102,8 @@ Set set = new HashSet(); reader.moveDown(); while (reader.hasMoreChildren()) { - reader.moveDown(); - Object elementl = readItem(reader, context, set); - reader.moveUp(); - set.add(elementl); + final Object principal = readCompleteItem(reader, context, set); + set.add(principal); } reader.moveUp(); return set; diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java index a0c8d3b..f78b1c4 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -46,7 +46,7 @@ } public boolean canConvert(final Class type) { - return Throwable.class.isAssignableFrom(type); + return type != null && Throwable.class.isAssignableFrom(type); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java index e4fa6c1..091dfbb 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2013, 2016 XStream Committers. + * Copyright (C) 2011, 2013, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -122,7 +122,7 @@ } this.valueField = field; } - enumMapper = JVM.is15() ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null; + enumMapper = JVM.isVersion(5) ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null; } public boolean canConvert(final Class type) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToStringConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToStringConverter.java index cb177ee..c849ae4 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToStringConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToStringConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -36,7 +36,7 @@ ctor = clazz.getConstructor(STRING_PARAMETER); } public boolean canConvert(Class type) { - return type.equals(clazz); + return type == clazz; } public String toString(Object obj) { return obj == null ? null : obj.toString(); diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java index 04dfd76..58ed993 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -141,84 +141,8 @@ } }); - new Object() { - { - final Map hiddenMappers = new HashMap(); - for (Iterator fieldIter = fields.iterator(); fieldIter.hasNext();) { - FieldInfo info = (FieldInfo)fieldIter.next(); - if (info.value != null) { - final Field defaultField = (Field)defaultFieldDefinition.get(info.fieldName); - Mapper.ImplicitCollectionMapping mapping = mapper - .getImplicitCollectionDefForFieldName( - defaultField.getDeclaringClass() == info.definedIn ? sourceType : info.definedIn, - info.fieldName); - if (mapping != null) { - Set mappings = (Set)hiddenMappers.get(info.fieldName); - if (mappings == null) { - mappings = new HashSet(); - mappings.add(mapping); - hiddenMappers.put(info.fieldName, mappings); - } else { - if (!mappings.add(mapping)) { - mapping = null; - } - } - } - if (mapping != null) { - if (context instanceof ReferencingMarshallingContext) { - if (info.value != Collections.EMPTY_LIST - && info.value != Collections.EMPTY_SET - && info.value != Collections.EMPTY_MAP) { - ReferencingMarshallingContext refContext = (ReferencingMarshallingContext)context; - refContext.registerImplicit(info.value); - } - } - final boolean isCollection = info.value instanceof Collection; - final boolean isMap = info.value instanceof Map; - final boolean isEntry = isMap && mapping.getKeyFieldName() == null; - final boolean isArray = info.value.getClass().isArray(); - for (Iterator iter = isArray - ? new ArrayIterator(info.value) - : isCollection ? ((Collection)info.value).iterator() : isEntry - ? ((Map)info.value).entrySet().iterator() - : ((Map)info.value).values().iterator(); iter.hasNext();) { - Object obj = iter.next(); - final String itemName; - final Class itemType; - if (obj == null) { - itemType = Object.class; - itemName = mapper.serializedClass(null); - } else if (isEntry) { - final String entryName = mapping.getItemFieldName() != null - ? mapping.getItemFieldName() - : mapper.serializedClass(Map.Entry.class); - Map.Entry entry = (Map.Entry)obj; - ExtendedHierarchicalStreamWriterHelper.startNode( - writer, entryName, entry.getClass()); - writeItem(entry.getKey(), context, writer); - writeItem(entry.getValue(), context, writer); - writer.endNode(); - continue; - } else if (mapping.getItemFieldName() != null) { - itemType = mapping.getItemType(); - itemName = mapping.getItemFieldName(); - } else { - itemType = obj.getClass(); - itemName = mapper.serializedClass(itemType); - } - writeField( - info.fieldName, itemName, itemType, info.definedIn, obj); - } - } else { - writeField( - info.fieldName, null, info.type, info.definedIn, info.value); - } - } - } - - } - - void writeField(String fieldName, String aliasName, Class fieldType, + final FieldMarshaller fieldMarshaller = new FieldMarshaller() { + public void writeField(String fieldName, String aliasName, Class fieldType, Class definedIn, Object newObj) { Class actualType = newObj != null ? newObj.getClass() : fieldType; ExtendedHierarchicalStreamWriterHelper.startNode(writer, aliasName != null @@ -252,8 +176,7 @@ writer.endNode(); } - void writeItem(Object item, MarshallingContext context, - HierarchicalStreamWriter writer) { + public void writeItem(Object item) { if (item == null) { String name = mapper.serializedClass(null); ExtendedHierarchicalStreamWriterHelper.startNode( @@ -268,6 +191,79 @@ } } }; + + final Map hiddenMappers = new HashMap(); + for (Iterator fieldIter = fields.iterator(); fieldIter.hasNext();) { + FieldInfo info = (FieldInfo)fieldIter.next(); + if (info.value != null) { + final Field defaultField = (Field)defaultFieldDefinition.get(info.fieldName); + Mapper.ImplicitCollectionMapping mapping = mapper + .getImplicitCollectionDefForFieldName( + defaultField.getDeclaringClass() == info.definedIn ? sourceType : info.definedIn, + info.fieldName); + if (mapping != null) { + Set mappings = (Set)hiddenMappers.get(info.fieldName); + if (mappings == null) { + mappings = new HashSet(); + mappings.add(mapping); + hiddenMappers.put(info.fieldName, mappings); + } else { + if (!mappings.add(mapping)) { + mapping = null; + } + } + } + if (mapping != null) { + if (context instanceof ReferencingMarshallingContext) { + if (info.value != Collections.EMPTY_LIST + && info.value != Collections.EMPTY_SET + && info.value != Collections.EMPTY_MAP) { + ReferencingMarshallingContext refContext = (ReferencingMarshallingContext)context; + refContext.registerImplicit(info.value); + } + } + final boolean isCollection = info.value instanceof Collection; + final boolean isMap = info.value instanceof Map; + final boolean isEntry = isMap && mapping.getKeyFieldName() == null; + final boolean isArray = info.value.getClass().isArray(); + for (Iterator iter = isArray + ? new ArrayIterator(info.value) + : isCollection ? ((Collection)info.value).iterator() : isEntry + ? ((Map)info.value).entrySet().iterator() + : ((Map)info.value).values().iterator(); iter.hasNext();) { + Object obj = iter.next(); + final String itemName; + final Class itemType; + if (obj == null) { + itemType = Object.class; + itemName = mapper.serializedClass(null); + } else if (isEntry) { + final String entryName = mapping.getItemFieldName() != null + ? mapping.getItemFieldName() + : mapper.serializedClass(Map.Entry.class); + Map.Entry entry = (Map.Entry)obj; + ExtendedHierarchicalStreamWriterHelper.startNode( + writer, entryName, entry.getClass()); + fieldMarshaller.writeItem(entry.getKey()); + fieldMarshaller.writeItem(entry.getValue()); + writer.endNode(); + continue; + } else if (mapping.getItemFieldName() != null) { + itemType = mapping.getItemType(); + itemName = mapping.getItemFieldName(); + } else { + itemType = obj.getClass(); + itemName = mapper.serializedClass(itemType); + } + fieldMarshaller.writeField( + info.fieldName, itemName, itemType, info.definedIn, obj); + } + } else { + fieldMarshaller.writeField( + info.fieldName, null, info.type, info.definedIn, info.value); + } + } + } } protected void marshallField(final MarshallingContext context, Object newObj, Field field) { @@ -662,6 +658,12 @@ } } + private interface FieldMarshaller { + void writeItem(final Object item); + void writeField(final String fieldName, final String aliasName, final Class fieldType, + final Class definedIn, final Object newObj); + } + private static class ArraysList extends ArrayList { final Class physicalFieldType; diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java index 12c886d..3e0d8a1 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -89,7 +89,7 @@ } public boolean canConvert(Class type) { - return (Enhancer.isEnhanced(type) && type.getName().indexOf(DEFAULT_NAMING_MARKER) > 0) + return type != null && Enhancer.isEnhanced(type) && type.getName().indexOf(DEFAULT_NAMING_MARKER) > 0 || type == CGLIBMapper.Marker.class; } diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java index 05ab79c..fd89d89 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java @@ -76,7 +76,7 @@ } public boolean canConvert(Class type) { - return JVM.canCreateDerivedObjectOutputStream() && Externalizable.class.isAssignableFrom(type); + return type != null && JVM.canCreateDerivedObjectOutputStream() && Externalizable.class.isAssignableFrom(type); } public void marshal(final Object original, final HierarchicalStreamWriter writer, final MarshallingContext context) { diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java index 77f01a4..32d3271 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2018 XStream Committers. * All rights reserved. * The software in this package is published under the terms of the BSD * style license a copy of which has been included with this distribution in @@ -35,6 +35,7 @@ Collections.EMPTY_MAP); private transient Map dictionaryEntries; + private transient FieldUtil fieldUtil; private final FieldKeySorter sorter; public FieldDictionary() { @@ -48,6 +49,14 @@ private void init() { dictionaryEntries = new HashMap(); + if (JVM.is15()) + try { + fieldUtil = (FieldUtil)JVM.loadClassForName("com.thoughtworks.xstream.converters.reflection.FieldUtil15", true).newInstance(); + } catch (Exception e) { + ; + } + if (fieldUtil == null) + fieldUtil = new FieldUtil14(); } /** @@ -160,6 +169,9 @@ } for (int i = 0; i < fields.length; i++) { final Field field = fields[i]; + if (fieldUtil.isSynthetic(field) && field.getName().startsWith("$jacoco")) { + continue; + } if (!field.isAccessible()) { field.setAccessible(true); } @@ -194,6 +206,10 @@ return this; } + interface FieldUtil { + boolean isSynthetic(Field field); + } + private static final class DictionaryEntry { private final Map keyedByFieldName; diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldUtil14.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldUtil14.java new file mode 100644 index 0000000..8320e99 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldUtil14.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2018 XStream Committers. + * All rights reserved. + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * Created on 10. October 2018 by Joerg Schaible. + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.lang.reflect.Field; + +/** + * @author Jörg Schaible + */ +class FieldUtil14 implements FieldDictionary.FieldUtil { + + public boolean isSynthetic(final Field field) { + return false; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldUtil15.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldUtil15.java new file mode 100644 index 0000000..a277676 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldUtil15.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2018 XStream Committers. + * All rights reserved. + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * Created on 10. October 2018 by Joerg Schaible. + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.lang.reflect.Field; + +/** + * @author Jörg Schaible + */ +class FieldUtil15 implements FieldDictionary.FieldUtil { + + public boolean isSynthetic(final Field field) { + return field.isSynthetic(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java index d2beebd..c7d837c 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2009, 2011, 2013, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2009, 2011, 2013, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -168,7 +168,7 @@ protected void validateFieldAccess(Field field) { if (Modifier.isFinal(field.getModifiers())) { - if (JVM.is15()) { + if (JVM.isVersion(5)) { if (!field.isAccessible()) { field.setAccessible(true); } diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/time/ChronologyConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/time/ChronologyConverter.java index 1cc3766..0fa694f 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/time/ChronologyConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/time/ChronologyConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 XStream Committers. + * Copyright (C) 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -27,7 +27,7 @@ @Override public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { - return Chronology.class.isAssignableFrom(type); + return type != null && Chronology.class.isAssignableFrom(type); } @Override diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/time/JapaneseEraConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/time/JapaneseEraConverter.java index 9906d69..7971b23 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/time/JapaneseEraConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/time/JapaneseEraConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 XStream Committers. + * Copyright (C) 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -26,7 +26,7 @@ @Override public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { - return JapaneseEra.class.isAssignableFrom(type); + return type != null && JapaneseEra.class.isAssignableFrom(type); } @Override diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/time/ZoneIdConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/time/ZoneIdConverter.java index c241dc6..dbe3976 100644 --- a/xstream/src/java/com/thoughtworks/xstream/converters/time/ZoneIdConverter.java +++ b/xstream/src/java/com/thoughtworks/xstream/converters/time/ZoneIdConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 XStream Committers. + * Copyright (C) 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -28,7 +28,7 @@ @Override public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { - return ZoneId.class.isAssignableFrom(type); + return type != null && ZoneId.class.isAssignableFrom(type); } @Override diff --git a/xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceUnmarshaller.java b/xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceUnmarshaller.java index 791ca18..dbfeaca 100644 --- a/xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceUnmarshaller.java +++ b/xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceUnmarshaller.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2008, 2011, 2015 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2011, 2015, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -67,11 +67,16 @@ } else { Object currentReferenceKey = getCurrentReferenceKey(); parentStack.push(currentReferenceKey); - result = super.convert(parent, type, converter); - if (currentReferenceKey != null) { - values.put(currentReferenceKey, result == null ? NULL : result); + Object localResult = null; + try { + localResult = super.convert(parent, type, converter); + } finally { + result = localResult; + if (currentReferenceKey != null) { + values.put(currentReferenceKey, result == null ? NULL : result); + } + parentStack.popSilently(); } - parentStack.popSilently(); } return result; } diff --git a/xstream/src/java/com/thoughtworks/xstream/core/DefaultConverterLookup.java b/xstream/src/java/com/thoughtworks/xstream/core/DefaultConverterLookup.java index c7f7716..d4e6349 100644 --- a/xstream/src/java/com/thoughtworks/xstream/core/DefaultConverterLookup.java +++ b/xstream/src/java/com/thoughtworks/xstream/core/DefaultConverterLookup.java @@ -15,14 +15,15 @@ import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.ConverterLookup; import com.thoughtworks.xstream.converters.ConverterRegistry; +import com.thoughtworks.xstream.core.util.Cloneables; import com.thoughtworks.xstream.core.util.PrioritizedList; import com.thoughtworks.xstream.mapper.Mapper; -import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; -import java.util.WeakHashMap; + /** * The default implementation of converters lookup. @@ -35,19 +36,33 @@ private final PrioritizedList converters = new PrioritizedList(); private transient Map typeToConverterMap; + private Map serializationMap = null; public DefaultConverterLookup() { - readResolve(); + this(new HashMap()); + } + + /** + * Constructs a DefaultConverterLookup with a provided map. + * + * @param map the map to use + * @throws NullPointerException if map is null + * @since 1.4.11 + */ + public DefaultConverterLookup(Map map) { + typeToConverterMap = map; + typeToConverterMap.clear(); } /** * @deprecated As of 1.3, use {@link #DefaultConverterLookup()} */ public DefaultConverterLookup(Mapper mapper) { + this(); } public Converter lookupConverterForType(Class type) { - Converter cachedConverter = (Converter) typeToConverterMap.get(type); + Converter cachedConverter = type != null ? (Converter)typeToConverterMap.get(type.getName()) : null; if (cachedConverter != null) { return cachedConverter; } @@ -55,10 +70,12 @@ final Map errors = new LinkedHashMap(); Iterator iterator = converters.iterator(); while (iterator.hasNext()) { - Converter converter = (Converter) iterator.next(); + Converter converter = (Converter)iterator.next(); try { if (converter.canConvert(type)) { - typeToConverterMap.put(type, converter); + if (type != null) { + typeToConverterMap.put(type.getName(), converter); + } return converter; } } catch (final RuntimeException e) { @@ -80,36 +97,32 @@ } throw exception; } - + public void registerConverter(Converter converter, int priority) { + typeToConverterMap.clear(); converters.add(converter, priority); - for (Iterator iter = typeToConverterMap.keySet().iterator(); iter.hasNext();) { - Class type = (Class) iter.next(); - try { - if (converter.canConvert(type)) { - iter.remove(); - } - } catch (final RuntimeException e) { - // ignore - } catch (final LinkageError e) { - // ignore - } - } } - + public void flushCache() { typeToConverterMap.clear(); Iterator iterator = converters.iterator(); while (iterator.hasNext()) { - Converter converter = (Converter) iterator.next(); + Converter converter = (Converter)iterator.next(); if (converter instanceof Caching) { ((Caching)converter).flushCache(); } } } + private Object writeReplace() { + serializationMap = (Map)Cloneables.cloneIfPossible(typeToConverterMap); + serializationMap.clear(); + return this; + } + private Object readResolve() { - typeToConverterMap = Collections.synchronizedMap(new WeakHashMap()); + typeToConverterMap = serializationMap == null ? new HashMap() : serializationMap; + serializationMap = null; return this; } } diff --git a/xstream/src/java/com/thoughtworks/xstream/core/JVM.java b/xstream/src/java/com/thoughtworks/xstream/core/JVM.java index 50d8892..e32a0c0 100644 --- a/xstream/src/java/com/thoughtworks/xstream/core/JVM.java +++ b/xstream/src/java/com/thoughtworks/xstream/core/JVM.java @@ -1,24 +1,15 @@ /* * Copyright (C) 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD * style license a copy of which has been included with this distribution in * the LICENSE.txt file. - * + * * Created on 09. May 2004 by Joe Walnes */ package com.thoughtworks.xstream.core; - -import com.thoughtworks.xstream.converters.reflection.FieldDictionary; -import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; -import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; -import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; -import com.thoughtworks.xstream.core.util.CustomObjectOutputStream; -import com.thoughtworks.xstream.core.util.DependencyInjectionFactory; -import com.thoughtworks.xstream.core.util.PresortedMap; -import com.thoughtworks.xstream.core.util.PresortedSet; import java.io.IOException; import java.lang.reflect.Field; @@ -32,6 +23,17 @@ import java.util.TreeMap; import java.util.TreeSet; +import com.thoughtworks.xstream.converters.reflection.FieldDictionary; +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.core.util.Base64Encoder; +import com.thoughtworks.xstream.core.util.CustomObjectOutputStream; +import com.thoughtworks.xstream.core.util.DependencyInjectionFactory; +import com.thoughtworks.xstream.core.util.PresortedMap; +import com.thoughtworks.xstream.core.util.PresortedSet; + + public class JVM implements Caching { private ReflectionProvider reflectionProvider; @@ -52,6 +54,7 @@ private static final float DEFAULT_JAVA_VERSION = 1.4f; private static final boolean reverseFieldOrder = false; private static final Class reflectionProviderType; + private static final StringCodec base64Codec; static class Test { private Object o; @@ -110,7 +113,8 @@ cls = null; } if (cls == null) { - cls = loadClassForName("com.thoughtworks.xstream.converters.reflection.SunLimitedUnsafeReflectionProvider"); + cls = loadClassForName( + "com.thoughtworks.xstream.converters.reflection.SunLimitedUnsafeReflectionProvider"); } type = cls; } catch (ObjectAccessException e) { @@ -171,6 +175,23 @@ isAWTAvailable = loadClassForName("java.awt.Color", false) != null; isSwingAvailable = loadClassForName("javax.swing.LookAndFeel", false) != null; isSQLAvailable = loadClassForName("java.sql.Date") != null; + + StringCodec base64 = null; + Class base64Class = loadClassForName( + "com.thoughtworks.xstream.core.util.Base64JavaUtilCodec"); + if (base64Class == null) { + base64Class = loadClassForName("com.thoughtworks.xstream.core.util.Base64JAXBCodec"); + } + if (base64Class != null) { + try { + base64 = (StringCodec)base64Class.newInstance(); + } catch (final Exception e) { + } + } + if (base64 == null) { + base64 = new Base64Encoder(); + } + base64Codec = base64; } /** @@ -180,8 +201,7 @@ } /** - * Parses the java version system property to determine the major java version, - * i.e. 1.x + * Parses the java version system property to determine the major java version, i.e. 1.x * * @return A float of the form 1.x */ @@ -198,21 +218,21 @@ * @deprecated As of 1.4.4, minimal JDK version is 1.4 already */ public static boolean is14() { - return majorJavaVersion >= 1.4f; + return isVersion(4); } /** * @deprecated As of 1.4.4, minimal JDK version will be 1.7 for next major release */ public static boolean is15() { - return majorJavaVersion >= 1.5f; + return isVersion(5); } /** * @deprecated As of 1.4.4, minimal JDK version will be 1.7 for next major release */ public static boolean is16() { - return majorJavaVersion >= 1.6f; + return isVersion(6); } /** @@ -220,19 +240,20 @@ * @deprecated As of 1.4.10, minimal JDK version will be 1.7 for next major release */ public static boolean is17() { - return majorJavaVersion >= 1.7f; + return isVersion(7); } /** * @since 1.4 + * @deprecated As of 1.4.11 use {@link #isVersion(int)}. */ public static boolean is18() { - return majorJavaVersion >= 1.8f; + return isVersion(8); } /** * @since 1.4.8 - * @deprecated As of upcoming use {@link #is9()} + * @deprecated As of 1.4.10 use {@link #isVersion(int)}. */ public static boolean is19() { return majorJavaVersion >= 1.9f; @@ -240,9 +261,25 @@ /** * @since 1.4.10 + * @deprecated As of 1.4.11 use {@link #isVersion(int)} */ public static boolean is9() { - return majorJavaVersion >= 9f; + return isVersion(9); + } + + /** + * Checks current runtime against provided major Java version. + * + * @param version the requested major Java version + * @return true if current runtime is at least the provided major version + * @since 1.4.11 + */ + public static boolean isVersion(final int version) { + if (version < 1) { + throw new IllegalArgumentException("Java version range starts with at least 1."); + } + final float v = majorJavaVersion < 9 ? 1f + version * 0.1f : version; + return majorJavaVersion >= v; } private static boolean isIBM() { @@ -258,10 +295,11 @@ /** * Load a XStream class for the given name. - * - *

This method is not meant to use loading arbitrary classes. It is used by XStream bootstrap - * until it is able to use the user provided or the default {@link ClassLoader}.

- * + *

+ * This method is not meant to use loading arbitrary classes. It is used by XStream bootstrap until it is able to + * use the user provided or the default {@link ClassLoader}. + *

+ * * @since 1.4.5 */ public static Class loadClassForName(String name) { @@ -277,10 +315,11 @@ /** * Load a XStream class for the given name. - * - *

This method is not meant to use loading arbitrary classes. It is used by XStream bootstrap - * until it is able to use the user provided or the default {@link ClassLoader}.

- * + *

+ * This method is not meant to use loading arbitrary classes. It is used by XStream bootstrap until it is able to + * use the user provided or the default {@link ClassLoader}. + *

+ * * @since 1.4.5 */ public static Class loadClassForName(String name, boolean initialize) { @@ -304,7 +343,7 @@ /** * Create the best matching ReflectionProvider. - * + * * @return a new instance * @since 1.4.5 */ @@ -332,13 +371,13 @@ * implementations configured in lib/stax.properties or registered with the Service * API. *

- * + * * @return the XMLInputFactory implementation or null * @throws ClassNotFoundException if the standard class cannot be found * @since 1.4.5 */ public static Class getStaxInputFactory() throws ClassNotFoundException { - if (is16()) { + if (isVersion(6)) { if (isIBM()) { return Class.forName("com.ibm.xml.xlxp.api.stax.XMLInputFactoryImpl"); } else { @@ -357,13 +396,13 @@ * implementations configured in lib/stax.properties or registered with the Service * API. *

- * + * * @return the XMLOutputFactory implementation or null * @throws ClassNotFoundException if the standard class cannot be found * @since 1.4.5 */ public static Class getStaxOutputFactory() throws ClassNotFoundException { - if (is16()) { + if (isVersion(6)) { if (isIBM()) { return Class.forName("com.ibm.xml.xlxp.api.stax.XMLOutputFactoryImpl"); } else { @@ -374,6 +413,17 @@ } /** + * Get an available Base64 implementation. Prefers java.util.Base64 over DataTypeConverter from JAXB over XStream's + * own implementation. + * + * @return a Base64 codec implementation + * @since 1.4.11 + */ + public static StringCodec getBase64Codec() { + return base64Codec; + } + + /** * @deprecated As of 1.4.5 use {@link #newReflectionProvider()} */ public synchronized ReflectionProvider bestReflectionProvider() { @@ -384,7 +434,7 @@ } private static boolean canUseSunUnsafeReflectionProvider() { - return canAllocateWithUnsafe && is14(); + return canAllocateWithUnsafe; } private static boolean canUseSunLimitedUnsafeReflectionProvider() { @@ -400,6 +450,7 @@ /** * Checks if AWT is available. + * * @since 1.4.5 */ public static boolean isAWTAvailable() { @@ -407,7 +458,8 @@ } /** - * Checks if the jvm supports awt. + * Checks if the JVM supports AWT. + * * @deprecated As of 1.4.5 use {@link #isAWTAvailable()} */ public boolean supportsAWT() { @@ -416,6 +468,7 @@ /** * Checks if Swing is available. + * * @since 1.4.5 */ public static boolean isSwingAvailable() { @@ -423,7 +476,8 @@ } /** - * Checks if the jvm supports swing. + * Checks if the JVM supports Swing. + * * @deprecated As of 1.4.5 use {@link #isSwingAvailable()} */ public boolean supportsSwing() { @@ -432,6 +486,7 @@ /** * Checks if SQL is available. + * * @since 1.4.5 */ public static boolean isSQLAvailable() { @@ -439,7 +494,8 @@ } /** - * Checks if the jvm supports sql. + * Checks if the JVM supports SQL. + * * @deprecated As of 1.4.5 use {@link #isSQLAvailable()} */ public boolean supportsSQL() { @@ -448,7 +504,7 @@ /** * Checks if TreeSet.addAll is optimized for SortedSet argument. - * + * * @since 1.4 */ public static boolean hasOptimizedTreeSetAddAll() { @@ -457,7 +513,7 @@ /** * Checks if TreeMap.putAll is optimized for SortedMap argument. - * + * * @since 1.4 */ public static boolean hasOptimizedTreeMapPutAll() { @@ -539,11 +595,13 @@ System.out.println("Java Beans EventHandler present: " + (loadClassForName("java.beans.EventHandler") != null)); System.out.println("Standard StAX XMLInputFactory: " + staxInputFactory); System.out.println("Standard StAX XMLOutputFactory: " + staxOutputFactory); + System.out.println("Standard Base64 Codec: " + getBase64Codec().getClass().toString()); System.out.println("Optimized TreeSet.addAll: " + hasOptimizedTreeSetAddAll()); System.out.println("Optimized TreeMap.putAll: " + hasOptimizedTreeMapPutAll()); System.out.println("Can parse UTC date format: " + canParseUTCDateFormat()); System.out.println("Can create derive ObjectOutputStream: " + canCreateDerivedObjectOutputStream()); System.out.println("Reverse field order detected for JDK: " + reverseJDK); - System.out.println("Reverse field order detected (only if JVM class itself has been compiled): " + reverseLocal); + System.out.println("Reverse field order detected (only if JVM class itself has been compiled): " + + reverseLocal); } } diff --git a/xstream/src/java/com/thoughtworks/xstream/core/StringCodec.java b/xstream/src/java/com/thoughtworks/xstream/core/StringCodec.java new file mode 100644 index 0000000..4721ddc --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/StringCodec.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2017, 2018 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. August 2017 by Joerg Schaible + */ +package com.thoughtworks.xstream.core; + +/** + * Interface for an encoder and decoder of data to string values and back. + * + * @author Jörg Schaible + * @since 1.4.11 + */ +public interface StringCodec { + + /** + * Decode the provided encoded string. + * + * @param encoded the encoded string + * @return the decoded data + * @since 1.4.11 + */ + byte[] decode(String encoded); + + /** + * Encode the provided data. + * + * @param data the data to encode + * @return the data encoded as string + * @since 1.4.11 + */ + String encode(byte[] data); +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/core/TreeUnmarshaller.java b/xstream/src/java/com/thoughtworks/xstream/core/TreeUnmarshaller.java index e40b105..0a5b3dc 100644 --- a/xstream/src/java/com/thoughtworks/xstream/core/TreeUnmarshaller.java +++ b/xstream/src/java/com/thoughtworks/xstream/core/TreeUnmarshaller.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -67,18 +67,18 @@ } protected Object convert(Object parent, Class type, Converter converter) { + types.push(type); try { - types.push(type); - Object result = converter.unmarshal(reader, this); - types.popSilently(); - return result; - } catch (ConversionException conversionException) { + return converter.unmarshal(reader, this); + } catch (final ConversionException conversionException) { addInformationTo(conversionException, type, converter, parent); throw conversionException; } catch (RuntimeException e) { ConversionException conversionException = new ConversionException(e); addInformationTo(conversionException, type, converter, parent); throw conversionException; + } finally { + types.popSilently(); } } diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/Base64Encoder.java b/xstream/src/java/com/thoughtworks/xstream/core/util/Base64Encoder.java index f28d991..1e9ab4a 100644 --- a/xstream/src/java/com/thoughtworks/xstream/core/util/Base64Encoder.java +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/Base64Encoder.java @@ -1,12 +1,12 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD * style license a copy of which has been included with this distribution in * the LICENSE.txt file. - * + * * Created on 06. August 2004 by Joe Walnes */ package com.thoughtworks.xstream.core.util; @@ -16,18 +16,25 @@ import java.io.Reader; import java.io.StringReader; +import com.thoughtworks.xstream.core.StringCodec; + + /** * Encodes binary data to plain text as Base64. - * - *

Despite there being a gazillion other Base64 implementations out there, this has been written as part of XStream as - * it forms a core part but is too trivial to warrant an extra dependency.

- * - *

This meets the standard as described in RFC 1521, section 5.2 , allowing - * other Base64 tools to manipulate the data.

+ *

+ * Despite there being a gazillion other Base64 implementations out there, this has been written as part of XStream as + * it forms a core part but is too trivial to warrant an extra dependency. Recent Java Runtimes (since Java 6) provide + * an own Base64 codec though. + *

+ *

+ * By default it will not insert line breaks to support Base64 values also as attribute values. However, the standard as + * described in RFC 1521, section 5.2 requires line breaks, + * allowing other Base64 tools to manipulate the data. You can configure the Base64Encoder to be RFC compliant. + *

* * @author Joe Walnes */ -public class Base64Encoder { +public class Base64Encoder implements StringCodec { // Here's how encoding works: // @@ -35,59 +42,113 @@ // // 2) The combined 24 bits (3 * 8) are split into 4 groups of 6 bits. // - // input |------||------||------| (3 values each with 8 bits) - // 101010101010101010101010 - // output |----||----||----||----| (4 values each with 6 bits) + // Input: + // |------||------||------| (3 values each with 8 bits) + // 101010101010101010101010 + // Output: + // |----||----||----||----| (4 values each with 6 bits) // // 3) Each of these 4 groups of 6 bits are converted back to a number, which will fall in the range of 0 - 63. // // 4) Each of these 4 numbers are converted to an alphanumeric char in a specified mapping table, to create - // a 4 character string. + // a 4 character string. // // 5) This is repeated for all groups of three bytes. // // 6) Special padding is done at the end of the stream using the '=' char. - private static final char[] SIXTY_FOUR_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); + private static final char[] SIXTY_FOUR_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + .toCharArray(); private static final int[] REVERSE_MAPPING = new int[123]; + private final boolean lineBreaks; static { - for (int i = 0; i < SIXTY_FOUR_CHARS.length; i++) REVERSE_MAPPING[SIXTY_FOUR_CHARS[i]] = i + 1; + for (int i = 0; i < SIXTY_FOUR_CHARS.length; i++) { + REVERSE_MAPPING[SIXTY_FOUR_CHARS[i]] = i + 1; + } } - public String encode(byte[] input) { - StringBuffer result = new StringBuffer(); + /** + * Constructs a Base64Encoder. + *

+ * The encoder will not insert any line breaks. + *

+ * + * @since 1.4.11 + */ + public Base64Encoder() { + this(false); + } + + /** + * Constructs a Base64Encoder. + * + * @param lineBreaks flag to insert line breaks + * @since 1.4.11 + */ + public Base64Encoder(final boolean lineBreaks) { + this.lineBreaks = lineBreaks; + } + + public String encode(final byte[] input) { + final int stringSize = computeResultingStringSize(input); + final StringBuffer result = new StringBuffer(stringSize); int outputCharCount = 0; for (int i = 0; i < input.length; i += 3) { - int remaining = Math.min(3, input.length - i); - int oneBigNumber = (input[i] & 0xff) << 16 | (remaining <= 1 ? 0 : input[i + 1] & 0xff) << 8 | (remaining <= 2 ? 0 : input[i + 2] & 0xff); - for (int j = 0; j < 4; j++) result.append(remaining + 1 > j ? SIXTY_FOUR_CHARS[0x3f & oneBigNumber >> 6 * (3 - j)] : '='); - if ((outputCharCount += 4) % 76 == 0) result.append('\n'); + final int remaining = Math.min(3, input.length - i); + final int oneBigNumber = (input[i] & 0xff) << 16 + | (remaining <= 1 ? 0 : input[i + 1] & 0xff) << 8 + | (remaining <= 2 ? 0 : input[i + 2] & 0xff); + for (int j = 0; j < 4; j++) { + result.append(remaining + 1 > j ? SIXTY_FOUR_CHARS[0x3f & oneBigNumber >> 6 * (3 - j)] : '='); + } + if (lineBreaks && (outputCharCount += 4) % 76 == 0 && i + 3 < input.length) { + result.append('\n'); + } } - return result.toString(); + final String s = result.toString(); + return s; } - public byte[] decode(String input) { + // package private for testing purpose + int computeResultingStringSize(final byte[] input) { + int stringSize = input.length / 3 + (input.length % 3 == 0 ? 0 : 1); + stringSize *= 4; + if (lineBreaks) { + stringSize += stringSize / 76; + } + return stringSize; + } + + public byte[] decode(final String input) { try { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - StringReader in = new StringReader(input); + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final StringReader in = new StringReader(input); for (int i = 0; i < input.length(); i += 4) { - int a[] = {mapCharToInt(in), mapCharToInt(in), mapCharToInt(in), mapCharToInt(in)}; - int oneBigNumber = (a[0] & 0x3f) << 18 | (a[1] & 0x3f) << 12 | (a[2] & 0x3f) << 6 | (a[3] & 0x3f); - for (int j = 0; j < 3; j++) if (a[j + 1] >= 0) out.write(0xff & oneBigNumber >> 8 * (2 - j)); + final int a[] = {mapCharToInt(in), mapCharToInt(in), mapCharToInt(in), mapCharToInt(in)}; + final int oneBigNumber = (a[0] & 0x3f) << 18 | (a[1] & 0x3f) << 12 | (a[2] & 0x3f) << 6 | a[3] & 0x3f; + for (int j = 0; j < 3; j++) { + if (a[j + 1] >= 0) { + out.write(0xff & oneBigNumber >> 8 * (2 - j)); + } + } } return out.toByteArray(); - } catch (IOException e) { + } catch (final IOException e) { throw new Error(e + ": " + e.getMessage()); } } - private int mapCharToInt(Reader input) throws IOException { + private int mapCharToInt(final Reader input) throws IOException { int c; while ((c = input.read()) != -1) { - int result = REVERSE_MAPPING[c]; - if (result != 0) return result -1; - if (c == '=') return -1; + final int result = REVERSE_MAPPING[c]; + if (result != 0) { + return result - 1; + } + if (c == '=') { + return -1; + } } return -1; } diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/Base64JAXBCodec.java b/xstream/src/java/com/thoughtworks/xstream/core/util/Base64JAXBCodec.java new file mode 100644 index 0000000..0a22418 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/Base64JAXBCodec.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2017, 2018 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. August 2017 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import javax.xml.bind.DatatypeConverter; + +import com.thoughtworks.xstream.core.StringCodec; + + +/** + * Base64 codec implementation based on JAXB. + * + * @author Jörg Schaible + * @since 1.4.11 + */ +public class Base64JAXBCodec implements StringCodec { + + @Override + public byte[] decode(final String base64) { + return DatatypeConverter.parseBase64Binary(base64); + } + + @Override + public String encode(final byte[] data) { + return DatatypeConverter.printBase64Binary(data); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/Base64JavaUtilCodec.java b/xstream/src/java/com/thoughtworks/xstream/core/util/Base64JavaUtilCodec.java new file mode 100644 index 0000000..21390e7 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/Base64JavaUtilCodec.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017, 2018 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. August 2017 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import java.util.Base64; + +import com.thoughtworks.xstream.core.StringCodec; + + +/** + * Base64 codec implementation based on java.util.Base64. + * + * @author Jörg Schaible + * @since 1.4.11 + */ +public class Base64JavaUtilCodec implements StringCodec { + final private Base64.Decoder decoder; + final private Base64.Encoder encoder; + + /** + * Constructs a Base64JavaUtilCodec. + *

+ * The implementation will use a basic encoder and a MIME decoder by default. + *

+ * + * @since 1.4.11 + */ + public Base64JavaUtilCodec() { + this(Base64.getEncoder(), Base64.getMimeDecoder()); + } + + /** + * Constructs a Base64JavaUtilCodec with provided encoder and decoder. + * + * @param encoder the encoder instance + * @param decoder the decoder instance + * @since 1.4.11 + */ + public Base64JavaUtilCodec(final Base64.Encoder encoder, final Base64.Decoder decoder) { + this.encoder = encoder; + this.decoder = decoder; + } + + @Override + public byte[] decode(final String base64) { + return decoder.decode(base64); + } + + @Override + public String encode(final byte[] data) { + return encoder.encodeToString(data); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/CompositeClassLoader.java b/xstream/src/java/com/thoughtworks/xstream/core/util/CompositeClassLoader.java index bdfc626..21593d1 100644 --- a/xstream/src/java/com/thoughtworks/xstream/core/util/CompositeClassLoader.java +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/CompositeClassLoader.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2011, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2011, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -53,7 +53,7 @@ */ public class CompositeClassLoader extends ClassLoader { static { - if (JVM.is17()) { + if (JVM.isVersion(7)) { // see http://www.cs.duke.edu/csed/java/jdk1.7/technotes/guides/lang/cl-mt.html try { Method m = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable", (Class[])null); diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java b/xstream/src/java/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java index 9ef7479..698b838 100644 --- a/xstream/src/java/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -136,11 +136,7 @@ } public int readUnsignedByte() throws IOException { - int b = ((Byte)peekCallback().readFromStream()).byteValue(); - if (b < 0) { - b += Byte.MAX_VALUE; - } - return b; + return ((Byte)peekCallback().readFromStream()).intValue() & 0xff; } public int readInt() throws IOException { @@ -168,11 +164,7 @@ } public int readUnsignedShort() throws IOException { - int b = ((Short)peekCallback().readFromStream()).shortValue(); - if (b < 0) { - b += Short.MAX_VALUE; - } - return b; + return ((Short)peekCallback().readFromStream()).intValue() & 0xffff; } public String readUTF() throws IOException { diff --git a/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamReader.java b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamReader.java index 27059fb..3ac2212 100644 --- a/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamReader.java +++ b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamReader.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 XStream Committers. + * Copyright (C) 2011, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -13,6 +13,7 @@ /** * @author Jörg Schaible * @since 1.4.2 + * @deprecated As of 1.4.11, this interface will be merged into parent with version 1.5.0. */ public interface ExtendedHierarchicalStreamReader extends HierarchicalStreamReader { diff --git a/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriter.java index 1091da1..6bac235 100644 --- a/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriter.java +++ b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -13,6 +13,7 @@ /** * @author Paul Hammant + * @deprecated As of 1.4.11, this interface will be merged into parent with version 1.5.0. */ public interface ExtendedHierarchicalStreamWriter extends HierarchicalStreamWriter { diff --git a/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriterHelper.java b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriterHelper.java index ac06624..353b4ab 100644 --- a/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriterHelper.java +++ b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriterHelper.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -11,10 +11,17 @@ */ package com.thoughtworks.xstream.io; +/** + * @deprecated As of 1.4.11, this helper is no longer required since version 1.5.0. + */ public class ExtendedHierarchicalStreamWriterHelper { + /** + * @deprecated As of 1.4.11, with version 1.5.0 use {@link HierarchicalStreamWriter#startNode(String, Class)} + * directly. This helper will be no longer required. + */ public static void startNode(HierarchicalStreamWriter writer, String name, Class clazz) { if (writer instanceof ExtendedHierarchicalStreamWriter) { - ((ExtendedHierarchicalStreamWriter) writer).startNode(name, clazz); + ((ExtendedHierarchicalStreamWriter)writer).startNode(name, clazz); } else { writer.startNode(name); } diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/BEAStaxDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/BEAStaxDriver.java index 01efa8f..a4c30d1 100644 --- a/xstream/src/java/com/thoughtworks/xstream/io/xml/BEAStaxDriver.java +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/BEAStaxDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011, 2014, 2015 XStream Committers. + * Copyright (C) 2009, 2011, 2014, 2015, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -22,9 +22,14 @@ * * @author Jörg Schaible * @since 1.4 + * @deprecated As of 1.4.11 use {@link StandardStaxDriver} or {@link WstxDriver} instead. BEA StAX implementation is + * outdated, unmaintained and has security issues. */ public class BEAStaxDriver extends StaxDriver { + /** + * @deprecated As of 1.4.11 use {@link StandardStaxDriver} or {@link WstxDriver} instead. + */ public BEAStaxDriver() { super(); } @@ -38,12 +43,16 @@ /** * @since 1.4.6 + * @deprecated As of 1.4.11 use {@link StandardStaxDriver} or {@link WstxDriver} instead. */ public BEAStaxDriver(QNameMap qnameMap, NameCoder nameCoder) { super(qnameMap, nameCoder); } - public BEAStaxDriver(QNameMap qnameMap) { + /** + * @deprecated As of 1.4.11 use {@link StandardStaxDriver} or {@link WstxDriver} instead. + */ + public BEAStaxDriver(final QNameMap qnameMap) { super(qnameMap); } @@ -56,6 +65,7 @@ /** * @since 1.4.6 + * @deprecated As of 1.4.11 use {@link StandardStaxDriver} or {@link WstxDriver} instead. */ public BEAStaxDriver(NameCoder nameCoder) { super(nameCoder); diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JDriver.java index 7018f42..685fbe6 100644 --- a/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JDriver.java +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JDriver.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2009, 2011, 2014, 2015 XStream Committers. + * Copyright (C) 2006, 2007, 2009, 2011, 2014, 2015, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -19,6 +19,7 @@ import java.io.Reader; import java.io.Writer; import java.net.URL; +import java.nio.charset.Charset; import org.dom4j.Document; import org.dom4j.DocumentException; @@ -142,7 +143,9 @@ } public HierarchicalStreamWriter createWriter(final OutputStream out) { - final Writer writer = new OutputStreamWriter(out); + final String encoding = getOutputFormat() != null ? getOutputFormat().getEncoding() : null; + final Charset charset = encoding != null && Charset.isSupported(encoding) ? Charset.forName(encoding) : null; + final Writer writer = charset != null ? new OutputStreamWriter(out, charset) : new OutputStreamWriter(out); return createWriter(writer); } diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JReader.java index 8ffe174..fce6ca5 100644 --- a/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JReader.java +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JReader.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * Copyright (C) 2006, 2007, 2009, 2011, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -14,6 +14,8 @@ import com.thoughtworks.xstream.converters.ErrorWriter; import com.thoughtworks.xstream.io.naming.NameCoder; import java.util.List; + +import org.dom4j.Branch; import org.dom4j.Document; import org.dom4j.Element; @@ -21,7 +23,14 @@ private Element currentElement; - public Dom4JReader(Element rootElement) { + /** + * @since 1.4.11 + */ + public Dom4JReader(final Branch branch) { + this(branch instanceof Element ? (Element)branch : ((Document)branch).getRootElement()); + } + + public Dom4JReader(final Element rootElement) { this(rootElement, new XmlFriendlyNameCoder()); } diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/DomDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/DomDriver.java index ae50fbe..001af27 100644 --- a/xstream/src/java/com/thoughtworks/xstream/io/xml/DomDriver.java +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/DomDriver.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2014, 2015 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2014, 2015, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -140,7 +140,7 @@ */ protected DocumentBuilderFactory createDocumentBuilderFactory() { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - if (JVM.is15()) { + if (JVM.isVersion(5)) { try { Method method = DocumentBuilderFactory.class.getMethod("setFeature", new Class[]{ String.class, boolean.class }); @@ -151,7 +151,7 @@ throw new ObjectAccessException("Cannot set feature of DocumentBuilderFactory.", e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); - if (JVM.is16() + if (JVM.isVersion(6) || (cause instanceof ParserConfigurationException && cause.getMessage().indexOf("disallow-doctype-decl") < 0)) { throw new StreamException(cause); diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomDriver.java index cca241d..3e6da8e 100644 --- a/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomDriver.java +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomDriver.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -11,12 +11,11 @@ */ package com.thoughtworks.xstream.io.xml; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import com.thoughtworks.xstream.io.HierarchicalStreamDriver; import com.thoughtworks.xstream.io.naming.NameCoder; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; /** * A {@link HierarchicalStreamDriver} for XPP DOM using the XmlPullParserFactory to locate an parser. @@ -26,8 +25,6 @@ */ public class XppDomDriver extends AbstractXppDomDriver { - private static XmlPullParserFactory factory; - public XppDomDriver() { super(new XmlFriendlyNameCoder()); } @@ -47,13 +44,7 @@ super(replacer); } - /** - * {@inheritDoc} - */ protected synchronized XmlPullParser createParser() throws XmlPullParserException { - if (factory == null) { - factory = XmlPullParserFactory.newInstance(null, XppDomDriver.class); - } - return factory.newPullParser(); + return XppDriver.createDefaultParser(); } } diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDriver.java index 0aad911..6557b62 100644 --- a/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDriver.java +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDriver.java @@ -1,12 +1,12 @@ /* * Copyright (C) 2004, 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD * style license a copy of which has been included with this distribution in * the LICENSE.txt file. - * + * * Created on 08. March 2004 by Joe Walnes */ package com.thoughtworks.xstream.io.xml; @@ -50,12 +50,21 @@ } /** - * {@inheritDoc} + * Create a default XML Pull Parser. The method uses the Java Service API to get the registered + * {@link XmlPullParserFactory} and let it create a new parser. + * + * @return a new instance of an XML Pull Parser + * @throws XmlPullParserException if the creation of a new parser fails. + * @since 1.4.11 */ - protected synchronized XmlPullParser createParser() throws XmlPullParserException { + public static synchronized XmlPullParser createDefaultParser() throws XmlPullParserException { if (factory == null) { factory = XmlPullParserFactory.newInstance(); } return factory.newPullParser(); } + + protected XmlPullParser createParser() throws XmlPullParserException { + return createDefaultParser(); + } } diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationConfiguration.java b/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationConfiguration.java index 78e8263..9f5b99a 100644 --- a/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationConfiguration.java +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2013 XStream Committers. + * Copyright (C) 2007, 2008, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -15,7 +15,7 @@ * * @author Jörg Schaible * @since 1.3 - * @deprecated As of 1.4.5, minimal JDK version will be 1.6 for next major release + * @deprecated As of 1.4.5, minimal JDK version will be 1.7 for next major release */ public interface AnnotationConfiguration { diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/AttributeMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/AttributeMapper.java index 38ce6ae..1ea91ab 100644 --- a/xstream/src/java/com/thoughtworks/xstream/mapper/AttributeMapper.java +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/AttributeMapper.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -107,8 +107,8 @@ } else if (fieldNameToTypeMap.get(fieldName) == type) { return true; } else if (fieldName != null && definedIn != null) { - Field field = reflectionProvider.getField(definedIn, fieldName); - return fieldToUseAsAttribute.contains(field); + final Field field = reflectionProvider.getFieldOrNull(definedIn, fieldName); + return field != null && fieldToUseAsAttribute.contains(field); } return false; } @@ -140,8 +140,8 @@ * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} */ public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute) { - Field field = reflectionProvider.getField(definedIn, attribute); - return getConverterFromAttribute(definedIn, attribute, field.getType()); + final Field field = reflectionProvider.getFieldOrNull(definedIn, attribute); + return field != null ? getConverterFromAttribute(definedIn, attribute, field.getType()) : null; } public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute, Class type) { @@ -160,8 +160,10 @@ * @param field the field itself * @since 1.2.2 */ - public void addAttributeFor(Field field) { - fieldToUseAsAttribute.add(field); + public void addAttributeFor(final Field field) { + if (field != null) { + fieldToUseAsAttribute.add(field); + } } /** @@ -169,10 +171,9 @@ * * @param definedIn the declaring class of the field * @param fieldName the name of the field - * @throws IllegalArgumentException if the field does not exist * @since 1.3 */ public void addAttributeFor(Class definedIn, String fieldName) { - fieldToUseAsAttribute.add(reflectionProvider.getField(definedIn, fieldName)); + addAttributeFor(reflectionProvider.getField(definedIn, fieldName)); } } diff --git a/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java b/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java index b03598c..9de4979 100644 --- a/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java +++ b/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2015, 2017 XStream Committers. + * Copyright (C) 2012, 2015, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -41,7 +41,7 @@ } public void testDerivedConcurrentHashMap() { - if (JVM.is18()) { + if (JVM.isVersion(8)) { xstream.alias("derived-map", DerivedConcurrentHashMap.class); xstream.registerConverter(new MapConverter(xstream.getMapper(), DerivedConcurrentHashMap.class)); diff --git a/xstream/src/test/com/thoughtworks/acceptance/EncodingTestSuite.java b/xstream/src/test/com/thoughtworks/acceptance/EncodingTestSuite.java index 43d927a..38f1336 100644 --- a/xstream/src/test/com/thoughtworks/acceptance/EncodingTestSuite.java +++ b/xstream/src/test/com/thoughtworks/acceptance/EncodingTestSuite.java @@ -13,13 +13,12 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Properties; import javax.xml.stream.XMLInputFactory; - -import org.apache.commons.lang.SystemUtils; import com.bea.xml.stream.MXParserFactory; import com.thoughtworks.acceptance.objects.StandardObject; @@ -72,7 +71,7 @@ } } addDriverTest(new StaxDriver()); - if (!SystemUtils.IS_OS_WINDOWS) { // see comment below for Windows + if (File.separatorChar == '\\') { // see comment below for Windows if (JVM.is16()) { final Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.xml.StandardStaxDriver"); try { diff --git a/xstream/src/test/com/thoughtworks/acceptance/Extended14TypesTest.java b/xstream/src/test/com/thoughtworks/acceptance/Extended14TypesTest.java index 632e1f5..341effd 100644 --- a/xstream/src/test/com/thoughtworks/acceptance/Extended14TypesTest.java +++ b/xstream/src/test/com/thoughtworks/acceptance/Extended14TypesTest.java @@ -109,7 +109,7 @@ " \n" + " \n" + " \n" + - " MDYxEDAOBgNVBAsTB1hTdHJlYW0xFTATBgNVBAoTDFRob3VnaHR3b3JrczELMAkGA1UEBhMCdWs=\n\n" + + " MDYxEDAOBgNVBAsTB1hTdHJlYW0xFTATBgNVBAoTDFRob3VnaHR3b3JrczELMAkGA1UEBhMCdWs=\n" + " \n" + " \n" + " \n" + diff --git a/xstream/src/test/com/thoughtworks/acceptance/Extended17TypesTest.java b/xstream/src/test/com/thoughtworks/acceptance/Extended17TypesTest.java index 9ff4974..ff087af 100644 --- a/xstream/src/test/com/thoughtworks/acceptance/Extended17TypesTest.java +++ b/xstream/src/test/com/thoughtworks/acceptance/Extended17TypesTest.java @@ -39,18 +39,20 @@ assertBothWays(Paths.get("../a/relative/path"), "../a/relative/path"); assertBothWays(Paths.get("/an/absolute/path"), "/an/absolute/path"); - String absolutePathName = Paths.get("target").toAbsolutePath().toString(); + final Path absolutePath = Paths.get("target").toAbsolutePath(); + String absolutePathName = absolutePath.toString(); if (File.separatorChar != '/') { absolutePathName = absolutePathName.replace(File.separatorChar, '/'); } - final URI uri = URI.create("file:" + absolutePathName); - assertBothWays(Paths.get(uri), "" + absolutePathName + ""); + final Path path = Paths.get(absolutePath.toUri()); + assertBothWays(path, "" + absolutePathName + ""); } public void testPathWithSpecialCharacters() { assertBothWays(Paths.get("with space"), "with space"); assertBothWays(Paths.get("with+plus"), "with+plus"); assertBothWays(Paths.get("with&ersand"), "with&ampersand"); + assertBothWays(Paths.get("with%20encoding"), "with%20encoding"); } public void testPathOfNonDefaultFileSystem() throws IOException { diff --git a/xstream/src/test/com/thoughtworks/acceptance/MultipleObjectsInOneStreamTest.java b/xstream/src/test/com/thoughtworks/acceptance/MultipleObjectsInOneStreamTest.java index 902d9a4..99995f1 100644 --- a/xstream/src/test/com/thoughtworks/acceptance/MultipleObjectsInOneStreamTest.java +++ b/xstream/src/test/com/thoughtworks/acceptance/MultipleObjectsInOneStreamTest.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2005, 2006 Joe Walnes. - * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * Copyright (C) 2006, 2007, 2008, 2009, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -14,13 +14,16 @@ import com.thoughtworks.acceptance.objects.Software; import com.thoughtworks.acceptance.objects.StandardObject; import com.thoughtworks.xstream.MarshallingStrategy; +import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.ConverterLookup; import com.thoughtworks.xstream.converters.DataHolder; import com.thoughtworks.xstream.core.ReferenceByIdMarshaller; import com.thoughtworks.xstream.core.ReferenceByIdUnmarshaller; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.ReaderWrapper; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; +import com.thoughtworks.xstream.io.xml.Xpp3Driver; import com.thoughtworks.xstream.io.xml.XppReader; import com.thoughtworks.xstream.mapper.Mapper; import com.thoughtworks.xstream.testutil.CallLog; @@ -176,6 +179,60 @@ } } + private static class LevelTrackingReader extends ReaderWrapper { + private int level; + protected LevelTrackingReader(HierarchicalStreamReader reader) { + super(reader); + } + + public void moveDown() { + ++level; + super.moveDown(); + } + + public void moveUp() { + super.moveUp(); + --level; + } + + public int getLevel() { + return level; + } + } + + public void testFailSafeDeserialization() throws IOException, ClassNotFoundException { + final String xml = "" + + "\n" + + " top\n" + + " \n" + + " first\n" + + " \n" + + " 1\n" + + " invalid\n" // deserialization will fail here + + " 3\n" + + " \n" + + " last\n" + + " \n" + + " bottom\n" + + ""; + + final LevelTrackingReader reader = new LevelTrackingReader(new Xpp3Driver().createReader(new StringReader(xml))); + final ObjectInputStream ois = xstream.createObjectInputStream(reader); + final int level = reader.getLevel(); + assertEquals("top", ois.readObject()); + try { + ois.readObject(); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ConversionException e) { + assertEquals(3, reader.getLevel() - level); + do { + reader.moveUp(); + } while (level != reader.getLevel()); + } + assertEquals("bottom", ois.readObject()); + ois.close(); + } + public void testObjectOutputStreamPropagatesCloseAndFlushEvents() throws IOException { // setup final CallLog log = new CallLog(); @@ -303,4 +360,38 @@ assertSame(alice, jane.secretary); } + + public void testReadUnsignedValuesFromInputStream() throws IOException { + final Writer writer = new StringWriter(); + final ObjectOutputStream oos = xstream.createObjectOutputStream(writer); + oos.writeByte(1); + oos.writeByte(-1); + oos.writeByte(Byte.MIN_VALUE); + oos.writeShort(1); + oos.writeShort(-1); + oos.writeShort(Short.MIN_VALUE); + oos.close(); + + final String expectedXml = "" + + "\n" + + " 1\n" + + " -1\n" + + " -128\n" + + " 1\n" + + " -1\n" + + " -32768\n" + + ""; + + assertEquals(expectedXml, writer.toString()); + + final ObjectInputStream ois = xstream.createObjectInputStream(new StringReader(writer.toString())); + assertEquals(1, ois.readUnsignedByte()); + assertEquals(255, ois.readUnsignedByte()); + assertEquals(128, ois.readUnsignedByte()); + assertEquals(1, ois.readUnsignedShort()); + assertEquals(65535, ois.readUnsignedShort()); + assertEquals(32768, ois.readUnsignedShort()); + + ois.close(); + } } diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java index 56f033e..85eaf1c 100644 --- a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java +++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013, 2014, 2017 XStream Committers. + * Copyright (C) 2013, 2014, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -12,6 +12,7 @@ import java.beans.EventHandler; +import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.XStreamException; import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; @@ -51,6 +52,29 @@ fail("Thrown " + XStreamException.class.getName() + " expected"); } catch (final XStreamException e) { assertTrue(e.getMessage().indexOf(EventHandler.class.getName()) > 0); + } + assertEquals(0, BUFFER.length()); + } + + public void testCannotInjectEventHandlerWithUnconfiguredSecurityFramework() { + xstream = new XStream(createDriver()); + xstream.alias("runnable", Runnable.class); + final String xml = "" + + "\n" + + " \n" + + " java.lang.Runnable\n" + + " \n" + + " \n" + + " exec\n" + + " \n" + + " \n" + + ""; + + try { + xstream.fromXML(xml); + fail("Thrown " + XStreamException.class.getName() + " expected"); + } catch (final XStreamException e) { + assertTrue(e.getMessage().indexOf(EventHandler.class.getName())>=0); } assertEquals(0, BUFFER.length()); } diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverterTest.java index a8e25bf..2f122a1 100644 --- a/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverterTest.java +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverterTest.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2005 Joe Walnes. - * Copyright (C) 2006, 2007, 2011, 2017 XStream Committers. + * Copyright (C) 2006, 2007, 2011, 2017, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -290,7 +290,7 @@ expected.set(Calendar.YEAR, 2017); Calendar out = (Calendar)converter.fromString("2017"); assertEquals(expected.getTime(), out.getTime()); - if (JVM.is18()) { // Java 8 passes, Joda-Time fails + if (JVM.isVersion(8)) { // Java 8 passes, Joda-Time fails expected.set(Calendar.MONTH, 3); out = (Calendar)converter.fromString("2017-04"); assertEquals(expected.getTime(), out.getTime()); @@ -300,7 +300,7 @@ public void testParsesStandardWeekDateFragment() { final Calendar expected = Calendar.getInstance(); expected.clear(); - if (!JVM.is18()) { // TODO: Java 8 fails here, Joda-Time passes + if (!JVM.isVersion(8)) { // TODO: Java 8 fails here, Joda-Time passes expected.set(2017, 3, 17); final Calendar out = (Calendar)converter.fromString("2017-W16"); assertEquals(expected.getTime(), out.getTime()); diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorterTest.java index 7919a8f..84b985b 100644 --- a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorterTest.java +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 XStream Committers. + * Copyright (C) 2007, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -53,7 +53,10 @@ while (!cls.equals(Object.class)) { Field[] fields = cls.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { - Field field = fields[i]; + final Field field = fields[i]; + if (field.getName().startsWith("$jacoco")) { + continue; + } map.put(new FieldKey(field.getName(), cls, i), field); } cls = cls.getSuperclass(); diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorterTest.java index 914ef3d..d063489 100644 --- a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorterTest.java +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2016 XStream Committers. + * Copyright (C) 2007, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -73,7 +73,10 @@ while (!cls.equals(Object.class)) { Field[] fields = cls.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { - Field field = fields[i]; + final Field field = fields[i]; + if (field.getName().startsWith("$jacoco")) { + continue; + } map.put(new FieldKey(field.getName(), cls, i), field); } cls = cls.getSuperclass(); diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/Base64EncoderTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/Base64EncoderTest.java index eff4d8e..0e51ff3 100644 --- a/xstream/src/test/com/thoughtworks/xstream/core/util/Base64EncoderTest.java +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/Base64EncoderTest.java @@ -1,93 +1,177 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007 XStream Committers. + * Copyright (C) 2006, 2007, 2017 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD * style license a copy of which has been included with this distribution in * the LICENSE.txt file. - * + * * Created on 06. August 2004 by Joe Walnes */ package com.thoughtworks.xstream.core.util; import com.thoughtworks.acceptance.AbstractAcceptanceTest; + public class Base64EncoderTest extends AbstractAcceptanceTest { - private Base64Encoder encoder = new Base64Encoder(); + private Base64Encoder encoder = new Base64Encoder(true); public void testEncodesEntireByteArrayAsString() { - byte input[] = "hello world".getBytes(); - String expected = "aGVsbG8gd29ybGQ="; + final byte input[] = "hello world".getBytes(); + final String expected = "aGVsbG8gd29ybGQ="; assertEquals(expected, encoder.encode(input)); assertByteArrayEquals(input, encoder.decode(expected)); } public void testWrapsLinesAt76Chars() { - byte input[] = ("hello world. hello world. hello world. hello world. hello world. hello world. hello world. " - + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. ").getBytes(); - String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" - + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3Js\n" - + "ZC4gaGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhl\n" - + "bGxvIHdvcmxkLiA="; + final byte input[] = + ("hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. ") + .getBytes(); + final String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3Js\n" + + "ZC4gaGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhl\n" + + "bGxvIHdvcmxkLiA="; assertEquals(expected, encoder.encode(input)); assertByteArrayEquals(input, encoder.decode(expected)); } + public void testExactly76Chars() { + final byte input[] = "hello world. hello world. hello world. hello world. hello".getBytes(); + final String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv"; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testModeWithoutLineWraps() { + final byte input[] = + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + .getBytes(); + final String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; + encoder = new Base64Encoder(false); + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testDecodesLinesWithLF() { + final byte data[] = + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + .getBytes(); + final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; + encoder = new Base64Encoder(false); + assertByteArrayEquals(data, encoder.decode(input)); + } + + public void testDecodesLinesWithCRLF() { + final byte data[] = + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + .getBytes(); + final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\r\n" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; + encoder = new Base64Encoder(false); + assertByteArrayEquals(data, encoder.decode(input)); + } + + public void testDecodesUnwrappedLines() { + final byte data[] = + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + .getBytes(); + final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; + encoder = new Base64Encoder(false); + assertByteArrayEquals(data, encoder.decode(input)); + } + + public void testDecodesShortLines() { + final byte data[] = "hello world".getBytes(); + final String input = "aGVs\nbG8g\nd29y\nbGQ="; + assertByteArrayEquals(data, encoder.decode(input)); + } + public void testPadsSingleMissingByteWhenNotMultipleOfThree() { - byte input[] = { 1, 2, 3, 4, 5 }; - String expected = "AQIDBAU="; + final byte input[] = {1, 2, 3, 4, 5}; + final String expected = "AQIDBAU="; assertEquals(expected, encoder.encode(input)); assertByteArrayEquals(input, encoder.decode(expected)); } public void testPadsDoubleMissingByteWhenNotMultipleOfThree() { - byte input[] = { 1, 2, 3, 4 }; - String expected = "AQIDBA=="; + final byte input[] = {1, 2, 3, 4}; + final String expected = "AQIDBA=="; assertEquals(expected, encoder.encode(input)); assertByteArrayEquals(input, encoder.decode(expected)); } public void testDoesNotPadWhenMultipleOfThree() { - byte input[] = { 1, 2, 3, 4, 5, 6 }; - String expected = "AQIDBAUG"; + final byte input[] = {1, 2, 3, 4, 5, 6}; + final String expected = "AQIDBAUG"; assertEquals(expected, encoder.encode(input)); assertByteArrayEquals(input, encoder.decode(expected)); } public void testHandlesAllPositiveBytes() { - byte input[] = new byte[127]; - for (int i = 0; i < 126; i++) input[i] = (byte) (i + 1); - String expected = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5\n" - + "Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFy\n" - + "c3R1dnd4eXp7fH1+AA=="; + final byte input[] = new byte[127]; + for (int i = 0; i < 126; i++) { + input[i] = (byte)(i + 1); + } + final String expected = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5\n" + + "Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFy\n" + + "c3R1dnd4eXp7fH1+AA=="; assertEquals(expected, encoder.encode(input)); assertByteArrayEquals(input, encoder.decode(expected)); } public void testHandlesAllNegativeBytes() { - byte input[] = new byte[128]; - for (int i = 0; i < 127; i++) input[i] = (byte) (-1 - i); - String expected = "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjH\n" - + "xsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+O\n" - + "jYyLiomIh4aFhIOCgQA="; + final byte input[] = new byte[128]; + for (int i = 0; i < 127; i++) { + input[i] = (byte)(-1 - i); + } + final String expected = "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjH\n" + + "xsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+O\n" + + "jYyLiomIh4aFhIOCgQA="; assertEquals(expected, encoder.encode(input)); assertByteArrayEquals(input, encoder.decode(expected)); } public void testHandlesZeroByte() { - byte input[] = { 0, 0, 0, 0 }; - String expected = "AAAAAA=="; + final byte input[] = {0, 0, 0, 0}; + final String expected = "AAAAAA=="; assertEquals(expected, encoder.encode(input)); assertByteArrayEquals(input, encoder.decode(expected)); } public void testProducesEmptyStringWhenNoBytesGiven() { - byte input[] = new byte[0]; - String expected = ""; + final byte input[] = new byte[0]; + final String expected = ""; assertEquals(expected, encoder.encode(input)); assertByteArrayEquals(input, encoder.decode(expected)); } + public void testInitializeStringBufferWithExpectedSizeUsing6BytesInput() throws Exception { + final byte input[] = {1, 2, 3, 4, 5, 6}; + assertEquals(encoder.encode(input).length(), encoder.computeResultingStringSize(input)); + } + + public void testInitializeStringBufferWithExpectedSizeUsing1BytesInput() throws Exception { + final byte input[] = {1}; + assertEquals(encoder.encode(input).length(), encoder.computeResultingStringSize(input)); + } + + public void testInitializeStringBufferWithExpectedSizeUsing4BytesInput() throws Exception { + final byte input[] = {1, 2, 3, 4}; + assertEquals(encoder.encode(input).length(), encoder.computeResultingStringSize(input)); + } + + public void testInitializeStringBufferWithExpectedSizeUsing140BytesInput() throws Exception { + final byte input[] = new byte[140]; + for (int i = 0; i < 139; i++) { + input[i] = (byte)(i + 1); + } + assertEquals(encoder.encode(input).length(), encoder.computeResultingStringSize(input)); + } + } diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/Base64JAXBCodecTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/Base64JAXBCodecTest.java new file mode 100644 index 0000000..c5df409 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/Base64JAXBCodecTest.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2017 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. August 2017 Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.core.StringCodec; + + +public class Base64JAXBCodecTest extends AbstractAcceptanceTest { + + private StringCodec encoder = new Base64JAXBCodec(); + + public void testEncodesEntireByteArrayAsString() { + final byte input[] = "hello world".getBytes(); + final String expected = "aGVsbG8gd29ybGQ="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testModeWithoutLineWraps() { + final byte input[] = + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + .getBytes(); + final String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testDecodesLinesWithLF() { + final byte data[] = + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + .getBytes(); + final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; + assertByteArrayEquals(data, encoder.decode(input)); + } + + public void testDecodesLinesWithCRLF() { + final byte data[] = + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + .getBytes(); + final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\r\n" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; + assertByteArrayEquals(data, encoder.decode(input)); + } + + public void testDecodesShortLines() { + final byte data[] = "hello world".getBytes(); + final String input = "aGVs\nbG8g\nd29y\nbGQ="; + assertByteArrayEquals(data, encoder.decode(input)); + } + + public void testPadsSingleMissingByteWhenNotMultipleOfThree() { + final byte input[] = {1, 2, 3, 4, 5}; + final String expected = "AQIDBAU="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testPadsDoubleMissingByteWhenNotMultipleOfThree() { + final byte input[] = {1, 2, 3, 4}; + final String expected = "AQIDBA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testDoesNotPadWhenMultipleOfThree() { + final byte input[] = {1, 2, 3, 4, 5, 6}; + final String expected = "AQIDBAUG"; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testHandlesAllPositiveBytes() { + final byte input[] = new byte[127]; + for (int i = 0; i < 126; i++) { + input[i] = (byte)(i + 1); + } + final String expected = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5" + + "Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFy" + + "c3R1dnd4eXp7fH1+AA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testHandlesAllNegativeBytes() { + final byte input[] = new byte[128]; + for (int i = 0; i < 127; i++) { + input[i] = (byte)(-1 - i); + } + final String expected = "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjH" + + "xsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+O" + + "jYyLiomIh4aFhIOCgQA="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testHandlesZeroByte() { + final byte input[] = {0, 0, 0, 0}; + final String expected = "AAAAAA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testProducesEmptyStringWhenNoBytesGiven() { + final byte input[] = new byte[0]; + final String expected = ""; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/Base64JavaUtilCodecTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/Base64JavaUtilCodecTest.java new file mode 100644 index 0000000..c09806f --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/Base64JavaUtilCodecTest.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2017 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. August 2017 Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.core.StringCodec; + + +public class Base64JavaUtilCodecTest extends AbstractAcceptanceTest { + + private StringCodec encoder = new Base64JavaUtilCodec(); + + public void testEncodesEntireByteArrayAsString() { + final byte input[] = "hello world".getBytes(); + final String expected = "aGVsbG8gd29ybGQ="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testModeWithoutLineWraps() { + final byte input[] = + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + .getBytes(); + final String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testDecodesLinesWithLF() { + final byte data[] = + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + .getBytes(); + final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; + assertByteArrayEquals(data, encoder.decode(input)); + } + + public void testDecodesLinesWithCRLF() { + final byte data[] = + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + .getBytes(); + final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\r\n" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; + assertByteArrayEquals(data, encoder.decode(input)); + } + + public void testDecodesShortLines() { + final byte data[] = "hello world".getBytes(); + final String input = "aGVs\nbG8g\nd29y\nbGQ="; + assertByteArrayEquals(data, encoder.decode(input)); + } + + public void testPadsSingleMissingByteWhenNotMultipleOfThree() { + final byte input[] = {1, 2, 3, 4, 5}; + final String expected = "AQIDBAU="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testPadsDoubleMissingByteWhenNotMultipleOfThree() { + final byte input[] = {1, 2, 3, 4}; + final String expected = "AQIDBA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testDoesNotPadWhenMultipleOfThree() { + final byte input[] = {1, 2, 3, 4, 5, 6}; + final String expected = "AQIDBAUG"; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testHandlesAllPositiveBytes() { + final byte input[] = new byte[127]; + for (int i = 0; i < 126; i++) { + input[i] = (byte)(i + 1); + } + final String expected = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5" + + "Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFy" + + "c3R1dnd4eXp7fH1+AA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testHandlesAllNegativeBytes() { + final byte input[] = new byte[128]; + for (int i = 0; i < 127; i++) { + input[i] = (byte)(-1 - i); + } + final String expected = "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjH" + + "xsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+O" + + "jYyLiomIh4aFhIOCgQA="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testHandlesZeroByte() { + final byte input[] = {0, 0, 0, 0}; + final String expected = "AAAAAA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testProducesEmptyStringWhenNoBytesGiven() { + final byte input[] = new byte[0]; + final String expected = ""; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/XppReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/XppReaderTest.java index 7852882..7624fb6 100644 --- a/xstream/src/test/com/thoughtworks/xstream/io/xml/XppReaderTest.java +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/XppReaderTest.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Joe Walnes. - * Copyright (C) 2006, 2007, 2015, 2016 XStream Committers. + * Copyright (C) 2006, 2007, 2015, 2016, 2018 XStream Committers. * All rights reserved. * * The software in this package is published under the terms of the BSD @@ -18,7 +18,7 @@ public class XppReaderTest extends AbstractXMLReaderTest { protected HierarchicalStreamReader createReader(String xml) throws Exception { - return new XppReader(new StringReader(xml)); + return new XppReader(new StringReader(xml), XppDriver.createDefaultParser()); } public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { diff --git a/xstream-benchmark/pom.xml b/xstream-benchmark/pom.xml index 88a273a..f8eeb01 100644 --- a/xstream-benchmark/pom.xml +++ b/xstream-benchmark/pom.xml @@ -14,7 +14,7 @@ com.thoughtworks.xstream xstream-parent - 1.4.10 + 1.4.11 xstream-benchmark jar @@ -50,7 +50,7 @@ false ${version.java.source} - ${link.javadoc.javase} + ${javadoc.link.javase} @@ -58,9 +58,9 @@ - jdk15-ge + jdk16-ge - [1.5,) + [1.6,) diff --git a/xstream-distribution/pom.xml b/xstream-distribution/pom.xml index 3b25118..5119b59 100644 --- a/xstream-distribution/pom.xml +++ b/xstream-distribution/pom.xml @@ -14,7 +14,7 @@ com.thoughtworks.xstream xstream-parent - 1.4.10 + 1.4.11 xstream-distribution pom diff --git a/xstream-distribution/src/content/CVE-2013-7285.html b/xstream-distribution/src/content/CVE-2013-7285.html index e6263f1..fa4cb59 100644 --- a/xstream-distribution/src/content/CVE-2013-7285.html +++ b/xstream-distribution/src/content/CVE-2013-7285.html @@ -1,6 +1,6 @@ + +

1.4.11

+ +

Released October 23, 2018.

+ +

This maintenance release addresses again the security vulnerability + CVE-2013-7285, an arbitrary execution of commands when unmarshalling for XStream instances with + uninitialized security framework. Only 1.4.10 uninitialized security framework was affected.

+ +

Minor changes

+ +
    +
  • GHPR:#91, GHPR:#106: Clean-up data stacks in UnmarshallingContext implementations in case of exception (by + Määrt Bakhoff).
  • +
  • GHI:#2: Unneeded contention in DefaultConverterLookup.
  • +
  • GHI:#94: Fix PathConverter containing absolute Windows paths.
  • +
  • GHI:#105: XStream's ObjectInputStream returns wrong values for readUnsignedByte and readUnsignedShort.
  • +
  • JIRA:XSTR-616 and GHPR:#93: Introduce StringCodec interface to support arbitrary Base64 codec + implementations for EncodedByteArrayConverter. Prefer Base64 codec implementations of the Java runtime over + XStream's own one.
  • +
  • GHI:#97: Support to run out of the box in a Java 1.4 runtime is established again.
  • +
  • Provide methods in AbstractCollectionConverter that read and write in a balanced way from and to the + hierarchical stream.
  • +
  • New future-proof method JVM.isVersion to detect major version of Java runtime (incl. Java 10) as + replacement for individual JVM.isXY methods.
  • +
  • GHI:#115: Dom4JDriver ignores character set of Dom4J configuration creating a Writer.
  • +
  • GHI:#116: Make converters null safe.
  • +
  • GHI:#123 and GHPR:#124: Declare XPP dependencies for OSGi as optional.
  • +
  • Add XppDriver.createDefaultParser for a simpler access to the default XmlPullParserFactory.
  • +
  • Old BEA reference implementation of StAX is outdated, unmaintained and has security issues, therefore + XStream's driver has been deprecated.
  • +
  • Support for JaCoCo: FieldDictionary ignores synthetic fields starting with $jacoco as name.
  • +
+ +

Stream compatibility

+ +
    +
  • The EncodedByteArrayConverter will now use an encoder by default that does no longer add line breaks as + normally required by the RFC 1521 after 76 characters, making it also easier to use the converter for + attributes. This will not affect XStream's Base64 decoder.
  • +
+ +

API changes

+ +
    +
  • Added c.t.x.converters.collection.AbstractCollectionConverter.readBareItem(HierarchicalStreamReader, UnmarshallingContext, Object).
  • +
  • Added c.t.x.converters.collection.AbstractCollectionConverter.readCompleteItem(HierarchicalStreamReader, UnarshallingContext, Object).
  • +
  • Deprecated c.t.x.converters.collection.AbstractCollectionConverter.readItem(HierarchicalStreamReader, UnmarshallingContext, Object).
  • +
  • Added c.t.x.converters.collection.AbstractCollectionConverter.writeBareItem(Object, MarshallingContext, HierarchicalStreamWriter).
  • +
  • Added c.t.x.converters.collection.AbstractCollectionConverter.writeCompleteItem(Object, MarshallingContext, HierarchicalStreamWriter).
  • +
  • Deprecated c.t.x.converters.collection.AbstractCollectionConverter.writeItem(Object, MarshallingContext, HierarchicalStreamWriter).
  • +
  • Added c.t.x.converters.collection.AbstractCollectionConverter.writeNullItem(MarshallingContext, HierarchicalStreamWriter).
  • +
  • Added c.t.x.converters.extended.EncodedByteArrayConverter(StingCodec).
  • +
  • Added c.t.x.converters.extended.NamedCollectionConverter.readBareItem(HierarchicalStreamReader, UnmarshallingContext, Object).
  • +
  • Deprecated c.t.x.converters.extended.NamedCollectionConverter.readItem(HierarchicalStreamReader, UnmarshallingContext, Object).
  • +
  • Added c.t.x.converters.extended.NamedCollectionConverter.writeCompleteItem(Object, MarshallingContext, HierarchicalStreamWriter).
  • +
  • Deprecated c.t.x.converters.extended.NamedCollectionConverter.writeItem(Object, MarshallingContext, HierarchicalStreamWriter).
  • +
  • Added c.t.x.core.DefaultConverterLookup(Map).
  • +
  • Added c.t.x.core.util.JVM.getBase64Codec().
  • +
  • Added c.t.x.core.util.JVM.isVersion().
  • +
  • Deprecated c.t.x.core.util.JVM.is18().
  • +
  • Deprecated c.t.x.core.util.JVM.is9().
  • +
  • Deprecated c.t.x.io.ExtendedHierarchicalStreamReader.
  • +
  • Deprecated c.t.x.io.ExtendedHierarchicalStreamWriter.
  • +
  • Deprecated c.t.x.io.ExtendedHierarchicalStreamWriterHelper.
  • +
  • Deprecated c.t.x.io.xml.BEAStaxDriver.
  • +
  • Added c.t.x.io.xml.Dom4JReader.Dom4JReader(Branch).
  • +
  • Added c.t.x.io.xml.XppDriver.createDefaultParser().
  • +
  • Added c.t.x.core.util.StingCodec.
  • +
+

1.4.10

Released May 23, 2017.

@@ -38,6 +114,8 @@

Major changes

    +
  • GHI:#84: New XStream artifact with -java7 appended as version suffix for a library explicitly + without the Java 8 stuff (lambda expression support, converters for java.time.* package).
  • Fix PrimitiveTypePermission to reject type void to prevent CVE-2017-7957 with an initialized security framework.
  • Improve performance by minimizing call stack of mapper chain.
  • diff --git a/xstream-distribution/src/content/download.html b/xstream-distribution/src/content/download.html index 181e43f..6dbc60d 100644 --- a/xstream-distribution/src/content/download.html +++ b/xstream-distribution/src/content/download.html @@ -1,7 +1,7 @@

    Previous Releases

    @@ -68,6 +46,12 @@

    Optional Dependencies

    +

    Note, that all those dependencies can be optional. XStream uses by default the XPP API in combination with the + Xpp3 implementation. Therefore are these dependencies not declared as optional in Maven. However, depending on your + choice of the XML parser, you can exclude the dependencies for the XPP API (e.g. by selecting Xpp3 directly) or + Xpp3 (e.g. by selecting StAX). You will then have to declare the dependencies for the alternative XML parser + yourself unless you use a parser form the Java runtime.

    +
    • Supported XML parsers and packages:
        @@ -84,6 +68,7 @@
      • Other optional 3rd party dependencies:
          +
        • Java Activation module for the ActivationDataFlavorConverter. The dependency is required for the Java 11 runtime.
        • Joda Time for optional ISO8601 date/time converters in JDK 1.7 or below.
        • CGLIB for optional support of some proxies generated with the CGLIB Enhancer.
        • Jettison for serialization and deserialization support with JSON. Note, that newer versions 1.3.x are no longer compatible with XStream.
        • diff --git a/xstream-distribution/src/content/faq.html b/xstream-distribution/src/content/faq.html index cbb8e75..69c19ce 100644 --- a/xstream-distribution/src/content/faq.html +++ b/xstream-distribution/src/content/faq.html @@ -113,6 +113,9 @@ Android, it is not possible to use the original XStream library directly, because it tries to convert all classes of XStream to the Dalvik runtime. You might have to build a custom version of XStream (see BUILD.txt) with a JDK that is equivalent to the Java level supported by the target version of Android.

          + +

          Since XStream 1.4.10 an additional artifact is deployed to the Central Maven Repository with -java7 + appended to the version that explicitly does not contain any Java 8 related stuff.

          Which limits exists for XStream in Google's Application Engine (GAE)?

          diff --git a/xstream-distribution/src/content/index.html b/xstream-distribution/src/content/index.html index 65aace7..34b42d7 100644 --- a/xstream-distribution/src/content/index.html +++ b/xstream-distribution/src/content/index.html @@ -1,7 +1,7 @@ xpp3 @@ -172,6 +223,10 @@ org.codehaus.jettison jettison runtime + + + javax.xml.bind + jaxb-api diff --git a/xstream-jmh/src/java/com/thoughtworks/xstream/benchmark/jmh/Base64Benchmark.java b/xstream-jmh/src/java/com/thoughtworks/xstream/benchmark/jmh/Base64Benchmark.java new file mode 100644 index 0000000..3118603 --- /dev/null +++ b/xstream-jmh/src/java/com/thoughtworks/xstream/benchmark/jmh/Base64Benchmark.java @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2017, 2018 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. July 2017 by Joerg Schaible + */ +package com.thoughtworks.xstream.benchmark.jmh; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.concurrent.TimeUnit; + +import javax.xml.bind.DatatypeConverter; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; + +import com.thoughtworks.xstream.core.StringCodec; +import com.thoughtworks.xstream.core.util.Base64Encoder; + + +/** + * Benchmark for different Base64 encoder and decoder implementations. Each implementation can be used by the + * EncodedByteArrayConverter. + * + * @author Jörg Schaible + * @since 1.4.11 + */ +@BenchmarkMode(Mode.AverageTime) +@Fork(value = 1) +@Measurement(iterations = 16) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Benchmark) +@Threads(4) +@Warmup(iterations = 5) +public class Base64Benchmark { + + /** + * Enumeration for the operation of the base 64 coder. + * + * @since 1.4.11 + */ + public static enum Operation { + /** + * Encoding operation. + */ + encode, + /** + * Decoding operation. + */ + decode + } + + /** + * Enumeration for the different base 64 coder. + * + * @since 1.4.11 + */ + public static enum Codec implements StringCodec { + /** + * XStream's own codec. + */ + xstreamInternal { + final private Base64Encoder codec = new Base64Encoder(false); + + @Override + public byte[] decode(final String base64) { + return codec.decode(base64); + } + + @Override + public String encode(final byte[] data) { + return codec.encode(data); + } + }, + /** + * Codec of JAXB, part of the Java runtime since 1.6. + */ + dataTypeConverter { + + @Override + public byte[] decode(final String base64) { + return DatatypeConverter.parseBase64Binary(base64); + } + + @Override + public String encode(final byte[] data) { + return DatatypeConverter.printBase64Binary(data); + } + + }, + /** + * Official codec of the Java runtime since 1.8. + */ + javaUtil { + final private java.util.Base64.Decoder decoder = java.util.Base64.getDecoder(); + final private java.util.Base64.Encoder encoder = java.util.Base64.getEncoder(); + + @Override + public byte[] decode(final String base64) { + return decoder.decode(base64); + } + + @Override + public String encode(final byte[] data) { + return encoder.encodeToString(data); + } + }, + /** + * Codec of Apache Commons Codec. + */ + commonsCodec { + + @Override + public byte[] decode(final String base64) { + return org.apache.commons.codec.binary.Base64.decodeBase64(base64); + } + + @Override + public String encode(final byte[] data) { + return org.apache.commons.codec.binary.Base64.encodeBase64String(data); + } + }, + /** + * Codec of MiGBase64, repackaged by brsanthu. + */ + migBase { + + @Override + public byte[] decode(final String base64) { + return com.migcomponents.migbase64.Base64.decode(base64); + } + + @Override + public String encode(final byte[] data) { + return com.migcomponents.migbase64.Base64.encodeToString(data, false); + } + + }; + + // to please Eclipse with JDK 5 target + public abstract byte[] decode(String encoded); + public abstract String encode(byte[] data); + } + + /** + * Enumeration for the different data sets. + * + * @since 1.4.11 + */ + public static enum Data { + /** + * Small data (16 bytes). + */ + small(16), + /** + * Medium data (4KB) + */ + medium(4096), + /** + * Big data (1MB) + */ + big(1024 * 1024); + private Data(final int length) { + data = getRandomBytes(length); + base64 = Codec.xstreamInternal.encode(data); + } + + private final String base64; + private final byte[] data; + + /** + * Get the encoded data as string. + * + * @return the encoded string + * @since 1.4.11 + */ + public String getBase64() { + return base64; + } + + /** + * Get the data to encode + * + * @return the data + * @since 1.4.11 + */ + public byte[] getData() { + return data; + } + + static { + final int lengths[] = {0, 1, 2, 3, 8, 65, 256, 4095, 1000000}; + final byte data[][] = new byte[lengths.length][]; + final String base64[] = new String[lengths.length]; + for (int i = 0; i < lengths.length; ++i) { + final int length = lengths[i]; + final byte[] orig = getRandomBytes(length); + for (final Codec codec : EnumSet.allOf(Codec.class)) { + if (base64[i] == null) { + base64[i] = codec.encode(orig); + data[i] = codec.decode(base64[i]); + assert Arrays.equals(data[i], orig); + } else { + assert base64[i].equals(codec.encode(orig)) : "Base64 differs for " + + codec + + ": <" + + base64[i] + + "> vs. <" + + codec.encode(orig) + + ">"; + } + } + } + } + + private static byte[] getRandomBytes(final int length) { + final char[] ch = new char[length]; + for (int j = 0; j < length; ++j) { + ch[j] = Character.valueOf((char)(Math.round(Math.random() * 254) + 1)); + } + final byte[] orig = new String(ch).getBytes(StandardCharsets.UTF_8); + return orig; + } + } + + @Param + private Codec codec; + @Param + private Operation operation; + @Param + private Data data; + + /** + * Encode and decode data. + * + * @since 1.4.11 + */ + @Benchmark + public void run() { + switch (operation) { + case encode: + codec.encode(data.getData()); + break; + case decode: + codec.decode(data.getBase64()); + break; + } + } +} diff --git a/xstream-jmh/src/reference/base64.txt b/xstream-jmh/src/reference/base64.txt new file mode 100644 index 0000000..928d9ec --- /dev/null +++ b/xstream-jmh/src/reference/base64.txt @@ -0,0 +1,31 @@ +Benchmark (codec) (data) (operation) Mode Cnt Score Error Units +Base64Benchmark.run xstreamInternal small encode avgt 16 370.353 ± 26.364 ns/op +Base64Benchmark.run xstreamInternal small decode avgt 16 387.549 ± 2.753 ns/op +Base64Benchmark.run xstreamInternal medium encode avgt 16 75746.500 ± 388.028 ns/op +Base64Benchmark.run xstreamInternal medium decode avgt 16 69507.593 ± 4615.284 ns/op +Base64Benchmark.run xstreamInternal big encode avgt 16 21809550.623 ± 287457.190 ns/op +Base64Benchmark.run xstreamInternal big decode avgt 16 22860405.161 ± 116129.778 ns/op +Base64Benchmark.run dataTypeConverter small encode avgt 16 113.739 ± 6.015 ns/op +Base64Benchmark.run dataTypeConverter small decode avgt 16 146.704 ± 7.826 ns/op +Base64Benchmark.run dataTypeConverter medium encode avgt 16 27994.835 ± 250.706 ns/op +Base64Benchmark.run dataTypeConverter medium decode avgt 16 31775.991 ± 997.564 ns/op +Base64Benchmark.run dataTypeConverter big encode avgt 16 11212057.101 ± 316407.971 ns/op +Base64Benchmark.run dataTypeConverter big decode avgt 16 7831267.697 ± 26381.875 ns/op +Base64Benchmark.run javaUtil small encode avgt 16 119.151 ± 0.623 ns/op +Base64Benchmark.run javaUtil small decode avgt 16 222.355 ± 10.904 ns/op +Base64Benchmark.run javaUtil medium encode avgt 16 19877.310 ± 1172.332 ns/op +Base64Benchmark.run javaUtil medium decode avgt 16 32920.559 ± 274.879 ns/op +Base64Benchmark.run javaUtil big encode avgt 16 9205883.279 ± 269329.433 ns/op +Base64Benchmark.run javaUtil big decode avgt 16 8964062.065 ± 394932.790 ns/op +Base64Benchmark.run commonsCodec small encode avgt 16 3416.205 ± 3.382 ns/op +Base64Benchmark.run commonsCodec small decode avgt 16 3514.384 ± 11.939 ns/op +Base64Benchmark.run commonsCodec medium encode avgt 16 78348.010 ± 2924.398 ns/op +Base64Benchmark.run commonsCodec medium decode avgt 16 74262.708 ± 3031.596 ns/op +Base64Benchmark.run commonsCodec big encode avgt 16 22347368.903 ± 178585.361 ns/op +Base64Benchmark.run commonsCodec big decode avgt 16 23798441.056 ± 195917.888 ns/op +Base64Benchmark.run migBase small encode avgt 16 113.382 ± 5.283 ns/op +Base64Benchmark.run migBase small decode avgt 16 171.957 ± 1.520 ns/op +Base64Benchmark.run migBase medium encode avgt 16 25132.013 ± 313.813 ns/op +Base64Benchmark.run migBase medium decode avgt 16 34109.501 ± 834.604 ns/op +Base64Benchmark.run migBase big encode avgt 16 10762327.746 ± 32072.333 ns/op +Base64Benchmark.run migBase big decode avgt 16 8194853.894 ± 34107.972 ns/op diff --git a/xstream-jmh/src/reference/converterType.txt b/xstream-jmh/src/reference/converterType.txt index c6990dd..95ea704 100644 --- a/xstream-jmh/src/reference/converterType.txt +++ b/xstream-jmh/src/reference/converterType.txt @@ -1,4 +1,4 @@ Benchmark Mode Cnt Score Error Units -ConverterTypeBenchmark.custom avgt 16 9827295.423 ± 216353.603 ns/op -ConverterTypeBenchmark.javaBean avgt 16 18939434.561 ± 196809.719 ns/op -ConverterTypeBenchmark.reflection avgt 16 19450925.166 ± 181312.751 ns/op +ConverterTypeBenchmark.custom avgt 16 9176744.283 ± 596076.907 ns/op +ConverterTypeBenchmark.javaBean avgt 16 18353984.976 ± 1308243.279 ns/op +ConverterTypeBenchmark.reflection avgt 16 23371721.858 ± 145348.676 ns/op diff --git a/xstream-jmh/src/reference/nameCoder.txt b/xstream-jmh/src/reference/nameCoder.txt index 4835d08..dd54d2c 100644 --- a/xstream-jmh/src/reference/nameCoder.txt +++ b/xstream-jmh/src/reference/nameCoder.txt @@ -1,6 +1,6 @@ Benchmark Mode Cnt Score Error Units -NameCoderBenchmark.cachedEscapedUnderscoreCoding avgt 25 4531410.494 ± 128534.700 ns/op -NameCoderBenchmark.dollarCoding avgt 25 4635671.256 ± 154209.189 ns/op -NameCoderBenchmark.escapedUnderscoreCoding avgt 25 5974244.102 ± 68996.714 ns/op -NameCoderBenchmark.noCoding avgt 25 4057270.642 ± 50166.734 ns/op -NameCoderBenchmark.xmlFriendlyCoding avgt 25 4953594.706 ± 98502.894 ns/op +NameCoderBenchmark.cachedEscapedUnderscoreCoding avgt 25 4350643.046 ± 24055.209 ns/op +NameCoderBenchmark.dollarCoding avgt 25 4621025.135 ± 248574.503 ns/op +NameCoderBenchmark.escapedUnderscoreCoding avgt 25 5896886.514 ± 44560.928 ns/op +NameCoderBenchmark.noCoding avgt 25 4190972.243 ± 149611.494 ns/op +NameCoderBenchmark.xmlFriendlyCoding avgt 25 4938586.549 ± 181401.642 ns/op diff --git a/xstream-jmh/src/reference/parsers.txt b/xstream-jmh/src/reference/parsers.txt index b9072d2..af531e9 100644 --- a/xstream-jmh/src/reference/parsers.txt +++ b/xstream-jmh/src/reference/parsers.txt @@ -1,37 +1,37 @@ Benchmark (driverFactory) Mode Cnt Score Error Units -ParserBenchmark.parseBigText Xpp3 avgt 15 2084516.475 ± 18357.160 ns/op -ParserBenchmark.parseBigText kXML2 avgt 15 3539743.111 ± 40107.429 ns/op -ParserBenchmark.parseBigText JDKStax avgt 15 7314997.951 ± 47929.496 ns/op -ParserBenchmark.parseBigText Woodstox avgt 15 1888835.931 ± 22134.786 ns/op -ParserBenchmark.parseBigText BEAStax avgt 15 2658801.705 ± 18343.532 ns/op -ParserBenchmark.parseBigText DOM avgt 15 9781342.261 ± 56171.129 ns/op -ParserBenchmark.parseBigText DOM4J avgt 15 7737425.182 ± 60332.494 ns/op -ParserBenchmark.parseBigText JDom avgt 15 6303281.491 ± 38500.209 ns/op -ParserBenchmark.parseBigText JDom2 avgt 15 5912161.208 ± 60666.941 ns/op -ParserBenchmark.parseBigText Xom avgt 15 8086930.673 ± 84884.910 ns/op -ParserBenchmark.parseBigText Binary avgt 15 1149384.865 ± 18245.639 ns/op -ParserBenchmark.parseBigText Jettison avgt 15 2983598.441 ± 51508.673 ns/op -ParserBenchmark.parseManyChildren Xpp3 avgt 15 693019.370 ± 3982.017 ns/op -ParserBenchmark.parseManyChildren kXML2 avgt 15 837861.515 ± 5737.910 ns/op -ParserBenchmark.parseManyChildren JDKStax avgt 15 727323.621 ± 12819.229 ns/op -ParserBenchmark.parseManyChildren Woodstox avgt 15 622817.191 ± 8434.515 ns/op -ParserBenchmark.parseManyChildren BEAStax avgt 15 716108.170 ± 3738.679 ns/op -ParserBenchmark.parseManyChildren DOM avgt 15 52632217.909 ± 820752.640 ns/op -ParserBenchmark.parseManyChildren DOM4J avgt 15 93587705.473 ± 576597.653 ns/op -ParserBenchmark.parseManyChildren JDom avgt 15 7066427.706 ± 67403.369 ns/op -ParserBenchmark.parseManyChildren JDom2 avgt 15 9159926.646 ± 91300.562 ns/op -ParserBenchmark.parseManyChildren Xom avgt 15 36550127.033 ± 85933.816 ns/op -ParserBenchmark.parseManyChildren Binary avgt 15 438657.801 ± 4495.124 ns/op -ParserBenchmark.parseManyChildren Jettison avgt 15 564172.475 ± 4212.309 ns/op -ParserBenchmark.parseNestedElements Xpp3 avgt 15 12426115.039 ± 129574.773 ns/op -ParserBenchmark.parseNestedElements kXML2 avgt 15 34291308.328 ± 168044.895 ns/op -ParserBenchmark.parseNestedElements JDKStax avgt 15 594349.622 ± 4103.535 ns/op -ParserBenchmark.parseNestedElements Woodstox avgt 15 645986.465 ± 7631.906 ns/op -ParserBenchmark.parseNestedElements BEAStax avgt 15 579754.753 ± 2345.131 ns/op -ParserBenchmark.parseNestedElements DOM avgt 15 5103544.581 ± 43300.158 ns/op -ParserBenchmark.parseNestedElements DOM4J avgt 15 5832065.181 ± 58233.910 ns/op -ParserBenchmark.parseNestedElements JDom avgt 15 14168656.571 ± 199034.717 ns/op -ParserBenchmark.parseNestedElements JDom2 avgt 15 10786607.592 ± 136001.568 ns/op -ParserBenchmark.parseNestedElements Xom avgt 15 7799715.857 ± 102903.181 ns/op -ParserBenchmark.parseNestedElements Binary avgt 15 290646.503 ± 1769.476 ns/op -ParserBenchmark.parseNestedElements Jettison avgt 15 632427.902 ± 4369.921 ns/op +ParserBenchmark.parseBigText Xpp3 avgt 15 2155470.575 ± 23234.958 ns/op +ParserBenchmark.parseBigText kXML2 avgt 15 3663477.841 ± 25428.211 ns/op +ParserBenchmark.parseBigText JDKStax avgt 15 7444273.102 ± 58755.804 ns/op +ParserBenchmark.parseBigText Woodstox avgt 15 1845769.311 ± 4622.237 ns/op +ParserBenchmark.parseBigText BEAStax avgt 15 2879876.995 ± 59633.850 ns/op +ParserBenchmark.parseBigText DOM avgt 15 9710278.896 ± 31003.340 ns/op +ParserBenchmark.parseBigText DOM4J avgt 15 7452345.867 ± 23882.243 ns/op +ParserBenchmark.parseBigText JDom avgt 15 6387821.035 ± 84970.337 ns/op +ParserBenchmark.parseBigText JDom2 avgt 15 5921949.583 ± 34834.810 ns/op +ParserBenchmark.parseBigText Xom avgt 15 8204769.944 ± 114956.192 ns/op +ParserBenchmark.parseBigText Binary avgt 15 1129812.942 ± 16087.727 ns/op +ParserBenchmark.parseBigText Jettison avgt 15 3016232.225 ± 25147.822 ns/op +ParserBenchmark.parseManyChildren Xpp3 avgt 15 661082.180 ± 6313.751 ns/op +ParserBenchmark.parseManyChildren kXML2 avgt 15 854613.418 ± 23502.923 ns/op +ParserBenchmark.parseManyChildren JDKStax avgt 15 706572.092 ± 4563.202 ns/op +ParserBenchmark.parseManyChildren Woodstox avgt 15 632147.776 ± 10452.976 ns/op +ParserBenchmark.parseManyChildren BEAStax avgt 15 666062.149 ± 2243.640 ns/op +ParserBenchmark.parseManyChildren DOM avgt 15 53954694.751 ± 64528.143 ns/op +ParserBenchmark.parseManyChildren DOM4J avgt 15 93099746.029 ± 1777192.772 ns/op +ParserBenchmark.parseManyChildren JDom avgt 15 6898339.792 ± 94446.669 ns/op +ParserBenchmark.parseManyChildren JDom2 avgt 15 8723291.385 ± 91814.554 ns/op +ParserBenchmark.parseManyChildren Xom avgt 15 42486494.920 ± 833304.520 ns/op +ParserBenchmark.parseManyChildren Binary avgt 15 383203.739 ± 3522.118 ns/op +ParserBenchmark.parseManyChildren Jettison avgt 15 555908.503 ± 2937.376 ns/op +ParserBenchmark.parseNestedElements Xpp3 avgt 15 12444913.194 ± 216691.144 ns/op +ParserBenchmark.parseNestedElements kXML2 avgt 15 34372562.351 ± 393544.126 ns/op +ParserBenchmark.parseNestedElements JDKStax avgt 15 617636.917 ± 3232.109 ns/op +ParserBenchmark.parseNestedElements Woodstox avgt 15 604788.852 ± 12685.186 ns/op +ParserBenchmark.parseNestedElements BEAStax avgt 15 572549.126 ± 4791.275 ns/op +ParserBenchmark.parseNestedElements DOM avgt 15 5148010.389 ± 46007.206 ns/op +ParserBenchmark.parseNestedElements DOM4J avgt 15 5533035.930 ± 101440.131 ns/op +ParserBenchmark.parseNestedElements JDom avgt 15 14111857.552 ± 448478.887 ns/op +ParserBenchmark.parseNestedElements JDom2 avgt 15 10579620.188 ± 55254.011 ns/op +ParserBenchmark.parseNestedElements Xom avgt 15 8086714.065 ± 57941.667 ns/op +ParserBenchmark.parseNestedElements Binary avgt 15 260233.635 ± 4080.416 ns/op +ParserBenchmark.parseNestedElements Jettison avgt 15 619961.028 ± 7869.358 ns/op diff --git a/xstream-jmh/src/reference/stringConverter.txt b/xstream-jmh/src/reference/stringConverter.txt index 66357f6..3b1f2b2 100644 --- a/xstream-jmh/src/reference/stringConverter.txt +++ b/xstream-jmh/src/reference/stringConverter.txt @@ -1,7 +1,7 @@ Benchmark Mode Cnt Score Error Units -StringConverterBenchmark.intern avgt 16 12650471.288 ± 165474.187 ns/op -StringConverterBenchmark.limitedConcurrentMap avgt 16 12072029.228 ± 175936.759 ns/op -StringConverterBenchmark.limitedSynchronizedWeakCache avgt 16 12748751.700 ± 205485.179 ns/op -StringConverterBenchmark.nonCaching avgt 16 9755034.512 ± 210645.214 ns/op -StringConverterBenchmark.unlimitedConcurrentMap avgt 16 11431423.547 ± 176483.052 ns/op -StringConverterBenchmark.unlimitedSynchronizedWeakCache avgt 16 11178461.611 ± 177404.016 ns/op +StringConverterBenchmark.intern avgt 16 12576002.757 ± 850369.771 ns/op +StringConverterBenchmark.limitedConcurrentMap avgt 16 10411028.373 ± 76602.128 ns/op +StringConverterBenchmark.limitedSynchronizedWeakCache avgt 16 10948390.386 ± 84458.276 ns/op +StringConverterBenchmark.nonCaching avgt 16 9422597.717 ± 39021.126 ns/op +StringConverterBenchmark.unlimitedConcurrentMap avgt 16 10666492.267 ± 285717.245 ns/op +StringConverterBenchmark.unlimitedSynchronizedWeakCache avgt 16 11917404.787 ± 1224543.882 ns/op