Uploaded image for project: 'JBoss Marshalling'
  1. JBoss Marshalling
  2. JBMAR-63

Cannot write byte arrays bigger than 65536 bytes

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • 1.2.0.CR2
    • 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))

      { throw sharedMismatch(); }

      final int len = readUnsignedShort();
      return doReadArray(len, unshared);
      }

      It appears it should be reading an unsigned int.

              dlloyd@redhat.com David Lloyd
              rh-ee-galder Galder Zamarreño
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved: