Wed, 22 Jun 2016 18:25:00 +0100
8146975: NullPointerException in IIOPInputStream.inputClassFields
Reviewed-by: chegar, rriggs, coffeys
src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Wed Jun 01 13:35:52 2016 +0200 1.2 +++ b/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Wed Jun 22 18:25:00 2016 +0100 1.3 @@ -2230,7 +2230,7 @@ 1.4 * REVISIT -- This code doesn't do what the comment says to when 1.5 * getField() is null! 1.6 */ 1.7 - private void inputClassFields(Object o, Class cl, 1.8 + private void inputClassFields(Object o, final Class<?> cl, 1.9 ObjectStreamField[] fields, 1.10 com.sun.org.omg.SendingContext.CodeBase sender) 1.11 throws InvalidClassException, StreamCorruptedException, 1.12 @@ -2264,21 +2264,31 @@ 1.13 } 1.14 1.15 try { 1.16 - Class fieldCl = fields[i].getClazz(); 1.17 + Class<?> fieldCl = fields[i].getClazz(); 1.18 if ((objectValue != null) 1.19 && (!fieldCl.isAssignableFrom( 1.20 objectValue.getClass()))) { 1.21 throw new IllegalArgumentException("Field mismatch"); 1.22 } 1.23 - Field classField = null; 1.24 + Field declaredClassField = null; 1.25 + final String inputStreamFieldName = fields[i].getName(); 1.26 try { 1.27 - classField = cl.getDeclaredField(fields[i].getName()); 1.28 - } catch (NoSuchFieldException nsfEx) { 1.29 - throw new IllegalArgumentException(nsfEx); 1.30 + declaredClassField = getDeclaredField( cl, inputStreamFieldName); 1.31 + } catch (PrivilegedActionException paEx) { 1.32 + throw new IllegalArgumentException( 1.33 + (NoSuchFieldException) paEx.getException()); 1.34 } catch (SecurityException secEx) { 1.35 - throw new IllegalArgumentException(secEx.getCause()); 1.36 + throw new IllegalArgumentException(secEx); 1.37 + } catch (NullPointerException npEx) { 1.38 + continue; 1.39 + } catch (NoSuchFieldException e) { 1.40 + continue; 1.41 } 1.42 - Class<?> declaredFieldClass = classField.getType(); 1.43 + 1.44 + if (declaredClassField == null) { 1.45 + continue; 1.46 + } 1.47 + Class<?> declaredFieldClass = declaredClassField.getType(); 1.48 1.49 // check input field type is a declared field type 1.50 // input field is a subclass of the declared field 1.51 @@ -2291,15 +2301,24 @@ 1.52 } 1.53 bridge.putObject( o, fields[i].getFieldID(), objectValue ) ; 1.54 // reflective code: fields[i].getField().set( o, objectValue ) ; 1.55 - } catch (IllegalArgumentException e) { 1.56 - ClassCastException exc = new ClassCastException("Assigning instance of class " + 1.57 - objectValue.getClass().getName() + 1.58 - " to field " + 1.59 - currentClassDesc.getName() + 1.60 - '#' + 1.61 - fields[i].getField().getName()); 1.62 - exc.initCause( e ) ; 1.63 - throw exc ; 1.64 + } catch (IllegalArgumentException iaEx) { 1.65 + String objectValueClassName = "null"; 1.66 + String currentClassDescClassName = "null"; 1.67 + String fieldName = "null"; 1.68 + if (objectValue != null) { 1.69 + objectValueClassName = objectValue.getClass().getName(); 1.70 + } 1.71 + if (currentClassDesc != null) { 1.72 + currentClassDescClassName = currentClassDesc.getName(); 1.73 + } 1.74 + if (fields[i] != null && fields[i].getField() != null) { 1.75 + fieldName = fields[i].getField().getName(); 1.76 + } 1.77 + ClassCastException ccEx = new ClassCastException( 1.78 + "Assigning instance of class " + objectValueClassName 1.79 + + " to field " + currentClassDescClassName + '#' + fieldName); 1.80 + ccEx.initCause( iaEx ) ; 1.81 + throw ccEx ; 1.82 } 1.83 } // end : for loop 1.84 } 1.85 @@ -2595,9 +2614,9 @@ 1.86 1.87 } 1.88 1.89 - private static void setObjectField(Object o, Class c, String fieldName, Object v) { 1.90 + private static void setObjectField(Object o, Class<?> c, String fieldName, Object v) { 1.91 try { 1.92 - Field fld = c.getDeclaredField( fieldName ) ; 1.93 + Field fld = getDeclaredField( c, fieldName ) ; 1.94 Class fieldCl = fld.getType(); 1.95 if(v != null && !fieldCl.isInstance(v)) { 1.96 throw new Exception(); 1.97 @@ -2617,10 +2636,10 @@ 1.98 } 1.99 } 1.100 1.101 - private static void setBooleanField(Object o, Class c, String fieldName, boolean v) 1.102 + private static void setBooleanField(Object o, Class<?> c, String fieldName, boolean v) 1.103 { 1.104 try { 1.105 - Field fld = c.getDeclaredField( fieldName ) ; 1.106 + Field fld = getDeclaredField( c, fieldName ) ; 1.107 if ((fld != null) && (fld.getType() == Boolean.TYPE)) { 1.108 long key = bridge.objectFieldOffset( fld ) ; 1.109 bridge.putBoolean( o, key, v ) ; 1.110 @@ -2640,10 +2659,10 @@ 1.111 } 1.112 } 1.113 1.114 - private static void setByteField(Object o, Class c, String fieldName, byte v) 1.115 + private static void setByteField(Object o, Class<?> c, String fieldName, byte v) 1.116 { 1.117 try { 1.118 - Field fld = c.getDeclaredField( fieldName ) ; 1.119 + Field fld = getDeclaredField( c, fieldName ) ; 1.120 if ((fld != null) && (fld.getType() == Byte.TYPE)) { 1.121 long key = bridge.objectFieldOffset( fld ) ; 1.122 bridge.putByte( o, key, v ) ; 1.123 @@ -2663,10 +2682,10 @@ 1.124 } 1.125 } 1.126 1.127 - private static void setCharField(Object o, Class c, String fieldName, char v) 1.128 + private static void setCharField(Object o, Class<?> c, String fieldName, char v) 1.129 { 1.130 try { 1.131 - Field fld = c.getDeclaredField( fieldName ) ; 1.132 + Field fld = getDeclaredField( c, fieldName ) ; 1.133 if ((fld != null) && (fld.getType() == Character.TYPE)) { 1.134 long key = bridge.objectFieldOffset( fld ) ; 1.135 bridge.putChar( o, key, v ) ; 1.136 @@ -2686,10 +2705,10 @@ 1.137 } 1.138 } 1.139 1.140 - private static void setShortField(Object o, Class c, String fieldName, short v) 1.141 + private static void setShortField(Object o, Class<?> c, String fieldName, short v) 1.142 { 1.143 try { 1.144 - Field fld = c.getDeclaredField( fieldName ) ; 1.145 + Field fld = getDeclaredField( c, fieldName ) ; 1.146 if ((fld != null) && (fld.getType() == Short.TYPE)) { 1.147 long key = bridge.objectFieldOffset( fld ) ; 1.148 bridge.putShort( o, key, v ) ; 1.149 @@ -2709,10 +2728,10 @@ 1.150 } 1.151 } 1.152 1.153 - private static void setIntField(Object o, Class c, String fieldName, int v) 1.154 + private static void setIntField(Object o, final Class<?> c, final String fieldName, int v) 1.155 { 1.156 try { 1.157 - Field fld = c.getDeclaredField( fieldName ) ; 1.158 + Field fld = getDeclaredField( c, fieldName ) ; 1.159 if ((fld != null) && (fld.getType() == Integer.TYPE)) { 1.160 long key = bridge.objectFieldOffset( fld ) ; 1.161 bridge.putInt( o, key, v ) ; 1.162 @@ -2732,10 +2751,10 @@ 1.163 } 1.164 } 1.165 1.166 - private static void setLongField(Object o, Class c, String fieldName, long v) 1.167 + private static void setLongField(Object o, Class<?> c, String fieldName, long v) 1.168 { 1.169 try { 1.170 - Field fld = c.getDeclaredField( fieldName ) ; 1.171 + Field fld = getDeclaredField( c, fieldName ) ; 1.172 if ((fld != null) && (fld.getType() == Long.TYPE)) { 1.173 long key = bridge.objectFieldOffset( fld ) ; 1.174 bridge.putLong( o, key, v ) ; 1.175 @@ -2755,10 +2774,10 @@ 1.176 } 1.177 } 1.178 1.179 - private static void setFloatField(Object o, Class c, String fieldName, float v) 1.180 + private static void setFloatField(Object o, Class<?> c, String fieldName, float v) 1.181 { 1.182 try { 1.183 - Field fld = c.getDeclaredField( fieldName ) ; 1.184 + Field fld = getDeclaredField( c, fieldName ) ; 1.185 if ((fld != null) && (fld.getType() == Float.TYPE)) { 1.186 long key = bridge.objectFieldOffset( fld ) ; 1.187 bridge.putFloat( o, key, v ) ; 1.188 @@ -2778,10 +2797,10 @@ 1.189 } 1.190 } 1.191 1.192 - private static void setDoubleField(Object o, Class c, String fieldName, double v) 1.193 + private static void setDoubleField(Object o, Class<?> c, String fieldName, double v) 1.194 { 1.195 try { 1.196 - Field fld = c.getDeclaredField( fieldName ) ; 1.197 + Field fld = getDeclaredField(c, fieldName ) ; 1.198 if ((fld != null) && (fld.getType() == Double.TYPE)) { 1.199 long key = bridge.objectFieldOffset( fld ) ; 1.200 bridge.putDouble( o, key, v ) ; 1.201 @@ -2801,6 +2820,23 @@ 1.202 } 1.203 } 1.204 1.205 + 1.206 + private static Field getDeclaredField(final Class<?> c, 1.207 + final String fieldName) 1.208 + throws PrivilegedActionException, NoSuchFieldException, SecurityException { 1.209 + if (System.getSecurityManager() == null) { 1.210 + return c.getDeclaredField(fieldName); 1.211 + } else { 1.212 + return AccessController 1.213 + .doPrivileged(new PrivilegedExceptionAction<Field>() { 1.214 + public Field run() 1.215 + throws NoSuchFieldException { 1.216 + return c.getDeclaredField(fieldName); 1.217 + } 1.218 + }); 1.219 + } 1.220 + } 1.221 + 1.222 /** 1.223 * This class maintains a map of stream position to 1.224 * an Object currently being deserialized. It is used 1.225 @@ -2811,12 +2847,12 @@ 1.226 */ 1.227 static class ActiveRecursionManager 1.228 { 1.229 - private Map offsetToObjectMap; 1.230 + private Map<Integer, Object> offsetToObjectMap; 1.231 1.232 public ActiveRecursionManager() { 1.233 // A hash map is unsynchronized and allows 1.234 // null values 1.235 - offsetToObjectMap = new HashMap(); 1.236 + offsetToObjectMap = new HashMap<>(); 1.237 } 1.238 1.239 // Called right after allocating a new object.