8038937: Validate fields on Swing classes deserialization
authoralexsch
Tue, 22 Jul 2014 17:17:05 +0400
changeset 26001 991e1be0b235
parent 26000 7d2b9a7ae7ce
child 26002 272da1566e9d
8038937: Validate fields on Swing classes deserialization Reviewed-by: serb, pchelko
jdk/src/share/classes/javax/swing/ImageIcon.java
jdk/src/share/classes/javax/swing/JComponent.java
jdk/src/share/classes/javax/swing/JFileChooser.java
jdk/src/share/classes/javax/swing/JLayer.java
jdk/src/share/classes/javax/swing/JOptionPane.java
jdk/src/share/classes/javax/swing/JPopupMenu.java
jdk/src/share/classes/javax/swing/JTabbedPane.java
jdk/src/share/classes/javax/swing/JTable.java
jdk/src/share/classes/javax/swing/JTree.java
jdk/src/share/classes/javax/swing/LegacyGlueFocusTraversalPolicy.java
jdk/src/share/classes/javax/swing/Timer.java
jdk/src/share/classes/javax/swing/text/AbstractDocument.java
jdk/src/share/classes/javax/swing/text/DefaultCaret.java
jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java
jdk/src/share/classes/javax/swing/text/JTextComponent.java
jdk/src/share/classes/javax/swing/text/MaskFormatter.java
jdk/src/share/classes/javax/swing/text/StyleContext.java
jdk/src/share/classes/javax/swing/text/html/CSS.java
jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java
jdk/src/share/classes/javax/swing/tree/DefaultTreeCellEditor.java
jdk/src/share/classes/javax/swing/tree/DefaultTreeModel.java
jdk/src/share/classes/javax/swing/tree/DefaultTreeSelectionModel.java
--- a/jdk/src/share/classes/javax/swing/ImageIcon.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/ImageIcon.java	Tue Jul 22 17:17:05 2014 +0400
@@ -490,12 +490,33 @@
     private void readObject(ObjectInputStream s)
         throws ClassNotFoundException, IOException
     {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        imageObserver = (ImageObserver) f.get("imageObserver", null);
+        description = (String) f.get("description", null);
+        width = f.get("width", -1);
+        height = f.get("height", -1);
+        accessibleContext = (AccessibleImageIcon) f.get("accessibleContext", null);
 
         int w = s.readInt();
         int h = s.readInt();
         int[] pixels = (int[])(s.readObject());
 
+        if (pixels == null && (w != -1 || h != -1)) {
+            throw new IllegalStateException("Inconsistent width and height"
+                    + " for null image [" + w + ", " + h + "]");
+        }
+
+        if (pixels != null && (w < 0 || h < 0)) {
+            throw new IllegalStateException("Inconsistent width and height"
+                    + " for image [" + w + ", " + h + "]");
+        }
+
+        if (w != getIconWidth() || h != getIconHeight()) {
+            throw new IllegalStateException("Inconsistent width and height"
+                    + " for image [" + w + ", " + h + "]");
+        }
+
         if (pixels != null) {
             Toolkit tk = Toolkit.getDefaultToolkit();
             ColorModel cm = ColorModel.getRGBdefault();
--- a/jdk/src/share/classes/javax/swing/JComponent.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/JComponent.java	Tue Jul 22 17:17:05 2014 +0400
@@ -1888,7 +1888,7 @@
      *   description: The preferred vertical alignment of the component.
      */
     public void setAlignmentY(float alignmentY) {
-        this.alignmentY = alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY;
+        this.alignmentY = validateAlignment(alignmentY);
         isAlignmentYSet = true;
     }
 
@@ -1917,10 +1917,14 @@
      *   description: The preferred horizontal alignment of the component.
      */
     public void setAlignmentX(float alignmentX) {
-        this.alignmentX = alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX;
+        this.alignmentX = validateAlignment(alignmentX);
         isAlignmentXSet = true;
     }
 
+    private float validateAlignment(float alignment) {
+        return alignment > 1.0f ? 1.0f : alignment < 0.0f ? 0.0f : alignment;
+    }
+
     /**
      * Sets the input verifier for this component.
      *
@@ -5514,7 +5518,24 @@
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException
     {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        isAlignmentXSet = f.get("isAlignmentXSet", false);
+        alignmentX = validateAlignment(f.get("alignmentX", 0f));
+        isAlignmentYSet = f.get("isAlignmentYSet", false);
+        alignmentY = validateAlignment(f.get("alignmentY", 0f));
+        listenerList = (EventListenerList) f.get("listenerList", null);
+        vetoableChangeSupport = (VetoableChangeSupport) f.get("vetoableChangeSupport", null);
+        autoscrolls = f.get("autoscrolls", false);
+        border = (Border) f.get("border", null);
+        flags = f.get("flags", 0);
+        inputVerifier = (InputVerifier) f.get("inputVerifier", null);
+        verifyInputWhenFocusTarget = f.get("verifyInputWhenFocusTarget", false);
+        popupMenu = (JPopupMenu) f.get("popupMenu", null);
+        focusInputMap = (InputMap) f.get("focusInputMap", null);
+        ancestorInputMap = (InputMap) f.get("ancestorInputMap", null);
+        windowInputMap = (ComponentInputMap) f.get("windowInputMap", null);
+        actionMap = (ActionMap) f.get("actionMap", null);
 
         /* If there's no ReadObjectCallback for this stream yet, that is, if
          * this is the first call to JComponent.readObject() for this
--- a/jdk/src/share/classes/javax/swing/JFileChooser.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/JFileChooser.java	Tue Jul 22 17:17:05 2014 +0400
@@ -50,6 +50,8 @@
 import java.awt.event.*;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
 import java.lang.ref.WeakReference;
 
 /**
@@ -460,10 +462,14 @@
      *        bound: false
      */
     public void setDragEnabled(boolean b) {
+        checkDragEnabled(b);
+        dragEnabled = b;
+    }
+
+    private static void checkDragEnabled(boolean b) {
         if (b && GraphicsEnvironment.isHeadless()) {
             throw new HeadlessException();
         }
-        dragEnabled = b;
     }
 
     /**
@@ -949,9 +955,7 @@
         if(this.dialogType == dialogType) {
             return;
         }
-        if(!(dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG || dialogType == CUSTOM_DIALOG)) {
-            throw new IllegalArgumentException("Incorrect Dialog Type: " + dialogType);
-        }
+        checkDialogType(dialogType);
         int oldValue = this.dialogType;
         this.dialogType = dialogType;
         if(dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG) {
@@ -960,6 +964,14 @@
         firePropertyChange(DIALOG_TYPE_CHANGED_PROPERTY, oldValue, dialogType);
     }
 
+    private static void checkDialogType(int dialogType) {
+        if (!(dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG
+                || dialogType == CUSTOM_DIALOG)) {
+            throw new IllegalArgumentException(
+                    "Incorrect Dialog Type: " + dialogType);
+        }
+    }
+
     /**
      * Sets the string that goes in the <code>JFileChooser</code> window's
      * title bar.
@@ -1349,12 +1361,17 @@
             return;
         }
 
-        if ((mode == FILES_ONLY) || (mode == DIRECTORIES_ONLY) || (mode == FILES_AND_DIRECTORIES)) {
+        checkFileSelectionMode(mode);
            int oldValue = fileSelectionMode;
            fileSelectionMode = mode;
            firePropertyChange(FILE_SELECTION_MODE_CHANGED_PROPERTY, oldValue, fileSelectionMode);
-        } else {
-           throw new IllegalArgumentException("Incorrect Mode for file selection: " + mode);
+    }
+
+    private static void checkFileSelectionMode(int mode) {
+        if ((mode != FILES_ONLY) && (mode != DIRECTORIES_ONLY)
+                && (mode != FILES_AND_DIRECTORIES)) {
+            throw new IllegalArgumentException(
+                    "Incorrect Mode for file selection: " + mode);
         }
     }
 
@@ -1901,7 +1918,43 @@
      */
     private void readObject(java.io.ObjectInputStream in)
             throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
+        ObjectInputStream.GetField f = in.readFields();
+
+        dialogTitle = (String) f.get("dialogTitle", null);
+        approveButtonText = (String) f.get("approveButtonText", null);
+        approveButtonToolTipText =
+                (String) f.get("approveButtonToolTipText", null);
+        approveButtonMnemonic = f.get("approveButtonMnemonic", 0);
+        @SuppressWarnings("unchecked")
+        Vector<FileFilter> newFilters = (Vector<FileFilter>) f.get("filters", null);
+        if (newFilters == null) {
+            throw new InvalidObjectException("Null filters");
+        }
+        filters = newFilters;
+        dialog = (JDialog) f.get("dialog", null);
+        int newDialogType = f.get("dialogType", OPEN_DIALOG);
+        checkDialogType(newDialogType);
+        dialogType = newDialogType;
+        returnValue = f.get("returnValue", 0);
+        accessory = (JComponent) f.get("accessory", null);
+        fileView = (FileView) f.get("fileView", null);
+        controlsShown = f.get("controlsShown", false);
+        useFileHiding = f.get("useFileHiding", false);
+        int newFileSelectionMode = f.get("fileSelectionMode", FILES_ONLY);
+        checkFileSelectionMode(newFileSelectionMode);
+        fileSelectionMode = newFileSelectionMode;
+        multiSelectionEnabled = f.get("multiSelectionEnabled", false);
+        useAcceptAllFileFilter = f.get("useAcceptAllFileFilter", false);
+        boolean newDragEnabled = f.get("dragEnabled", false);
+        checkDragEnabled(newDragEnabled);
+        dragEnabled = newDragEnabled;
+        fileFilter = (FileFilter) f.get("fileFilter", null);
+        fileSystemView = (FileSystemView) f.get("fileSystemView", null);
+        currentDirectory = (File) f.get("currentDirectory", null);
+        selectedFile = (File) f.get("selectedFile", null);
+        selectedFiles = (File[]) f.get("selectedFiles", null);
+        accessibleContext = (AccessibleContext) f.get("accessibleContext", null);
+
         installShowFilesListener();
     }
 
--- a/jdk/src/share/classes/javax/swing/JLayer.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/JLayer.java	Tue Jul 22 17:17:05 2014 +0400
@@ -648,13 +648,19 @@
 
     private void readObject(ObjectInputStream s)
             throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
-        if (layerUI != null) {
-            setUI(layerUI);
-        }
+        ObjectInputStream.GetField f = s.readFields();
+
+        view = (V) f.get("view", null);
+        glassPane = (JPanel) f.get("glassPane", null);
+        eventMask = f.get("eventMask", 0l);
         if (eventMask != 0) {
             eventController.updateAWTEventListener(0, eventMask);
         }
+        @SuppressWarnings("unchecked")
+        LayerUI<V> newLayerUI = (LayerUI<V>) f.get("layerUI", null);
+        if (newLayerUI != null) {
+            setUI(newLayerUI);
+        }
     }
 
     /**
--- a/jdk/src/share/classes/javax/swing/JOptionPane.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/JOptionPane.java	Tue Jul 22 17:17:05 2014 +0400
@@ -43,13 +43,10 @@
 import java.awt.event.ComponentAdapter;
 import java.awt.event.ComponentEvent;
 import java.io.IOException;
+import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.Vector;
 import javax.swing.plaf.OptionPaneUI;
 import javax.swing.event.InternalFrameEvent;
@@ -2055,15 +2052,22 @@
      * description: The option pane's message type.
      */
     public void setMessageType(int newType) {
+        checkMessageType(newType);
+        int           oldType = messageType;
+        messageType = newType;
+        firePropertyChange(MESSAGE_TYPE_PROPERTY, oldType, messageType);
+    }
+
+    private static void checkMessageType(int newType){
         if(newType != ERROR_MESSAGE && newType != INFORMATION_MESSAGE &&
            newType != WARNING_MESSAGE && newType != QUESTION_MESSAGE &&
            newType != PLAIN_MESSAGE)
-            throw new RuntimeException("JOptionPane: type must be one of JOptionPane.ERROR_MESSAGE, JOptionPane.INFORMATION_MESSAGE, JOptionPane.WARNING_MESSAGE, JOptionPane.QUESTION_MESSAGE or JOptionPane.PLAIN_MESSAGE");
-
-        int           oldType = messageType;
-
-        messageType = newType;
-        firePropertyChange(MESSAGE_TYPE_PROPERTY, oldType, messageType);
+            throw new RuntimeException("JOptionPane: type must be one of"
+                    + " JOptionPane.ERROR_MESSAGE,"
+                    + " JOptionPane.INFORMATION_MESSAGE,"
+                    + " JOptionPane.WARNING_MESSAGE,"
+                    + " JOptionPane.QUESTION_MESSAGE"
+                    + " or JOptionPane.PLAIN_MESSAGE");
     }
 
     /**
@@ -2097,16 +2101,23 @@
      * description: The option pane's option type.
       */
     public void setOptionType(int newType) {
-        if(newType != DEFAULT_OPTION && newType != YES_NO_OPTION &&
-           newType != YES_NO_CANCEL_OPTION && newType != OK_CANCEL_OPTION)
-            throw new RuntimeException("JOptionPane: option type must be one of JOptionPane.DEFAULT_OPTION, JOptionPane.YES_NO_OPTION, JOptionPane.YES_NO_CANCEL_OPTION or JOptionPane.OK_CANCEL_OPTION");
-
+        checkOptionType(newType);
         int            oldType = optionType;
-
         optionType = newType;
         firePropertyChange(OPTION_TYPE_PROPERTY, oldType, optionType);
     }
 
+    private static void checkOptionType(int newType) {
+        if (newType != DEFAULT_OPTION && newType != YES_NO_OPTION
+                && newType != YES_NO_CANCEL_OPTION
+                && newType != OK_CANCEL_OPTION) {
+            throw new RuntimeException("JOptionPane: option type must be one of"
+                    + " JOptionPane.DEFAULT_OPTION, JOptionPane.YES_NO_OPTION,"
+                    + " JOptionPane.YES_NO_CANCEL_OPTION"
+                    + " or JOptionPane.OK_CANCEL_OPTION");
+        }
+    }
+
     /**
      * Returns the type of options that are displayed.
      *
@@ -2385,7 +2396,15 @@
 
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        int newMessageType = f.get("messageType", 0);
+        checkMessageType(newMessageType);
+        messageType = newMessageType;
+        int newOptionType = f.get("optionType", 0);
+        checkOptionType(newOptionType);
+        optionType = newOptionType;
+        wantsInput = f.get("wantsInput", false);
 
         Vector<?>       values = (Vector)s.readObject();
         int             indexCounter = 0;
--- a/jdk/src/share/classes/javax/swing/JPopupMenu.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/JPopupMenu.java	Tue Jul 22 17:17:05 2014 +0400
@@ -1345,7 +1345,20 @@
     // implements javax.swing.MenuElement
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        int newDesiredLocationX = f.get("desiredLocationX", 0);
+        int newDesiredLocationY = f.get("desiredLocationY", 0);
+        Point p = adjustPopupLocationToFitScreen(
+                newDesiredLocationX, newDesiredLocationY);
+        desiredLocationX = p.x;
+        desiredLocationY = p.y;
+
+        label = (String) f.get("label", null);
+        paintBorder = f.get("paintBorder", false);
+        margin = (Insets) f.get("margin", null);
+        lightWeightPopup = f.get("lightWeightPopup", false);
+        selectionModel = (SingleSelectionModel) f.get("selectionModel", null);
 
         Vector<?>          values = (Vector)s.readObject();
         int             indexCounter = 0;
--- a/jdk/src/share/classes/javax/swing/JTabbedPane.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/JTabbedPane.java	Tue Jul 22 17:17:05 2014 +0400
@@ -495,10 +495,7 @@
      *
      */
     public void setTabPlacement(int tabPlacement) {
-        if (tabPlacement != TOP && tabPlacement != LEFT &&
-            tabPlacement != BOTTOM && tabPlacement != RIGHT) {
-            throw new IllegalArgumentException("illegal tab placement: must be TOP, BOTTOM, LEFT, or RIGHT");
-        }
+        checkTabPlacement(tabPlacement);
         if (this.tabPlacement != tabPlacement) {
             int oldValue = this.tabPlacement;
             this.tabPlacement = tabPlacement;
@@ -508,6 +505,14 @@
         }
     }
 
+    private static void checkTabPlacement(int tabPlacement) {
+        if (tabPlacement != TOP && tabPlacement != LEFT &&
+            tabPlacement != BOTTOM && tabPlacement != RIGHT) {
+            throw new IllegalArgumentException("illegal tab placement:"
+                    + " must be TOP, BOTTOM, LEFT, or RIGHT");
+        }
+    }
+
     /**
      * Returns the policy used by the tabbedpane to layout the tabs when all the
      * tabs will not fit within a single run.
@@ -551,9 +556,7 @@
      *
      */
     public void setTabLayoutPolicy(int tabLayoutPolicy) {
-        if (tabLayoutPolicy != WRAP_TAB_LAYOUT && tabLayoutPolicy != SCROLL_TAB_LAYOUT) {
-            throw new IllegalArgumentException("illegal tab layout policy: must be WRAP_TAB_LAYOUT or SCROLL_TAB_LAYOUT");
-        }
+        checkTabLayoutPolicy(tabLayoutPolicy);
         if (this.tabLayoutPolicy != tabLayoutPolicy) {
             int oldValue = this.tabLayoutPolicy;
             this.tabLayoutPolicy = tabLayoutPolicy;
@@ -563,6 +566,14 @@
         }
     }
 
+    private static void checkTabLayoutPolicy(int tabLayoutPolicy) {
+        if (tabLayoutPolicy != WRAP_TAB_LAYOUT
+                && tabLayoutPolicy != SCROLL_TAB_LAYOUT) {
+            throw new IllegalArgumentException("illegal tab layout policy:"
+                    + " must be WRAP_TAB_LAYOUT or SCROLL_TAB_LAYOUT");
+        }
+    }
+
     /**
      * Returns the currently selected index for this tabbedpane.
      * Returns -1 if there is no currently selected tab.
@@ -1816,7 +1827,19 @@
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException
     {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        int newTabPlacement = f.get("tabPlacement", TOP);
+        checkTabPlacement(newTabPlacement);
+        tabPlacement = newTabPlacement;
+        int newTabLayoutPolicy = f.get("tabLayoutPolicy", 0);
+        checkTabLayoutPolicy(newTabLayoutPolicy);
+        tabLayoutPolicy = newTabLayoutPolicy;
+        model = (SingleSelectionModel) f.get("model", null);
+        haveRegistered = f.get("haveRegistered", false);
+        changeListener = (ChangeListener) f.get("changeListener", null);
+        visComp = (Component) f.get("visComp", null);
+
         if ((ui != null) && (getUIClassID().equals(uiClassID))) {
             ui.installUI(this);
         }
--- a/jdk/src/share/classes/javax/swing/JTable.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/JTable.java	Tue Jul 22 17:17:05 2014 +0400
@@ -37,6 +37,7 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectInputStream;
 import java.io.IOException;
+import java.io.InvalidObjectException;
 
 import javax.accessibility.*;
 
@@ -1203,11 +1204,7 @@
      *              AUTO_RESIZE_ALL_COLUMNS        JTable.AUTO_RESIZE_ALL_COLUMNS
      */
     public void setAutoResizeMode(int mode) {
-        if ((mode == AUTO_RESIZE_OFF) ||
-            (mode == AUTO_RESIZE_NEXT_COLUMN) ||
-            (mode == AUTO_RESIZE_SUBSEQUENT_COLUMNS) ||
-            (mode == AUTO_RESIZE_LAST_COLUMN) ||
-            (mode == AUTO_RESIZE_ALL_COLUMNS)) {
+        if (isValidAutoResizeMode(mode)) {
             int old = autoResizeMode;
             autoResizeMode = mode;
             resizeAndRepaint();
@@ -1218,6 +1215,14 @@
         }
     }
 
+    private static boolean isValidAutoResizeMode(int mode) {
+        return (mode == AUTO_RESIZE_OFF)
+                || (mode == AUTO_RESIZE_NEXT_COLUMN)
+                || (mode == AUTO_RESIZE_SUBSEQUENT_COLUMNS)
+                || (mode == AUTO_RESIZE_LAST_COLUMN)
+                || (mode == AUTO_RESIZE_ALL_COLUMNS);
+    }
+
     /**
      * Returns the auto resize mode of the table.  The default mode
      * is AUTO_RESIZE_SUBSEQUENT_COLUMNS.
@@ -1439,10 +1444,14 @@
      *        bound: false
      */
     public void setDragEnabled(boolean b) {
+        checkDragEnabled(b);
+        dragEnabled = b;
+    }
+
+    private void checkDragEnabled(boolean b) {
         if (b && GraphicsEnvironment.isHeadless()) {
             throw new HeadlessException();
         }
-        dragEnabled = b;
     }
 
     /**
@@ -1489,6 +1498,11 @@
      * @since 1.6
      */
     public final void setDropMode(DropMode dropMode) {
+        checkDropMode(dropMode);
+        this.dropMode = dropMode;
+    }
+
+    private static void checkDropMode(DropMode dropMode) {
         if (dropMode != null) {
             switch (dropMode) {
                 case USE_SELECTION:
@@ -1499,14 +1513,12 @@
                 case ON_OR_INSERT:
                 case ON_OR_INSERT_ROWS:
                 case ON_OR_INSERT_COLS:
-                    this.dropMode = dropMode;
                     return;
             }
         }
-
-        throw new IllegalArgumentException(dropMode + ": Unsupported drop mode for table");
-    }
-
+        throw new IllegalArgumentException(dropMode
+                + ": Unsupported drop mode for table");
+    }
     /**
      * Returns the drop mode for this component.
      *
@@ -5865,7 +5877,75 @@
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException
     {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        TableModel newDataModel = (TableModel) f.get("dataModel", null);
+        if (newDataModel == null) {
+            throw new InvalidObjectException("Null dataModel");
+        }
+        dataModel = newDataModel;
+
+        TableColumnModel newColumnModel = (TableColumnModel) f.get("columnModel", null);
+        if (newColumnModel == null) {
+            throw new InvalidObjectException("Null columnModel");
+        }
+        columnModel = newColumnModel;
+
+        ListSelectionModel newSelectionModel = (ListSelectionModel) f.get("selectionModel", null);
+        if (newSelectionModel == null) {
+            throw new InvalidObjectException("Null selectionModel");
+        }
+        selectionModel = newSelectionModel;
+
+        tableHeader = (JTableHeader) f.get("tableHeader", null);
+        int newRowHeight = f.get("rowHeight", 0);
+        if (newRowHeight <= 0) {
+            throw new InvalidObjectException("Row height less than 1");
+        }
+        rowHeight = newRowHeight;
+
+        rowMargin = f.get("rowMargin", 0);
+        Color newGridColor = (Color) f.get("gridColor", null);
+        if (newGridColor == null) {
+            throw new InvalidObjectException("Null gridColor");
+        }
+        gridColor = newGridColor;
+
+        showHorizontalLines = f.get("showHorizontalLines", false);
+        showVerticalLines = f.get("showVerticalLines", false);
+        int newAutoResizeMode = f.get("autoResizeMode", 0);
+        if (!isValidAutoResizeMode(newAutoResizeMode)) {
+            throw new InvalidObjectException("autoResizeMode is not valid");
+        }
+        autoResizeMode = newAutoResizeMode;
+        autoCreateColumnsFromModel = f.get("autoCreateColumnsFromModel", false);
+        preferredViewportSize = (Dimension) f.get("preferredViewportSize", null);
+        rowSelectionAllowed = f.get("rowSelectionAllowed", false);
+        cellSelectionEnabled = f.get("cellSelectionEnabled", false);
+        selectionForeground = (Color) f.get("selectionForeground", null);
+        selectionBackground = (Color) f.get("selectionBackground", null);
+        rowModel = (SizeSequence) f.get("rowModel", null);
+
+        boolean newDragEnabled = f.get("dragEnabled", false);
+        checkDragEnabled(newDragEnabled);
+        dragEnabled = newDragEnabled;
+
+        surrendersFocusOnKeystroke = f.get("surrendersFocusOnKeystroke", false);
+        editorRemover = (PropertyChangeListener) f.get("editorRemover", null);
+        columnSelectionAdjusting = f.get("columnSelectionAdjusting", false);
+        rowSelectionAdjusting = f.get("rowSelectionAdjusting", false);
+        printError = (Throwable) f.get("printError", null);
+        isRowHeightSet = f.get("isRowHeightSet", false);
+        updateSelectionOnSort = f.get("updateSelectionOnSort", false);
+        ignoreSortChange = f.get("ignoreSortChange", false);
+        sorterChanged = f.get("sorterChanged", false);
+        autoCreateRowSorter = f.get("autoCreateRowSorter", false);
+        fillsViewportHeight = f.get("fillsViewportHeight", false);
+        DropMode newDropMode = (DropMode) f.get("dropMode",
+                DropMode.USE_SELECTION);
+        checkDropMode(newDropMode);
+        dropMode = newDropMode;
+
         if ((ui != null) && (getUIClassID().equals(uiClassID))) {
             ui.installUI(this);
         }
--- a/jdk/src/share/classes/javax/swing/JTree.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/JTree.java	Tue Jul 22 17:17:05 2014 +0400
@@ -1216,10 +1216,14 @@
      *        bound: false
      */
     public void setDragEnabled(boolean b) {
+        checkDragEnabled(b);
+        dragEnabled = b;
+    }
+
+    private static void checkDragEnabled(boolean b) {
         if (b && GraphicsEnvironment.isHeadless()) {
             throw new HeadlessException();
         }
-        dragEnabled = b;
     }
 
     /**
@@ -1262,18 +1266,23 @@
      * @since 1.6
      */
     public final void setDropMode(DropMode dropMode) {
+        checkDropMode(dropMode);
+        this.dropMode = dropMode;
+    }
+
+    private static void checkDropMode(DropMode dropMode) {
         if (dropMode != null) {
             switch (dropMode) {
                 case USE_SELECTION:
                 case ON:
                 case INSERT:
                 case ON_OR_INSERT:
-                    this.dropMode = dropMode;
                     return;
             }
         }
 
-        throw new IllegalArgumentException(dropMode + ": Unsupported drop mode for tree");
+        throw new IllegalArgumentException(dropMode +
+                ": Unsupported drop mode for tree");
     }
 
     /**
@@ -3089,7 +3098,34 @@
 
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        rootVisible = f.get("rootVisible", false);
+        rowHeight = f.get("rowHeight", 0);
+        rowHeightSet = f.get("rowHeightSet", false);
+        showsRootHandles = f.get("showsRootHandles", false);
+        showsRootHandlesSet = f.get("showsRootHandlesSet", false);
+        editable = f.get("editable", false);
+        largeModel = f.get("largeModel", false);
+        visibleRowCount = f.get("visibleRowCount", 0);
+        invokesStopCellEditing = f.get("invokesStopCellEditing", false);
+        scrollsOnExpand = f.get("scrollsOnExpand", false);
+        scrollsOnExpandSet = f.get("scrollsOnExpandSet", false);
+        toggleClickCount = f.get("toggleClickCount", 0);
+        leadPath = (TreePath) f.get("leadPath", null);
+        anchorPath = (TreePath) f.get("anchorPath", null);
+        expandsSelectedPaths = f.get("expandsSelectedPaths", false);
+        settingUI = f.get("settingUI", false);
+        boolean newDragEnabled = f.get("dragEnabled", false);
+        checkDragEnabled(newDragEnabled);
+        dragEnabled = newDragEnabled;
+        DropMode newDropMode = (DropMode) f.get("dropMode",
+                DropMode.USE_SELECTION);
+        checkDropMode(newDropMode);
+        dropMode = newDropMode;
+
+        expandRow = f.get("expandRow", -1);
+        dropTimer = (TreeTimer) f.get("dropTimer", null);
 
         // Create an instance of expanded state.
 
--- a/jdk/src/share/classes/javax/swing/LegacyGlueFocusTraversalPolicy.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/LegacyGlueFocusTraversalPolicy.java	Tue Jul 22 17:17:05 2014 +0400
@@ -194,7 +194,23 @@
     private void readObject(ObjectInputStream in)
         throws IOException, ClassNotFoundException
     {
-        in.defaultReadObject();
+        ObjectInputStream.GetField f = in.readFields();
+
+        @SuppressWarnings("unchecked")
+        HashMap<Component, Component>  newForwardMap =
+                (HashMap<Component, Component> ) f.get("forwardMap", null);
+        if (newForwardMap == null) {
+            throw new InvalidObjectException("Null forwardMap");
+        }
+        forwardMap = newForwardMap;
+        @SuppressWarnings("unchecked")
+        HashMap<Component, Component> newBackwardMap =
+                (HashMap<Component, Component>) f.get("backwardMap", null);
+        if (newBackwardMap == null) {
+            throw new InvalidObjectException("Null backwardMap");
+        }
+        backwardMap = newBackwardMap;
+
         delegatePolicy = (FocusTraversalPolicy)in.readObject();
         delegateManager = (DefaultFocusManager)in.readObject();
     }
--- a/jdk/src/share/classes/javax/swing/Timer.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/Timer.java	Tue Jul 22 17:17:05 2014 +0400
@@ -401,14 +401,15 @@
      * @see #setInitialDelay
      */
     public void setDelay(int delay) {
-        if (delay < 0) {
-            throw new IllegalArgumentException("Invalid delay: " + delay);
-        }
-        else {
+        checkDelay(delay, "Invalid delay: ");
             this.delay = delay;
         }
+
+    private static void checkDelay(int delay, String message) {
+        if (delay < 0) {
+            throw new IllegalArgumentException(message + delay);
     }
-
+    }
 
     /**
      * Returns the delay, in milliseconds,
@@ -435,14 +436,9 @@
      * @see #setDelay
      */
     public void setInitialDelay(int initialDelay) {
-        if (initialDelay < 0) {
-            throw new IllegalArgumentException("Invalid initial delay: " +
-                                               initialDelay);
-        }
-        else {
+        checkDelay(initialDelay, "Invalid initial delay: ");
             this.initialDelay = initialDelay;
         }
-    }
 
 
     /**
@@ -638,7 +634,26 @@
         throws ClassNotFoundException, IOException
     {
         this.acc = AccessController.getContext();
-        in.defaultReadObject();
+        ObjectInputStream.GetField f = in.readFields();
+
+        EventListenerList newListenerList = (EventListenerList)
+                f.get("listenerList", null);
+        if (newListenerList == null) {
+            throw new InvalidObjectException("Null listenerList");
+        }
+        listenerList = newListenerList;
+
+        int newInitialDelay = f.get("initialDelay", 0);
+        checkDelay(newInitialDelay, "Invalid initial delay: ");
+        initialDelay = newInitialDelay;
+
+        int newDelay = f.get("delay", 0);
+        checkDelay(newDelay, "Invalid delay: ");
+        delay = newDelay;
+
+        repeats = f.get("repeats", false);
+        coalesce = f.get("coalesce", false);
+        actionCommand = (String) f.get("actionCommand", null);
     }
 
     /*
--- a/jdk/src/share/classes/javax/swing/text/AbstractDocument.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/text/AbstractDocument.java	Tue Jul 22 17:17:05 2014 +0400
@@ -1429,8 +1429,13 @@
     private void readObject(ObjectInputStream s)
       throws ClassNotFoundException, IOException
     {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        documentProperties = (Dictionary) f.get("documentProperties", null);
         listenerList = new EventListenerList();
+        data = (Content) f.get("data", null);
+        context = (AttributeContext) f.get("context", null);
+        documentFilter = (DocumentFilter) f.get("documentFilter", null);
 
         // Restore bidi structure
         //REMIND(bcb) This creates an initial bidi element to account for
--- a/jdk/src/share/classes/javax/swing/text/DefaultCaret.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/text/DefaultCaret.java	Tue Jul 22 17:17:05 2014 +0400
@@ -1516,7 +1516,30 @@
     private void readObject(ObjectInputStream s)
       throws ClassNotFoundException, IOException
     {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        EventListenerList newListenerList = (EventListenerList) f.get("listenerList", null);
+        if (newListenerList == null) {
+            throw new InvalidObjectException("Null listenerList");
+        }
+        listenerList = newListenerList;
+        component = (JTextComponent) f.get("component", null);
+        updatePolicy = f.get("updatePolicy", 0);
+        visible = f.get("visible", false);
+        active = f.get("active", false);
+        dot = f.get("dot", 0);
+        mark = f.get("mark", 0);
+        selectionTag = f.get("selectionTag", null);
+        selectionVisible = f.get("selectionVisible", false);
+        flasher = (Timer) f.get("flasher", null);
+        magicCaretPosition = (Point) f.get("magicCaretPosition", null);
+        dotLTR = f.get("dotLTR", false);
+        markLTR = f.get("markLTR", false);
+        ownsSelection = f.get("ownsSelection", false);
+        forceCaretPositionChange = f.get("forceCaretPositionChange", false);
+        caretWidth = f.get("caretWidth", 0);
+        aspectRatio = f.get("aspectRatio", 0.0f);
+
         handler = new Handler();
         if (!s.readBoolean()) {
             dotBias = Position.Bias.Forward;
--- a/jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/text/DefaultStyledDocument.java	Tue Jul 22 17:17:05 2014 +0400
@@ -1082,8 +1082,9 @@
 
     private void readObject(ObjectInputStream s)
             throws ClassNotFoundException, IOException {
-        listeningStyles = new Vector<Style>();
-        s.defaultReadObject();
+        listeningStyles = new Vector<>();
+        ObjectInputStream.GetField f = s.readFields();
+        buffer = (ElementBuffer) f.get("buffer", null);
         // Reinstall style listeners.
         if (styleContextChangeListener == null &&
             listenerList.getListenerCount(DocumentListener.class) > 0) {
--- a/jdk/src/share/classes/javax/swing/text/JTextComponent.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/text/JTextComponent.java	Tue Jul 22 17:17:05 2014 +0400
@@ -683,10 +683,14 @@
      *        bound: false
      */
     public void setDragEnabled(boolean b) {
+        checkDragEnabled(b);
+        dragEnabled = b;
+    }
+
+    private static void checkDragEnabled(boolean b) {
         if (b && GraphicsEnvironment.isHeadless()) {
             throw new HeadlessException();
         }
-        dragEnabled = b;
     }
 
     /**
@@ -727,11 +731,15 @@
      * @since 1.6
      */
     public final void setDropMode(DropMode dropMode) {
+        checkDropMode(dropMode);
+        this.dropMode = dropMode;
+    }
+
+    private static void checkDropMode(DropMode dropMode) {
         if (dropMode != null) {
             switch (dropMode) {
                 case USE_SELECTION:
                 case INSERT:
-                    this.dropMode = dropMode;
                     return;
             }
         }
@@ -3747,7 +3755,34 @@
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException
     {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        model = (Document) f.get("model", null);
+        navigationFilter = (NavigationFilter) f.get("navigationFilter", null);
+        caretColor = (Color) f.get("caretColor", null);
+        selectionColor = (Color) f.get("selectionColor", null);
+        selectedTextColor = (Color) f.get("selectedTextColor", null);
+        disabledTextColor = (Color) f.get("disabledTextColor", null);
+        editable = f.get("editable", false);
+        margin = (Insets) f.get("margin", null);
+        focusAccelerator = f.get("focusAccelerator", '\0');
+        boolean newDragEnabled = f.get("dragEnabled", false);
+        checkDragEnabled(newDragEnabled);
+        dragEnabled = newDragEnabled;
+        DropMode newDropMode = (DropMode) f.get("dropMode",
+                DropMode.USE_SELECTION);
+        checkDropMode(newDropMode);
+        dropMode = newDropMode;
+        composedTextAttribute = (SimpleAttributeSet) f.get("composedTextAttribute", null);
+        composedTextContent = (String) f.get("composedTextContent", null);
+        composedTextStart = (Position) f.get("composedTextStart", null);
+        composedTextEnd = (Position) f.get("composedTextEnd", null);
+        latestCommittedTextStart = (Position) f.get("latestCommittedTextStart", null);
+        latestCommittedTextEnd = (Position) f.get("latestCommittedTextEnd", null);
+        composedTextCaret = (ComposedTextCaret) f.get("composedTextCaret", null);
+        checkedInputOverride = f.get("checkedInputOverride", false);
+        needToSendKeyTypedEvent = f.get("needToSendKeyTypedEvent", false);
+
         caretEvent = new MutableCaretEvent(this);
         addMouseListener(caretEvent);
         addFocusListener(caretEvent);
--- a/jdk/src/share/classes/javax/swing/text/MaskFormatter.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/text/MaskFormatter.java	Tue Jul 22 17:17:05 2014 +0400
@@ -649,7 +649,15 @@
      */
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        validCharacters = (String) f.get("validCharacters", null);
+        invalidCharacters = (String) f.get("invalidCharacters", null);
+        placeholderString = (String) f.get("placeholderString", null);
+        placeholder = f.get("placeholder", '\0');
+        containsLiteralChars = f.get("containsLiteralChars", false);
+        mask = (String) f.get("mask", null);
+
         try {
             updateInternalMask();
         } catch (ParseException pe) {
--- a/jdk/src/share/classes/javax/swing/text/StyleContext.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/text/StyleContext.java	Tue Jul 22 17:17:05 2014 +0400
@@ -714,11 +714,19 @@
       throws ClassNotFoundException, IOException
     {
         fontSearch = new FontKey(null, 0, 0);
-        fontTable = new Hashtable<FontKey, Font>();
+        fontTable = new Hashtable<>();
         search = new SimpleAttributeSet();
         attributesPool = Collections.
-                synchronizedMap(new WeakHashMap<SmallAttributeSet, WeakReference<SmallAttributeSet>>());
-        s.defaultReadObject();
+                synchronizedMap(new WeakHashMap<SmallAttributeSet,
+                        WeakReference<SmallAttributeSet>>());
+
+        ObjectInputStream.GetField f = s.readFields();
+        Style newStyles = (Style) f.get("styles", null);
+        if (newStyles == null) {
+            throw new InvalidObjectException("Null styles");
+        }
+        styles = newStyles;
+        unusedSets = f.get("unusedSets", 0);
     }
 
     // --- variables ---------------------------------------------------
@@ -734,7 +742,7 @@
 
     private Style styles;
     private transient FontKey fontSearch = new FontKey(null, 0, 0);
-    private transient Hashtable<FontKey, Font> fontTable = new Hashtable<FontKey, Font>();
+    private transient Hashtable<FontKey, Font> fontTable = new Hashtable<>();
 
     private transient Map<SmallAttributeSet, WeakReference<SmallAttributeSet>> attributesPool = Collections.
             synchronizedMap(new WeakHashMap<SmallAttributeSet, WeakReference<SmallAttributeSet>>());
--- a/jdk/src/share/classes/javax/swing/text/html/CSS.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/text/html/CSS.java	Tue Jul 22 17:17:05 2014 +0400
@@ -3555,10 +3555,13 @@
     private void readObject(ObjectInputStream s)
       throws ClassNotFoundException, IOException
     {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+        int newBaseFontSize = f.get("baseFontSize", 0);
+        setBaseFontSize(newBaseFontSize);
+
         // Reconstruct the hashtable.
         int numValues = s.readInt();
-        valueConvertor = new Hashtable<Object, Object>(Math.max(1, numValues));
+        valueConvertor = new Hashtable<>(Math.max(1, numValues));
         while (numValues-- > 0) {
             Object key = s.readObject();
             Object value = s.readObject();
--- a/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/tree/DefaultMutableTreeNode.java	Tue Jul 22 17:17:05 2014 +0400
@@ -1297,10 +1297,19 @@
 
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
-        Object[]      tValues;
 
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+        parent = (MutableTreeNode) f.get("parent", null);
+        @SuppressWarnings("unchecked")
+        Vector<TreeNode> newChildren = (Vector<TreeNode>) f.get("children", null);
+        boolean newAllowsChildren = f.get("allowsChildren", false);
+        if (!newAllowsChildren && newChildren != null && newChildren.size() > 0) {
+            throw new IllegalStateException("node does not allow children");
+        }
+        children = newChildren;
+        allowsChildren = newAllowsChildren;
 
+        Object[]      tValues;
         tValues = (Object[])s.readObject();
 
         if(tValues.length > 0 && tValues[0].equals("userObject"))
--- a/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellEditor.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/tree/DefaultTreeCellEditor.java	Tue Jul 22 17:17:05 2014 +0400
@@ -571,7 +571,18 @@
 
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+
+        renderer = (DefaultTreeCellRenderer) f.get("renderer", null);
+        Container newEditingContainer = (Container) f.get("editingContainer", null);
+        if (newEditingContainer == null) {
+            throw new InvalidObjectException("Null editingContainer");
+        }
+        editingContainer = newEditingContainer;
+        canEdit = f.get("canEdit", false);
+        borderSelectionColor = (Color) f.get("borderSelectionColor", null);
+        font = (Font) f.get("font", null);
+
 
         Vector<?>       values = (Vector)s.readObject();
         int             indexCounter = 0;
@@ -579,7 +590,12 @@
 
         if(indexCounter < maxCounter && values.elementAt(indexCounter).
            equals("realEditor")) {
-            realEditor = (TreeCellEditor)values.elementAt(++indexCounter);
+            TreeCellEditor newRealEditor =
+                    (TreeCellEditor)values.elementAt(++indexCounter);
+            if (newRealEditor == null) {
+                throw new InvalidObjectException("Null realEditor");
+            }
+            realEditor = newRealEditor;
             indexCounter++;
         }
     }
--- a/jdk/src/share/classes/javax/swing/tree/DefaultTreeModel.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/tree/DefaultTreeModel.java	Tue Jul 22 17:17:05 2014 +0400
@@ -691,7 +691,13 @@
 
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
+        ObjectInputStream.GetField f = s.readFields();
+        EventListenerList newListenerList = (EventListenerList) f.get("listenerList", null);
+        if (newListenerList == null) {
+            throw new InvalidObjectException("Null listenerList");
+        }
+        listenerList = newListenerList;
+        asksAllowsChildren = f.get("asksAllowsChildren", false);
 
         Vector<?>       values = (Vector)s.readObject();
         int             indexCounter = 0;
@@ -699,7 +705,11 @@
 
         if(indexCounter < maxCounter && values.elementAt(indexCounter).
            equals("root")) {
-            root = (TreeNode)values.elementAt(++indexCounter);
+            TreeNode newRoot  = (TreeNode)values.elementAt(++indexCounter);
+            if (newRoot == null) {
+                throw new InvalidObjectException("Null root");
+            }
+            root = newRoot;
             indexCounter++;
         }
     }
--- a/jdk/src/share/classes/javax/swing/tree/DefaultTreeSelectionModel.java	Tue Jul 22 17:10:50 2014 +0400
+++ b/jdk/src/share/classes/javax/swing/tree/DefaultTreeSelectionModel.java	Tue Jul 22 17:17:05 2014 +0400
@@ -151,17 +151,20 @@
     public void setSelectionMode(int mode) {
         int            oldMode = selectionMode;
 
-        selectionMode = mode;
-        if(selectionMode != TreeSelectionModel.SINGLE_TREE_SELECTION &&
-           selectionMode != TreeSelectionModel.CONTIGUOUS_TREE_SELECTION &&
-           selectionMode != TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION)
-            selectionMode = TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION;
+        selectionMode = validateSelectionMode(mode);
         if(oldMode != selectionMode && changeSupport != null)
             changeSupport.firePropertyChange(SELECTION_MODE_PROPERTY,
                                              Integer.valueOf(oldMode),
                                              Integer.valueOf(selectionMode));
     }
 
+    private static int validateSelectionMode(int mode) {
+        return (mode != TreeSelectionModel.SINGLE_TREE_SELECTION
+                && mode != TreeSelectionModel.CONTIGUOUS_TREE_SELECTION
+                && mode != TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION)
+                ? TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION : mode;
+    }
+
     /**
      * Returns the selection mode, one of <code>SINGLE_TREE_SELECTION</code>,
      * <code>DISCONTIGUOUS_TREE_SELECTION</code> or
@@ -1219,14 +1222,40 @@
 
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
-        Object[]      tValues;
+        ObjectInputStream.GetField f = s.readFields();
 
-        s.defaultReadObject();
+        changeSupport = (SwingPropertyChangeSupport) f.get("changeSupport", null);
+        selection = (TreePath[]) f.get("selection", null);
+        EventListenerList newListenerList = (EventListenerList) f.get("listenerList", null);
+        if (newListenerList == null) {
+            throw new InvalidObjectException("Null listenerList");
+        }
+        listenerList = newListenerList;
+        listSelectionModel = (DefaultListSelectionModel) f.get("listSelectionModel", null);
+        selectionMode = validateSelectionMode(f.get("selectionMode", 0));
+        leadPath = (TreePath) f.get("leadPath", null);
+        leadIndex = f.get("leadIndex", 0);
+        leadRow = f.get("leadRow", 0);
+        @SuppressWarnings("unchecked")
+        Hashtable<TreePath, Boolean> newUniquePaths =
+                (Hashtable<TreePath, Boolean>) f.get("uniquePaths", null);
+        uniquePaths = newUniquePaths;
+        @SuppressWarnings("unchecked")
+        Hashtable<TreePath, Boolean> newLastPaths =
+                (Hashtable<TreePath, Boolean>) f.get("lastPaths", null);
+        lastPaths = newLastPaths;
+        tempPaths = (TreePath[]) f.get("tempPaths", null);
 
+        Object[]      tValues;
         tValues = (Object[])s.readObject();
 
-        if(tValues.length > 0 && tValues[0].equals("rowMapper"))
-            rowMapper = (RowMapper)tValues[1];
+        if (tValues.length > 0 && tValues[0].equals("rowMapper")) {
+            RowMapper newRowMapper = (RowMapper) tValues[1];
+            if (newRowMapper == null) {
+                throw new InvalidObjectException("Null newRowMapper");
+            }
+            rowMapper = newRowMapper;
+        }
     }
 }