[ 
https://issues.apache.org/jira/browse/HBASE-26197?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

chenglei updated HBASE-26197:
-----------------------------
    Description: 
MultiByteBuff.put(int destOffset, ByteBuff src, int srcOffset, int length) has 
some obvious bug:
* It is a common utility method and may be used in many situations, but its 
implementation seems  assuming that src {{ByteBuff}} is also a 
{{MultiByteBuff}} and byte size of every {{ByteBuffer}} in {{src.items}} has 
exactly the same size as every {{ByteBuffer}}  in the dest 
{{MultiByteBuff}},just as line 749 and line  754 illustrated:
{code:java}:
746     public MultiByteBuff put(int offset, ByteBuff src, int srcOffset, int 
length) {
747         checkRefCount();
748         int destItemIndex = getItemIndex(offset);
749         int srcItemIndex = getItemIndex(srcOffset);
750         ByteBuffer destItem = this.items[destItemIndex];
751         offset = offset - this.itemBeginPos[destItemIndex];
752
753        ByteBuffer srcItem = getItemByteBuffer(src, srcItemIndex);
754        srcOffset = srcOffset - this.itemBeginPos[srcItemIndex];
            ...
{code}
But looking the usage of this method in the hbase project, obviously the 
assumption is not right and even in following 
{{MultiByteBuff.getItemByteBuffer}} which inside the above 
{{MultiByteBuff.put}} method, it also considing the case the src {{ByteBuff}} 
may be {{SingleByteBuff}},which is in contradiction with line 754 in the above 
{{MultiByteBuff.put}}:

*    {code:java}
       private static ByteBuffer getItemByteBuffer(ByteBuff buf, int index) {
             return (buf instanceof SingleByteBuff) ? buf.nioByteBuffers()[0]
                   : ((MultiByteBuff) buf).items[index];
        }
   {code} 

* If src is {{SingleByteBuff}} and its remaining space is fewer than 
length,when remaining space is exhausted, this {{MultiByteBuff.put}} method 
would not throw any exception and continue to put src {{ByteBuff}} again from 
position 0 because above {{MultiByteBuff.getItemByteBuffer}} ignores index 
paramter for   {{SingleByteBuff}} . Obviously, this behavior
is much strange and unexpected.


  was:
MultiByteBuff.put(int destOffset, ByteBuff src, int srcOffset, int length) has 
some obvious bug:
* It is a common utility method and may be used in many situations, but its 
implementation seems  assuming that src {{ByteBuff}} is also a 
{{MultiByteBuff}} and byte size of every {{ByteBuffer}} in {{src.items}} has 
exactly the same size as every {{ByteBuffer}}  in the dest 
{{MultiByteBuff}},just as line 749 and line  754 illustrated:
{code:java}:
746     public MultiByteBuff put(int offset, ByteBuff src, int srcOffset, int 
length) {
747         checkRefCount();
748         int destItemIndex = getItemIndex(offset);
749         int srcItemIndex = getItemIndex(srcOffset);
750         ByteBuffer destItem = this.items[destItemIndex];
751         offset = offset - this.itemBeginPos[destItemIndex];
752
753        ByteBuffer srcItem = getItemByteBuffer(src, srcItemIndex);
754        srcOffset = srcOffset - this.itemBeginPos[srcItemIndex];
            ...
{code}
But looking the usage of this method in the hbase project, obviously the 
assumption is not right and even in following 
{{MultiByteBuff.getItemByteBuffer}} which inside the above 
{{MultiByteBuff.put}} method, it also considing the case the src {{ByteBuff}} 
may be {{SingleByteBuff}},which is in contradiction with line 754 in the above 
{{MultiByteBuff.put}}:

*    {code:java}
       private static ByteBuffer getItemByteBuffer(ByteBuff buf, int index) {
             return (buf instanceof SingleByteBuff) ? buf.nioByteBuffers()[0]
                   : ((MultiByteBuff) buf).items[index];
        }
   {code} 

* If src is {{SingleByteBuff}} and its remaining space is fewer than 
length,when remaining space is exhausted, this {{MultiByteBuff.put}} method 
would not throw any exception and continue to put src {{ByteBuff}} again from 
position 0 because above {{MultiByteBuff.getItemByteBuffer}} ignores index 
paramter for   {{SingleByteBuff}} . Obviously, this behavior
is strange and unexpected.



> Fix some obvious bugs in MultiByteBuff.put
> ------------------------------------------
>
>                 Key: HBASE-26197
>                 URL: https://issues.apache.org/jira/browse/HBASE-26197
>             Project: HBase
>          Issue Type: Bug
>    Affects Versions: 3.0.0-alpha-1, 2.4.5
>            Reporter: chenglei
>            Priority: Major
>
> MultiByteBuff.put(int destOffset, ByteBuff src, int srcOffset, int length) 
> has some obvious bug:
> * It is a common utility method and may be used in many situations, but its 
> implementation seems  assuming that src {{ByteBuff}} is also a 
> {{MultiByteBuff}} and byte size of every {{ByteBuffer}} in {{src.items}} has 
> exactly the same size as every {{ByteBuffer}}  in the dest 
> {{MultiByteBuff}},just as line 749 and line  754 illustrated:
> {code:java}:
> 746     public MultiByteBuff put(int offset, ByteBuff src, int srcOffset, int 
> length) {
> 747         checkRefCount();
> 748         int destItemIndex = getItemIndex(offset);
> 749         int srcItemIndex = getItemIndex(srcOffset);
> 750         ByteBuffer destItem = this.items[destItemIndex];
> 751         offset = offset - this.itemBeginPos[destItemIndex];
> 752
> 753        ByteBuffer srcItem = getItemByteBuffer(src, srcItemIndex);
> 754        srcOffset = srcOffset - this.itemBeginPos[srcItemIndex];
>             ...
> {code}
> But looking the usage of this method in the hbase project, obviously the 
> assumption is not right and even in following 
> {{MultiByteBuff.getItemByteBuffer}} which inside the above 
> {{MultiByteBuff.put}} method, it also considing the case the src {{ByteBuff}} 
> may be {{SingleByteBuff}},which is in contradiction with line 754 in the 
> above {{MultiByteBuff.put}}:
> *    {code:java}
>        private static ByteBuffer getItemByteBuffer(ByteBuff buf, int index) {
>              return (buf instanceof SingleByteBuff) ? buf.nioByteBuffers()[0]
>                    : ((MultiByteBuff) buf).items[index];
>         }
>    {code} 
> * If src is {{SingleByteBuff}} and its remaining space is fewer than 
> length,when remaining space is exhausted, this {{MultiByteBuff.put}} method 
> would not throw any exception and continue to put src {{ByteBuff}} again from 
> position 0 because above {{MultiByteBuff.getItemByteBuffer}} ignores index 
> paramter for   {{SingleByteBuff}} . Obviously, this behavior
> is much strange and unexpected.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to