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.io.InvalidObjectException;
|
||||
import java.util.EventObject;
|
||||
|
||||
import java.util.Collections;
|
||||
@ -329,22 +330,50 @@ public class DragGestureEvent extends EventObject {
|
||||
{
|
||||
ObjectInputStream.GetField f = s.readFields();
|
||||
|
||||
dragSource = (DragSource)f.get("dragSource", null);
|
||||
component = (Component)f.get("component", null);
|
||||
origin = (Point)f.get("origin", null);
|
||||
action = f.get("action", 0);
|
||||
DragSource newDragSource = (DragSource)f.get("dragSource", null);
|
||||
if (newDragSource == null) {
|
||||
throw new InvalidObjectException("null DragSource");
|
||||
}
|
||||
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
|
||||
List newEvents;
|
||||
try {
|
||||
events = (List)f.get("events", null);
|
||||
newEvents = (List)f.get("events", null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 1.4-compatible byte stream. 'events' was written explicitly
|
||||
events = (List)s.readObject();
|
||||
newEvents = (List)s.readObject();
|
||||
}
|
||||
|
||||
// Implementation assumes 'events' is never null.
|
||||
if (events == null) {
|
||||
events = Collections.EMPTY_LIST;
|
||||
if (newEvents != null && newEvents.isEmpty()) {
|
||||
// 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.Point;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import java.util.Collections;
|
||||
import java.util.TooManyListenersException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -411,10 +413,21 @@ public abstract class DragGestureRecognizer implements Serializable {
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void readObject(ObjectInputStream s)
|
||||
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();
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
@ -562,7 +563,36 @@ public class DragSourceContext
|
||||
private void readObject(ObjectInputStream s)
|
||||
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();
|
||||
listener = (DragSourceListener)s.readObject();
|
||||
@ -630,5 +660,5 @@ public class DragSourceContext
|
||||
*
|
||||
* @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