You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Gary Gregory (JIRA)" <ji...@apache.org> on 2017/11/06 15:53:00 UTC

[jira] [Comment Edited] (COLLECTIONS-599) HashEntry array object naming data initialized with double the size during deserialization

    [ https://issues.apache.org/jira/browse/COLLECTIONS-599?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15714952#comment-15714952 ] 

Gary Gregory edited comment on COLLECTIONS-599 at 11/6/17 3:52 PM:
-------------------------------------------------------------------

Possible fix would be calculating threshold before putting the data in doReadObject API. 
Calculating threshold would not initialize the array by double.
Please find the code below : 

{code:java}
protected void doReadObject(ObjectInputStream in)
    throws IOException, ClassNotFoundException
  {
    this.loadFactor = in.readFloat();
    int capacity = in.readInt();
    int size = in.readInt();
    init();
    this.data = new HashEntry[capacity];
    this.threshold = calculateThreshold(this.data.length, this.loadFactor);
    for (int i = 0; i < size; i++)
    {
      Object key = in.readObject();
      Object value = in.readObject();
      put(key, value);
    }
    
  }
{code}

Why these is critical because this version of jar are been used by struts 2 . 
I saw these been changed in version 4.1 , but if you classes in 4.1 are declared in different package.
We should have provide fix for these version as we cant change jars which is internally using these stuff. 




was (Author: tejast5):
Possible fix would be calculating threshold before putting the data in doReadObject API. 
Calculating threshold would not initialize the array by double.
Please find the code below : 

protected void doReadObject(ObjectInputStream in)
    throws IOException, ClassNotFoundException
  {
    this.loadFactor = in.readFloat();
    int capacity = in.readInt();
    int size = in.readInt();
    init();
    this.data = new HashEntry[capacity];
    this.threshold = calculateThreshold(this.data.length, this.loadFactor);
    for (int i = 0; i < size; i++)
    {
      Object key = in.readObject();
      Object value = in.readObject();
      put(key, value);
    }
    
  }

Why these is critical because this version of jar are been used by struts 2 . 
I saw these been changed in version 4.1 , but if you classes in 4.1 are declared in different package.
We should have provide fix for these version as we cant change jars which is internally using these stuff. 



> HashEntry array object naming data initialized with double the size during deserialization
> ------------------------------------------------------------------------------------------
>
>                 Key: COLLECTIONS-599
>                 URL: https://issues.apache.org/jira/browse/COLLECTIONS-599
>             Project: Commons Collections
>          Issue Type: Bug
>          Components: Collection, Map
>    Affects Versions: 3.1
>            Reporter: Tejas Patel
>            Priority: Critical
>             Fix For: 4.1
>
>
> Common collections 3.1 and 3.2 are used at many places and frameworks including struts2. 
> Supose a LinkedMap object it is created and have size greater than zero is serialized. While deserializing this object , array of HashEntry naming data delacred in AbstractHashedMap always initialises with a new capacity of double its double of the serialized object. 
> Please see the below API declared in AbstractHashedMap class :
> {code:java}
> protected void checkCapacity()
>   {
>     if (this.size >= this.threshold)
>     {
>       int newCapacity = this.data.length * 2;
>       if (newCapacity <= 1073741824) {
>         ensureCapacity(newCapacity);
>       }
>     }
>   }
> {code}



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)