Mantis Bugtracker
  

Viewing Issue Advanced Details Jump to Notes ] View Simple ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0004069 [Hessian] crash always 06-04-10 05:49 07-18-23 02:04
Reporter raggatt2000 View Status public  
Assigned To
Priority normal Resolution open Platform
Status new   OS
Projection none   OS Version
ETA none Fixed in Version Product Version 4.0.7
  Product Build
Summary 0004069: IndexOutOfBoundsException when deserializing Google Collections
Description I?m getting an issue when deserializing classes containing Google Collections classes - Hessian throws an IndexOutOfBoundsException when calling readObject() on the Hessian2Input instance. I?ve attached an example class which replicates the exception. I?m running using the following:

Java 6 (jdk 1.6.0_17)
Google Collections 1.0
Hessian 4.0.7 - (note: also affects 4.0.x)

As far as I can tell, the exception seems to occur as a result of one of/a combination of the following:
- ImmutableMap implements custom serialization methods writeReplace() and readResolve()
- A single instance being referenced from multiple locations

Resulting exception is:

Exception in thread "main" com.caucho.hessian.io.HessianFieldException: com.ml.HessianTest.test: com.ml.HessianTest cannot be assigned from null
    at com.caucho.hessian.io.UnsafeDeserializer.logDeserializeError(UnsafeDeserializer.java:774)
    at com.caucho.hessian.io.UnsafeDeserializer$ObjectFieldDeserializer.deserialize(UnsafeDeserializer.java:421)
    at com.caucho.hessian.io.UnsafeDeserializer.readObject(UnsafeDeserializer.java:239)
    at com.caucho.hessian.io.UnsafeDeserializer.readObject(UnsafeDeserializer.java:150)
    at com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2188)
    at com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2109)
    at com.caucho.hessian.io.MapDeserializer.readMap(MapDeserializer.java:114)
    at com.caucho.hessian.io.SerializerFactory.readMap(SerializerFactory.java:522)
    at com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2079)
    at com.ml.HessianTest.main(HessianTest.java:51)
Caused by: java.lang.IndexOutOfBoundsException: Index: 80, Size: 73
    at java.util.ArrayList.RangeCheck(ArrayList.java:547)
    at java.util.ArrayList.get(ArrayList.java:322)
    at com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1790)
    at com.caucho.hessian.io.UnsafeDeserializer$ObjectFieldDeserializer.deserialize(UnsafeDeserializer.java:417)
    ... 8 more

Java code for replicating below:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;

import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;

public class HessianTest implements Serializable {

    private final Map<String, String> map;
    private final HessianTest test;

    private HessianTest(Map<String, String> map, HessianTest test) {
        this.map = map;
        this.test = test;
    }

    public static void main(String[] args) throws IOException {

        Map<String, HessianTest> map = Maps.newHashMap();
        HessianTest lastTest = null;
        //seems to start failing when limit set to 18
        for (int i = 0; i < 18; i++) {
            HessianTest test = new HessianTest(ImmutableMap.of("id" + i, "id" + i), lastTest);
            //following line works fine - probably indicating
            //that the issue is with the google collection
            //serialization routine
            //HessianTest test = new HessianTest(Collections.singletonMap("id" + i, "id" + i), lastTest);
            map.put("id" + i, test);
            lastTest = test;
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Hessian2Output oos = new Hessian2Output(baos);

        oos.writeObject(map);
        oos.close();
        baos.close();

        byte[] input = baos.toByteArray();

        ByteArrayInputStream bais = new ByteArrayInputStream(input);
        Hessian2Input ois = new Hessian2Input(bais);

        ois.readObject();

    }

    private static final long serialVersionUID = 1L;

}
Steps To Reproduce
Additional Information
Attached Files  HessianTest.java [^] (1,605 bytes) 06-04-10 05:49
 IdentityIntMap.java [^] (6,809 bytes) 06-08-10 11:24

- Relationships

- Notes
(0004636)
raggatt2000
06-08-10 11:22

I've found the bug which is causing this issue. It's in the put method of the IdentityIntMap class.

The current implementation of the remove method only virtually removes the Object from the map. Instead of nulling out the reference which which is being removed, it is allocated a reference value of -1. All is fine until the map grows too large and needs to be rebalanced. The put method is called to reinsert all the objects back into the new larger map and each object is counted again when size is incremented. To fix, the following line:

_size++;

should be changed to:

if (value != -1)
    _size++;

The deleted object will then be ignored by the put method.

I'll attach the suggested fixed class to this issue.

Thanks
 
(0004973)
Aaron Pieper
01-19-11 12:18

Thank you, this fix worked for me.

A similar error can be caused if you try to deserialize a mangled inputstream. For example, I converted a byte array to a string using an invalid string encoding. When I tried to deserialize the resulting string input stream using Hessian, it threw an IndexOutOfBoundsException in the same place.
 
(0005273)
alexeyre
05-22-11 06:55

I've had the same issue with a Hessian service which returns an ArrayList or object which contain fields of type org.w3c.Node.
The fix provided in this bug worked for me too.

Will this bug-fix be released sometime soon ?
 

- Issue History
Date Modified Username Field Change
06-04-10 05:49 raggatt2000 New Issue
06-04-10 05:49 raggatt2000 File Added: HessianTest.java
06-04-10 05:54 raggatt2000 Issue Monitored: raggatt2000
06-08-10 11:22 raggatt2000 Note Added: 0004636
06-08-10 11:24 raggatt2000 File Added: IdentityIntMap.java
01-19-11 12:18 Aaron Pieper Note Added: 0004973
05-22-11 06:55 alexeyre Note Added: 0005273
05-23-11 01:51 alexeyre Issue Monitored: alexeyre
07-17-23 19:18 earlymine Note Added: 0007210
07-18-23 02:04 WilliamThompson Note Added: 0007215
11-14-23 17:29 ferg Note Deleted: 0007210
11-14-23 17:29 ferg Note Deleted: 0007215


Mantis 1.0.0rc3[^]
Copyright © 2000 - 2005 Mantis Group
45 total queries executed.
32 unique queries executed.
Powered by Mantis Bugtracker