-
Bug
-
Resolution: Done
-
Major
-
1.2.0.CR2
-
None
-
None
Handling of byte arrays bigger than 65536 bytes appears to be broken. In the attached test case, where a byte array of 70000 bytes is being preloaded, the following is being thrown:
Caused by: java.lang.NullPointerException
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObjectArray(RiverUnmarshaller.java:1369)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadArray(RiverUnmarshaller.java:1412)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:291)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:158)
at org.jboss.marshalling.AbstractUnmarshaller.readObject(AbstractUnmarshaller.java:81)
at org.infinispan.container.entries.ImmortalCacheEntry$Externalizer.readObject(ImmortalCacheEntry.java:121)
The code shouldn't have gone through the doReadObjectArray() path since it's a byte array.
The problem comes from the differences writing byte arrays smaller and bigger than 65536:
} else if (len <= 65536)
{ write(unshared ? ID_ARRAY_MEDIUM_UNSHARED : ID_ARRAY_MEDIUM); writeShort(len); write(ID_PRIM_BYTE); write(bytes, 0, len); }else
{ write(unshared ? ID_ARRAY_LARGE_UNSHARED : ID_ARRAY_LARGE); writeInt(len); write(ID_PRIM_BYTE); write(bytes, 0, len); }For less than 65536, 2 bytes are used for lenght, whereas for longer, 4 bytes. The reading part appears to always read two bytes, so when reading long byte arrays, it takes the 3rd byte of the length which is not ID_PRIM_BYTE and so it fails.
Indeed, here's the reading part:
case ID_ARRAY_LARGE_UNSHARED: {
if (unshared != (leadByte == ID_ARRAY_LARGE_UNSHARED))
final int len = readUnsignedShort();
return doReadArray(len, unshared);
}
It appears it should be reading an unsigned int.
- blocks
-
ISPN-146 Preload with large amount of state fails
- Closed