contextProperties = new HashMap<>();
+ jaxbContext = JAXBContext.newInstance(DOMAIN_CLASSES, contextProperties);
+ unmarshaller = jaxbContext.createUnmarshaller();
+ }
+
+ private void unmarshallDocument(String fileName) {
+ Object testObject = null;
+ File file = new File(ClassLoader.getSystemResource(fileName).getFile());
+ try {
+ testObject = unmarshaller.unmarshal(file);
+ fail("javax.xml.bind.UnmarshalException was not occured for " + fileName);
+ } catch (UnmarshalException e) {
+ assertNotNull(e);
+ } catch (Exception e) {
+ fail("No expected javax.xml.bind.UnmarshalException was thrown: " + e);
+ }
+ // the deserialized object variable must be null
+ assertNull(testObject);
+ }
+
+
+}
diff --git a/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/InsecureDataObject.java b/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/InsecureDataObject.java
new file mode 100644
index 00000000000..f2e92611a2b
--- /dev/null
+++ b/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/InsecureDataObject.java
@@ -0,0 +1,639 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+package org.eclipse.persistence.testing.sdo.externalizable;
+
+import commonj.sdo.*;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.List;
+
+public class InsecureDataObject implements DataObject {
+ @Override
+ public Object get(String path) {
+ return null;
+ }
+
+ @Override
+ public void set(String path, Object value) {
+
+ }
+
+ @Override
+ public boolean isSet(String path) {
+ return false;
+ }
+
+ @Override
+ public void unset(String path) {
+
+ }
+
+ @Override
+ public boolean getBoolean(String path) {
+ return false;
+ }
+
+ @Override
+ public byte getByte(String path) {
+ return 0;
+ }
+
+ @Override
+ public char getChar(String path) {
+ return 0;
+ }
+
+ @Override
+ public double getDouble(String path) {
+ return 0;
+ }
+
+ @Override
+ public float getFloat(String path) {
+ return 0;
+ }
+
+ @Override
+ public int getInt(String path) {
+ return 0;
+ }
+
+ @Override
+ public long getLong(String path) {
+ return 0;
+ }
+
+ @Override
+ public short getShort(String path) {
+ return 0;
+ }
+
+ @Override
+ public byte[] getBytes(String path) {
+ return new byte[0];
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(String path) {
+ return null;
+ }
+
+ @Override
+ public BigInteger getBigInteger(String path) {
+ return null;
+ }
+
+ @Override
+ public DataObject getDataObject(String path) {
+ return null;
+ }
+
+ @Override
+ public Date getDate(String path) {
+ return null;
+ }
+
+ @Override
+ public String getString(String path) {
+ return null;
+ }
+
+ @Override
+ public List getList(String path) {
+ return null;
+ }
+
+ @Override
+ public Sequence getSequence(String path) {
+ return null;
+ }
+
+ @Override
+ public void setBoolean(String path, boolean value) {
+
+ }
+
+ @Override
+ public void setByte(String path, byte value) {
+
+ }
+
+ @Override
+ public void setChar(String path, char value) {
+
+ }
+
+ @Override
+ public void setDouble(String path, double value) {
+
+ }
+
+ @Override
+ public void setFloat(String path, float value) {
+
+ }
+
+ @Override
+ public void setInt(String path, int value) {
+
+ }
+
+ @Override
+ public void setLong(String path, long value) {
+
+ }
+
+ @Override
+ public void setShort(String path, short value) {
+
+ }
+
+ @Override
+ public void setBytes(String path, byte[] value) {
+
+ }
+
+ @Override
+ public void setBigDecimal(String path, BigDecimal value) {
+
+ }
+
+ @Override
+ public void setBigInteger(String path, BigInteger value) {
+
+ }
+
+ @Override
+ public void setDataObject(String path, DataObject value) {
+
+ }
+
+ @Override
+ public void setDate(String path, Date value) {
+
+ }
+
+ @Override
+ public void setString(String path, String value) {
+
+ }
+
+ @Override
+ public void setList(String path, List value) {
+
+ }
+
+ @Override
+ public Object get(int propertyIndex) {
+ return null;
+ }
+
+ @Override
+ public void set(int propertyIndex, Object value) {
+
+ }
+
+ @Override
+ public boolean isSet(int propertyIndex) {
+ return false;
+ }
+
+ @Override
+ public void unset(int propertyIndex) {
+
+ }
+
+ @Override
+ public boolean getBoolean(int propertyIndex) {
+ return false;
+ }
+
+ @Override
+ public byte getByte(int propertyIndex) {
+ return 0;
+ }
+
+ @Override
+ public char getChar(int propertyIndex) {
+ return 0;
+ }
+
+ @Override
+ public double getDouble(int propertyIndex) {
+ return 0;
+ }
+
+ @Override
+ public float getFloat(int propertyIndex) {
+ return 0;
+ }
+
+ @Override
+ public int getInt(int propertyIndex) {
+ return 0;
+ }
+
+ @Override
+ public long getLong(int propertyIndex) {
+ return 0;
+ }
+
+ @Override
+ public short getShort(int propertyIndex) {
+ return 0;
+ }
+
+ @Override
+ public byte[] getBytes(int propertyIndex) {
+ return new byte[0];
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(int propertyIndex) {
+ return null;
+ }
+
+ @Override
+ public BigInteger getBigInteger(int propertyIndex) {
+ return null;
+ }
+
+ @Override
+ public DataObject getDataObject(int propertyIndex) {
+ return null;
+ }
+
+ @Override
+ public Date getDate(int propertyIndex) {
+ return null;
+ }
+
+ @Override
+ public String getString(int propertyIndex) {
+ return null;
+ }
+
+ @Override
+ public List getList(int propertyIndex) {
+ return null;
+ }
+
+ @Override
+ public Sequence getSequence(int propertyIndex) {
+ return null;
+ }
+
+ @Override
+ public void setBoolean(int propertyIndex, boolean value) {
+
+ }
+
+ @Override
+ public void setByte(int propertyIndex, byte value) {
+
+ }
+
+ @Override
+ public void setChar(int propertyIndex, char value) {
+
+ }
+
+ @Override
+ public void setDouble(int propertyIndex, double value) {
+
+ }
+
+ @Override
+ public void setFloat(int propertyIndex, float value) {
+
+ }
+
+ @Override
+ public void setInt(int propertyIndex, int value) {
+
+ }
+
+ @Override
+ public void setLong(int propertyIndex, long value) {
+
+ }
+
+ @Override
+ public void setShort(int propertyIndex, short value) {
+
+ }
+
+ @Override
+ public void setBytes(int propertyIndex, byte[] value) {
+
+ }
+
+ @Override
+ public void setBigDecimal(int propertyIndex, BigDecimal value) {
+
+ }
+
+ @Override
+ public void setBigInteger(int propertyIndex, BigInteger value) {
+
+ }
+
+ @Override
+ public void setDataObject(int propertyIndex, DataObject value) {
+
+ }
+
+ @Override
+ public void setDate(int propertyIndex, Date value) {
+
+ }
+
+ @Override
+ public void setString(int propertyIndex, String value) {
+
+ }
+
+ @Override
+ public void setList(int propertyIndex, List value) {
+
+ }
+
+ @Override
+ public Object get(Property property) {
+ return null;
+ }
+
+ @Override
+ public void set(Property property, Object value) {
+
+ }
+
+ @Override
+ public boolean isSet(Property property) {
+ return false;
+ }
+
+ @Override
+ public void unset(Property property) {
+
+ }
+
+ @Override
+ public boolean getBoolean(Property property) {
+ return false;
+ }
+
+ @Override
+ public byte getByte(Property property) {
+ return 0;
+ }
+
+ @Override
+ public char getChar(Property property) {
+ return 0;
+ }
+
+ @Override
+ public double getDouble(Property property) {
+ return 0;
+ }
+
+ @Override
+ public float getFloat(Property property) {
+ return 0;
+ }
+
+ @Override
+ public int getInt(Property property) {
+ return 0;
+ }
+
+ @Override
+ public long getLong(Property property) {
+ return 0;
+ }
+
+ @Override
+ public short getShort(Property property) {
+ return 0;
+ }
+
+ @Override
+ public byte[] getBytes(Property property) {
+ return new byte[0];
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(Property property) {
+ return null;
+ }
+
+ @Override
+ public BigInteger getBigInteger(Property property) {
+ return null;
+ }
+
+ @Override
+ public DataObject getDataObject(Property property) {
+ return null;
+ }
+
+ @Override
+ public Date getDate(Property property) {
+ return null;
+ }
+
+ @Override
+ public String getString(Property property) {
+ return null;
+ }
+
+ @Override
+ public List getList(Property property) {
+ return null;
+ }
+
+ @Override
+ public Sequence getSequence(Property property) {
+ return null;
+ }
+
+ @Override
+ public void setBoolean(Property property, boolean value) {
+
+ }
+
+ @Override
+ public void setByte(Property property, byte value) {
+
+ }
+
+ @Override
+ public void setChar(Property property, char value) {
+
+ }
+
+ @Override
+ public void setDouble(Property property, double value) {
+
+ }
+
+ @Override
+ public void setFloat(Property property, float value) {
+
+ }
+
+ @Override
+ public void setInt(Property property, int value) {
+
+ }
+
+ @Override
+ public void setLong(Property property, long value) {
+
+ }
+
+ @Override
+ public void setShort(Property property, short value) {
+
+ }
+
+ @Override
+ public void setBytes(Property property, byte[] value) {
+
+ }
+
+ @Override
+ public void setBigDecimal(Property property, BigDecimal value) {
+
+ }
+
+ @Override
+ public void setBigInteger(Property property, BigInteger value) {
+
+ }
+
+ @Override
+ public void setDataObject(Property property, DataObject value) {
+
+ }
+
+ @Override
+ public void setDate(Property property, Date value) {
+
+ }
+
+ @Override
+ public void setString(Property property, String value) {
+
+ }
+
+ @Override
+ public void setList(Property property, List value) {
+
+ }
+
+ @Override
+ public DataObject createDataObject(String propertyName) {
+ return null;
+ }
+
+ @Override
+ public DataObject createDataObject(int propertyIndex) {
+ return null;
+ }
+
+ @Override
+ public DataObject createDataObject(Property property) {
+ return null;
+ }
+
+ @Override
+ public DataObject createDataObject(String propertyName, String namespaceURI, String typeName) {
+ return null;
+ }
+
+ @Override
+ public DataObject createDataObject(int propertyIndex, String namespaceURI, String typeName) {
+ return null;
+ }
+
+ @Override
+ public DataObject createDataObject(Property property, Type type) {
+ return null;
+ }
+
+ @Override
+ public void delete() {
+
+ }
+
+ @Override
+ public DataObject getContainer() {
+ return null;
+ }
+
+ @Override
+ public Property getContainmentProperty() {
+ return null;
+ }
+
+ @Override
+ public DataGraph getDataGraph() {
+ return null;
+ }
+
+ @Override
+ public Type getType() {
+ return null;
+ }
+
+ @Override
+ public Sequence getSequence() {
+ return null;
+ }
+
+ @Override
+ public List getInstanceProperties() {
+ return null;
+ }
+
+ @Override
+ public Property getInstanceProperty(String propertyName) {
+ return null;
+ }
+
+ @Override
+ public Property getProperty(String propertyName) {
+ return null;
+ }
+
+ @Override
+ public DataObject getRootObject() {
+ return null;
+ }
+
+ @Override
+ public ChangeSummary getChangeSummary() {
+ return null;
+ }
+
+ @Override
+ public void detach() {
+
+ }
+}
diff --git a/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/SDOResolvableTest.java b/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/SDOResolvableTest.java
index c0c6948a317..8e7fe0b6ea1 100644
--- a/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/SDOResolvableTest.java
+++ b/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/SDOResolvableTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -16,11 +16,13 @@
import commonj.sdo.helper.XMLDocument;
import java.io.FileInputStream;
+import java.io.InvalidClassException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
+import org.eclipse.persistence.internal.localization.LoggingLocalization;
import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDODataObject;
import org.eclipse.persistence.sdo.helper.SDOHelperContext;
@@ -33,6 +35,7 @@
public class SDOResolvableTest extends SDOResolvableTestCases {
public final String SERIALIZATION_FILE_NAME = tempFileDir + "/serialization.bin";
+ public final String SERIALIZATION_INSECURE_FILE_NAME = tempFileDir + "/serializationInsecure.bin";
public SDOResolvableTest(String name) {
super(name);
@@ -228,4 +231,25 @@ public void testWriteList() {
// the original and deserialized objects should be the same
//assertTrue(equalityHelper.equal(anObject, aDeserializedDataObject));
}
+
+ public void testWriteReadInsecureDataObject() throws Exception {
+ DataObject anObject = new InsecureDataObject();
+ DataObject aDeserializedInsecureDataObject = null;
+
+ // check that we received a DataObject
+ assertNotNull(anObject);
+
+ serialize(anObject, SERIALIZATION_INSECURE_FILE_NAME);
+ // deserialize the binary file representation
+ try {
+ aDeserializedInsecureDataObject = deserializeInsecure(SERIALIZATION_INSECURE_FILE_NAME);
+ } catch (InvalidClassException e) {
+ assertEquals(LoggingLocalization.buildMessage("sdo_error_deserialization", new Object[] {anObject.getClass().getName()}), e.getMessage());
+ return;
+ }
+
+ // the deserialized object variable must be null
+ assertNull(aDeserializedInsecureDataObject);
+ fail("java.io.InvalidClassException was not occured.");
+ }
}
diff --git a/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/SDOResolvableTestCases.java b/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/SDOResolvableTestCases.java
index 50c65f5ad4f..1b2a1da5354 100644
--- a/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/SDOResolvableTestCases.java
+++ b/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/externalizable/SDOResolvableTestCases.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -151,6 +151,25 @@ public DataObject deserialize(String filename) {
return anObject;
}
+ public DataObject deserializeInsecure(String filename) throws Exception{
+ // declare streams and objects
+ FileInputStream aFileInputStream = null;
+
+ // ObjectInputStream wrapper (to pass a custom context)
+ DataObjectInputStream aDataObjectInputStream = null;
+
+ DataObject anObject = null;
+ // DeSerialize
+ aFileInputStream = new FileInputStream(filename);
+ // use our wrapper for InputStream that maintains context
+ aDataObjectInputStream = new DataObjectInputStream(aFileInputStream, aHelperContext);
+ // read into context
+ anObject = (DataObject)aDataObjectInputStream.readObject();
+ aDataObjectInputStream.close();
+ aFileInputStream.close();
+ return anObject;
+ }
+
public List deserializeList(String filename) {
// declare streams and objects
FileInputStream aFileInputStream = null;
diff --git a/sdo/org.eclipse.persistence.sdo/src/org/eclipse/persistence/sdo/SDOConstants.java b/sdo/org.eclipse.persistence.sdo/src/org/eclipse/persistence/sdo/SDOConstants.java
index f7a0f7a2793..99d9e94cdde 100644
--- a/sdo/org.eclipse.persistence.sdo/src/org/eclipse/persistence/sdo/SDOConstants.java
+++ b/sdo/org.eclipse.persistence.sdo/src/org/eclipse/persistence/sdo/SDOConstants.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -19,6 +19,10 @@
import org.eclipse.persistence.sdo.types.*;
import org.eclipse.persistence.sdo.helper.SDOTypeHelper;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* Purpose: Maintain constants in one class
*
Responsibilities:
@@ -344,6 +348,14 @@ public class SDOConstants {
/** Search string concatenated from default package for type generation and the package separator dot */
public static final String JAVA_TYPE_GENERATION_DEFAULT_PACKAGE_NAME_SEARCH = JAVA_TYPEGENERATION_DEFAULT_PACKAGE_NAME + JAVA_PACKAGE_NAME_SEPARATOR;
+ /** List of the classes allowed to deserialize in SDO*/
+ public static final Set ALLOWED_DESERIALIZATION_CLASS_NAMES = Collections.unmodifiableSet(
+ new HashSet() {{
+ add(org.eclipse.persistence.sdo.SDOExternalizableDelegator.class.getName());
+ add(org.eclipse.persistence.sdo.AbstractExternalizableDelegator.class.getName());
+ add(java.util.ArrayList.class.getName());
+ }});
+
static {
if(null != sdoTypeHelper) {
sdoTypeHelper.reset();
diff --git a/sdo/org.eclipse.persistence.sdo/src/org/eclipse/persistence/sdo/helper/DataObjectInputStream.java b/sdo/org.eclipse.persistence.sdo/src/org/eclipse/persistence/sdo/helper/DataObjectInputStream.java
index efb8e7911c8..d27b7243c2d 100644
--- a/sdo/org.eclipse.persistence.sdo/src/org/eclipse/persistence/sdo/helper/DataObjectInputStream.java
+++ b/sdo/org.eclipse.persistence.sdo/src/org/eclipse/persistence/sdo/helper/DataObjectInputStream.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -30,11 +30,14 @@
*/
package org.eclipse.persistence.sdo.helper;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
+import java.io.*;
+import java.util.Arrays;
+
import commonj.sdo.helper.HelperContext;
import commonj.sdo.impl.HelperProvider;
+import org.eclipse.persistence.internal.localization.LoggingLocalization;
+import org.eclipse.persistence.logging.AbstractSessionLog;
+import org.eclipse.persistence.sdo.SDOConstants;
public class DataObjectInputStream extends ObjectInputStream {
private HelperContext aHelperContext;
@@ -79,4 +82,14 @@ public HelperContext getHelperContext() {
public void setHelperContext(HelperContext helperContext) {
aHelperContext = helperContext;
}
+
+ @Override
+ protected Class> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
+ if (!SDOConstants.ALLOWED_DESERIALIZATION_CLASS_NAMES.contains(desc.getName())) {
+ AbstractSessionLog.getLog().log(AbstractSessionLog.SEVERE, "sdo_error_deserialization", new Object[] {desc.getName()});
+ throw new InvalidClassException(LoggingLocalization.buildMessage("sdo_error_deserialization", new Object[] {desc.getName()}));
+ }
+ return super.resolveClass(desc);
+ }
+
}