8030050: Validate fields on DnD class deserialization

Reviewed-by: anthony, serb
This commit is contained in:
Petr Pchelko 2014-01-22 12:35:43 +04:00
parent 7554f9dc43
commit bfc61365e0
10 changed files with 158 additions and 11 deletions

View File

@ -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;
}
/*

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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");
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.