diff options
author | Guilhem Lavaux <guilhem@kaffe.org> | 2004-02-28 21:28:53 +0000 |
---|---|---|
committer | Michael Koch <mkoch@gcc.gnu.org> | 2004-02-28 21:28:53 +0000 |
commit | 646e3290103bd932139f0aa5758258ea364b88a8 (patch) | |
tree | d0c8fb679a0816081a9e684d6257cbb4ca08a0e4 /libjava/java/io/ObjectInputStream.java | |
parent | ca67f278502e6f32aab0dd6ba4715762691f690d (diff) | |
download | gcc-646e3290103bd932139f0aa5758258ea364b88a8.zip gcc-646e3290103bd932139f0aa5758258ea364b88a8.tar.gz gcc-646e3290103bd932139f0aa5758258ea364b88a8.tar.bz2 |
2004-02-28 Guilhem Lavaux <guilhem@kaffe.org>
* java/io/ObjectInputStream.java
(readClassDescriptor): Keep elements of the mapping non null.
(checkTypeConsistency): New method.
(readFields): Fixed main loop and base logic. Small reindentation.
* java/io/ObjectStreamField.java
(lookupField): New method to update the field reference.
(checkFieldType): New method.
* java/io/ObjectStreamClass.java
(setClass, setFields): Call lookupField when building the field
database. Check the real field type.
From-SVN: r78627
Diffstat (limited to 'libjava/java/io/ObjectInputStream.java')
-rw-r--r-- | libjava/java/io/ObjectInputStream.java | 312 |
1 files changed, 184 insertions, 128 deletions
diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java index ce2d0ca..3c2dec9 100644 --- a/libjava/java/io/ObjectInputStream.java +++ b/libjava/java/io/ObjectInputStream.java @@ -1,6 +1,5 @@ /* ObjectInputStream.java -- Class used to read serialized objects - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 - Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -413,6 +412,64 @@ public class ObjectInputStream extends InputStream } /** + * This method makes a partial check of types for the fields + * contained given in arguments. It checks primitive types of + * fields1 against non primitive types of fields2. This method + * assumes the two lists has already been sorted according to + * the Java specification. + * + * @param name Name of the class owning the given fields. + * @param fields1 First list to check. + * @param fields2 Second list to check. + * @throws InvalidClassException if a field in fields1, which has a primitive type, is a present + * in the non primitive part in fields2. + */ + private void checkTypeConsistency(String name, ObjectStreamField[] fields1, ObjectStreamField[] fields2) + throws InvalidClassException + int nonPrimitive = 0; + + for (nonPrimitive = 0; + nonPrimitive < fields1.length + && fields1[nonPrimitive].isPrimitive(); nonPrimitive++) + { + } + + if (nonPrimitive == fields1.length) + return; + + int i = 0; + ObjectStreamField f1; + ObjectStreamField f2; + + while (i < fields2.length + && nonPrimitive < fields1.length) + { + f1 = fields1[nonPrimitive]; + f2 = fields2[i]; + + if (!f2.isPrimitive()) + break; + + int compVal = f1.getName().compareTo (f2.getName()); + + if (compVal < 0) + { + nonPrimitive++; + } + else if (compVal > 0) + { + i++; + } + else + { + throw new InvalidClassException + ("invalid field type for " + f2.getName() + + " in class " + name); + } + } + } + + /** * This method reads a class descriptor from the real input stream * and use these data to create a new instance of ObjectStreamClass. * Fields are sorted and ordered for the real read which occurs for @@ -497,6 +554,15 @@ public class ObjectInputStream extends InputStream int real_idx = 0; int map_idx = 0; + /* + * Check that there is no type inconsistencies between the lists. + * A special checking must be done for the two groups: primitive types and + * not primitive types. + */ + checkTypeConsistency(name, real_fields, stream_fields); + checkTypeConsistency(name, stream_fields, real_fields); + + while (stream_idx < stream_fields.length || real_idx < real_fields.length) { @@ -514,7 +580,7 @@ public class ObjectInputStream extends InputStream else { int comp_val = - real_fields[real_idx].compareTo (stream_fields[stream_idx]); + real_fields[real_idx].compareTo (stream_fields[stream_idx]); if (comp_val < 0) { @@ -528,21 +594,13 @@ public class ObjectInputStream extends InputStream { stream_field = stream_fields[stream_idx++]; real_field = real_fields[real_idx++]; - if(stream_field.getType() != real_field.getType()) - throw new InvalidClassException - ("invalid field type for " + real_field.getName() + - " in class " + name); + if (stream_field.getType() != real_field.getType()) + throw new InvalidClassException + ("invalid field type for " + real_field.getName() + + " in class " + name); } } - if (stream_field != null) - { - if (stream_field.getOffset() < 0) - stream_field = null; - else if (!stream_field.isToSet()) - real_field = null; - } - if (real_field != null && !real_field.isToSet()) - real_field = null; + /* If some of stream_fields does not correspond to any of real_fields, * or the opposite, then fieldmapping will go short. */ @@ -551,7 +609,7 @@ public class ObjectInputStream extends InputStream ObjectStreamField[] newfieldmapping = new ObjectStreamField[fieldmapping.length + 2]; System.arraycopy(fieldmapping, 0, - newfieldmapping, 0, fieldmapping.length); + newfieldmapping, 0, fieldmapping.length); fieldmapping = newfieldmapping; } fieldmapping[map_idx++] = stream_field; @@ -1577,121 +1635,119 @@ public class ObjectInputStream extends InputStream { ObjectStreamField stream_field = fields[i]; ObjectStreamField real_field = fields[i + 1]; - if(stream_field != null || real_field != null) - { - boolean read_value = stream_field != null; - boolean set_value = real_field != null; - String field_name; - char type; - if (stream_field != null) - { - field_name = stream_field.getName(); - type = stream_field.getTypeCode(); - } - else - { - field_name = real_field.getName(); - type = real_field.getTypeCode(); - } + boolean read_value = (stream_field != null && stream_field.getOffset() >= 0 && stream_field.isToSet()); + boolean set_value = (real_field != null && real_field.isToSet()); + String field_name; + char type; - switch(type) - { - case 'Z': - { - boolean value = - read_value ? this.realInputStream.readBoolean() : false; - if (dump && read_value && set_value) - dumpElementln(" " + field_name + ": " + value); - if (set_value) - real_field.setBooleanField(obj, value); - break; - } - case 'B': - { - byte value = - read_value ? this.realInputStream.readByte() : 0; - if (dump && read_value && set_value) - dumpElementln(" " + field_name + ": " + value); - if (set_value) - real_field.setByteField(obj, value); - break; - } - case 'C': - { - char value = - read_value ? this.realInputStream.readChar(): 0; - if (dump && read_value && set_value) - dumpElementln(" " + field_name + ": " + value); - if (set_value) - real_field.setCharField(obj, value); - break; - } - case 'D': - { - double value = - read_value ? this.realInputStream.readDouble() : 0; - if (dump && read_value && set_value) - dumpElementln(" " + field_name + ": " + value); - if (set_value) - real_field.setDoubleField(obj, value); - break; - } - case 'F': - { - float value = - read_value ? this.realInputStream.readFloat() : 0; - if (dump && read_value && set_value) - dumpElementln(" " + field_name + ": " + value); - if (set_value) - real_field.setFloatField(obj, value); - break; - } - case 'I': - { - int value = - read_value ? this.realInputStream.readInt() : 0; - if (dump && read_value && set_value) - dumpElementln(" " + field_name + ": " + value); - if (set_value) - real_field.setIntField(obj, value); - break; - } - case 'J': - { - long value = - read_value ? this.realInputStream.readLong() : 0; - if (dump && read_value && set_value) - dumpElementln(" " + field_name + ": " + value); - if (set_value) - real_field.setLongField(obj, value); - break; - } - case 'S': - { - short value = - read_value ? this.realInputStream.readShort() : 0; - if (dump && read_value && set_value) - dumpElementln(" " + field_name + ": " + value); - if (set_value) - real_field.setShortField(obj, value); - break; - } - case 'L': - case '[': - { - Object value = - read_value ? readObject() : null; - if (set_value) - real_field.setObjectField(obj, value); - break; - } - default: - throw new InternalError("Invalid type code: " + type); - } + if (stream_field != null) + { + field_name = stream_field.getName(); + type = stream_field.getTypeCode(); + } + else + { + field_name = real_field.getName(); + type = real_field.getTypeCode(); + } + + switch(type) + { + case 'Z': + { + boolean value = + read_value ? this.realInputStream.readBoolean() : false; + if (dump && read_value && set_value) + dumpElementln(" " + field_name + ": " + value); + if (set_value) + real_field.setBooleanField(obj, value); + break; + } + case 'B': + { + byte value = + read_value ? this.realInputStream.readByte() : 0; + if (dump && read_value && set_value) + dumpElementln(" " + field_name + ": " + value); + if (set_value) + real_field.setByteField(obj, value); + break; + } + case 'C': + { + char value = + read_value ? this.realInputStream.readChar(): 0; + if (dump && read_value && set_value) + dumpElementln(" " + field_name + ": " + value); + if (set_value) + real_field.setCharField(obj, value); + break; + } + case 'D': + { + double value = + read_value ? this.realInputStream.readDouble() : 0; + if (dump && read_value && set_value) + dumpElementln(" " + field_name + ": " + value); + if (set_value) + real_field.setDoubleField(obj, value); + break; + } + case 'F': + { + float value = + read_value ? this.realInputStream.readFloat() : 0; + if (dump && read_value && set_value) + dumpElementln(" " + field_name + ": " + value); + if (set_value) + real_field.setFloatField(obj, value); + break; + } + case 'I': + { + int value = + read_value ? this.realInputStream.readInt() : 0; + if (dump && read_value && set_value) + dumpElementln(" " + field_name + ": " + value); + if (set_value) + real_field.setIntField(obj, value); + break; + } + case 'J': + { + long value = + read_value ? this.realInputStream.readLong() : 0; + if (dump && read_value && set_value) + dumpElementln(" " + field_name + ": " + value); + if (set_value) + real_field.setLongField(obj, value); + break; + } + case 'S': + { + short value = + read_value ? this.realInputStream.readShort() : 0; + if (dump && read_value && set_value) + dumpElementln(" " + field_name + ": " + value); + if (set_value) + real_field.setShortField(obj, value); + break; + } + case 'L': + case '[': + { + Object value = + read_value ? readObject() : null; + if (set_value) + real_field.setObjectField(obj, value); + break; + } + default: + throw new InternalError("Invalid type code: " + type); } } } - + // Toggles writing primitive data to block-data buffer. private boolean setBlockDataMode (boolean on) { |