Index: UnicodeString.java =================================================================== --- UnicodeString.java (revision 1407532) +++ UnicodeString.java (working copy) @@ -35,6 +35,26 @@ { int length = LittleEndian.getInt( data, offset ); + // If the length looks wrong, this might be because the offset is expected to be on a + // 4 byte boundary. Try changing it rather than getting an ArrayIndexOutOfBoundsException + // from LittleEndian.getByteArray. Also avoids creating a large byte[] if this is the case. + if (!validLength( length, data, offset + LittleEndian.INT_SIZE )) + { + if (offset % 4 != 0) + { + offset += 2; + } + + length = LittleEndian.getInt( data, offset ); + + if (!validLength(length, data, offset + LittleEndian.INT_SIZE)) + { + throw new IllegalPropertySetDataException( + "UnicodeString started at offset #" + offset + + " is not NULL-terminated" ); + } + } + if ( length == 0 ) { _value = new byte[0]; @@ -43,13 +63,18 @@ _value = LittleEndian.getByteArray( data, offset + LittleEndian.INT_SIZE, length * 2 ); - - if ( _value[length * 2 - 1] != 0 || _value[length * 2 - 2] != 0 ) - throw new IllegalPropertySetDataException( - "UnicodeString started at offset #" + offset - + " is not NULL-terminated" ); } + private boolean validLength(int length, byte[] data, int offset) { + if (length == 0) + { + return true; + } + int size = length * 2; + offset += size; + return offset < data.length && size >= 0 && data[offset-1] == 0 && data[offset-2] == 0; + } + int getSize() { return LittleEndian.INT_SIZE + _value.length;