8030050: Validate fields on DnD class deserialization
Reviewed-by: anthony, serb
This commit is contained in:
parent
7554f9dc43
commit
bfc61365e0
@ -36,6 +36,7 @@ import java.awt.event.InputEvent;
|
|||||||
|
|
||||||
import java.awt.datatransfer.Transferable;
|
import java.awt.datatransfer.Transferable;
|
||||||
|
|
||||||
|
import java.io.InvalidObjectException;
|
||||||
import java.util.EventObject;
|
import java.util.EventObject;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -329,22 +330,50 @@ public class DragGestureEvent extends EventObject {
|
|||||||
{
|
{
|
||||||
ObjectInputStream.GetField f = s.readFields();
|
ObjectInputStream.GetField f = s.readFields();
|
||||||
|
|
||||||
dragSource = (DragSource)f.get("dragSource", null);
|
DragSource newDragSource = (DragSource)f.get("dragSource", null);
|
||||||
component = (Component)f.get("component", null);
|
if (newDragSource == null) {
|
||||||
origin = (Point)f.get("origin", null);
|
throw new InvalidObjectException("null DragSource");
|
||||||
action = f.get("action", 0);
|
}
|
||||||
|
dragSource = newDragSource;
|
||||||
|
|
||||||
|
Component newComponent = (Component)f.get("component", null);
|
||||||
|
if (newComponent == null) {
|
||||||
|
throw new InvalidObjectException("null component");
|
||||||
|
}
|
||||||
|
component = newComponent;
|
||||||
|
|
||||||
|
Point newOrigin = (Point)f.get("origin", null);
|
||||||
|
if (newOrigin == null) {
|
||||||
|
throw new InvalidObjectException("null origin");
|
||||||
|
}
|
||||||
|
origin = newOrigin;
|
||||||
|
|
||||||
|
int newAction = f.get("action", 0);
|
||||||
|
if (newAction != DnDConstants.ACTION_COPY &&
|
||||||
|
newAction != DnDConstants.ACTION_MOVE &&
|
||||||
|
newAction != DnDConstants.ACTION_LINK) {
|
||||||
|
throw new InvalidObjectException("bad action");
|
||||||
|
}
|
||||||
|
action = newAction;
|
||||||
|
|
||||||
// Pre-1.4 support. 'events' was previously non-transient
|
// Pre-1.4 support. 'events' was previously non-transient
|
||||||
|
List newEvents;
|
||||||
try {
|
try {
|
||||||
events = (List)f.get("events", null);
|
newEvents = (List)f.get("events", null);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// 1.4-compatible byte stream. 'events' was written explicitly
|
// 1.4-compatible byte stream. 'events' was written explicitly
|
||||||
events = (List)s.readObject();
|
newEvents = (List)s.readObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementation assumes 'events' is never null.
|
// Implementation assumes 'events' is never null.
|
||||||
if (events == null) {
|
if (newEvents != null && newEvents.isEmpty()) {
|
||||||
events = Collections.EMPTY_LIST;
|
// Constructor treats empty events list as invalid value
|
||||||
|
// Throw exception if serialized list is empty
|
||||||
|
throw new InvalidObjectException("empty list of events");
|
||||||
|
} else if (newEvents == null) {
|
||||||
|
newEvents = Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
events = newEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -29,6 +29,8 @@ import java.awt.event.InputEvent;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
|
||||||
|
import java.io.InvalidObjectException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.TooManyListenersException;
|
import java.util.TooManyListenersException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@ -411,10 +413,21 @@ public abstract class DragGestureRecognizer implements Serializable {
|
|||||||
*
|
*
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private void readObject(ObjectInputStream s)
|
private void readObject(ObjectInputStream s)
|
||||||
throws ClassNotFoundException, IOException
|
throws ClassNotFoundException, IOException
|
||||||
{
|
{
|
||||||
s.defaultReadObject();
|
ObjectInputStream.GetField f = s.readFields();
|
||||||
|
|
||||||
|
DragSource newDragSource = (DragSource)f.get("dragSource", null);
|
||||||
|
if (newDragSource == null) {
|
||||||
|
throw new InvalidObjectException("null DragSource");
|
||||||
|
}
|
||||||
|
dragSource = newDragSource;
|
||||||
|
|
||||||
|
component = (Component)f.get("component", null);
|
||||||
|
sourceActions = f.get("sourceActions", 0) & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK);
|
||||||
|
events = (ArrayList<InputEvent>)f.get("events", new ArrayList<>(1));
|
||||||
|
|
||||||
dragGestureListener = (DragGestureListener)s.readObject();
|
dragGestureListener = (DragGestureListener)s.readObject();
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import java.awt.datatransfer.UnsupportedFlavorException;
|
|||||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InvalidObjectException;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@ -562,7 +563,36 @@ public class DragSourceContext
|
|||||||
private void readObject(ObjectInputStream s)
|
private void readObject(ObjectInputStream s)
|
||||||
throws ClassNotFoundException, IOException
|
throws ClassNotFoundException, IOException
|
||||||
{
|
{
|
||||||
s.defaultReadObject();
|
ObjectInputStream.GetField f = s.readFields();
|
||||||
|
|
||||||
|
DragGestureEvent newTrigger = (DragGestureEvent)f.get("trigger", null);
|
||||||
|
if (newTrigger == null) {
|
||||||
|
throw new InvalidObjectException("Null trigger");
|
||||||
|
}
|
||||||
|
if (newTrigger.getDragSource() == null) {
|
||||||
|
throw new InvalidObjectException("Null DragSource");
|
||||||
|
}
|
||||||
|
if (newTrigger.getComponent() == null) {
|
||||||
|
throw new InvalidObjectException("Null trigger component");
|
||||||
|
}
|
||||||
|
|
||||||
|
int DGRActions = newTrigger.getSourceAsDragGestureRecognizer().getSourceActions()
|
||||||
|
& (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK);
|
||||||
|
if (DGRActions == DnDConstants.ACTION_NONE) {
|
||||||
|
throw new InvalidObjectException("Invalid source actions");
|
||||||
|
}
|
||||||
|
int triggerActions = newTrigger.getDragAction();
|
||||||
|
if (triggerActions != DnDConstants.ACTION_COPY &&
|
||||||
|
triggerActions != DnDConstants.ACTION_MOVE &&
|
||||||
|
triggerActions != DnDConstants.ACTION_LINK) {
|
||||||
|
throw new InvalidObjectException("No drag action");
|
||||||
|
}
|
||||||
|
trigger = newTrigger;
|
||||||
|
|
||||||
|
cursor = (Cursor)f.get("cursor", null);
|
||||||
|
useCustomCursor = f.get("useCustomCursor", false);
|
||||||
|
sourceActions = f.get("sourceActions", 0)
|
||||||
|
& (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK);
|
||||||
|
|
||||||
transferable = (Transferable)s.readObject();
|
transferable = (Transferable)s.readObject();
|
||||||
listener = (DragSourceListener)s.readObject();
|
listener = (DragSourceListener)s.readObject();
|
||||||
@ -630,5 +660,5 @@ public class DragSourceContext
|
|||||||
*
|
*
|
||||||
* @serial
|
* @serial
|
||||||
*/
|
*/
|
||||||
private final int sourceActions;
|
private int sourceActions;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8030050
|
||||||
|
* @summary Validate fields on DnD class deserialization
|
||||||
|
* @author petr.pchelko@oracle.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InvalidObjectException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class BadSerializationTest {
|
||||||
|
|
||||||
|
private static final String[] badSerialized = new String[] {
|
||||||
|
"badAction",
|
||||||
|
"noEvents",
|
||||||
|
"nullComponent",
|
||||||
|
"nullDragSource",
|
||||||
|
"nullOrigin"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final String goodSerialized = "good";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
String testSrc = System.getProperty("test.src") + File.separator;
|
||||||
|
testReadObject(testSrc + goodSerialized, false);
|
||||||
|
Stream.of(badSerialized).forEach(file -> testReadObject(testSrc + file, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testReadObject(String filename, boolean expectException) {
|
||||||
|
Exception exceptionCaught = null;
|
||||||
|
try (FileInputStream fileInputStream = new FileInputStream(filename);
|
||||||
|
ObjectInputStream ois = new ObjectInputStream(fileInputStream)) {
|
||||||
|
ois.readObject();
|
||||||
|
} catch (InvalidObjectException e) {
|
||||||
|
exceptionCaught = e;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("FAILED: IOException", e);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new RuntimeException("FAILED: ClassNotFoundException", e);
|
||||||
|
}
|
||||||
|
if (exceptionCaught != null && !expectException) {
|
||||||
|
throw new RuntimeException("FAILED: UnexpectedException", exceptionCaught);
|
||||||
|
}
|
||||||
|
if (exceptionCaught == null && expectException) {
|
||||||
|
throw new RuntimeException("FAILED: Invalid object was created with no exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/badAction
Normal file
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/badAction
Normal file
Binary file not shown.
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/good
Normal file
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/good
Normal file
Binary file not shown.
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/noEvents
Normal file
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/noEvents
Normal file
Binary file not shown.
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/nullComponent
Normal file
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/nullComponent
Normal file
Binary file not shown.
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/nullDragSource
Normal file
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/nullDragSource
Normal file
Binary file not shown.
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/nullOrigin
Normal file
BIN
jdk/test/java/awt/dnd/BadSerializaionTest/nullOrigin
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user