-
Notifications
You must be signed in to change notification settings - Fork 370
Correct data setting into Hash object #1589
Conversation
… long; 0s are added if source data is too short
@@ -37,7 +37,7 @@ public AbstractHash() { | |||
public AbstractHash(byte[] source, int sourceOffset, int sourceSize) { | |||
if(sourceSize < SIZE_IN_TRITS) { | |||
byte[] dest = new byte[SIZE_IN_BYTES]; | |||
System.arraycopy(source, sourceOffset, dest, 0, sourceSize - sourceOffset > source.length ? source.length - sourceOffset : sourceSize); | |||
System.arraycopy(source, sourceOffset, dest, 0, Math.min(dest.length, Math.min(source.length, sourceSize))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you still need source.length -sourceOffset
System.arraycopy(source, sourceOffset, dest, 0, Math.min(dest.length, Math.min(source.length, sourceSize))); | |
System.arraycopy(source, sourceOffset, dest, 0, Math.min(dest.length, Math.min(source.length - sourceOffset, sourceSize))); |
I don't we currently really use this size optimization. But maybe we will so might as well add support.
Would you like to wrap this line in a method with default
visibility, add the @VisibleForTesting
annotation, and add a unit task.
Since you are fixing a bug, we need to write a unit test so that the bug will never repeat itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hash object is just a storage for data. The constructor parameters (source
, sourceOffset
and sourceSize
) are description of the data source.
Hash object can't validate data. It can only check data syntax: the data array is not null and data coordinates (sourceOffset
and sourceSize
) are valid for this array. I.e. if syntax is incorrect, the hash object throws the corresponding exception: NullPointerException or ArrayIndexOutOfBoundsException.
If hash object tries to fix incorrect data source (Math.min(source.length - sourceOffset, sourceSize)
), it can be a reason of incorrect data using and a reason of a bug that hard to find.
I.e. my point of view: if sorceOffset + sorceSize > source.length
, ArrayIndexOutOfBoundsException has to be thrown to inform about the bug. Anyway you take a decision :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want to add the exception?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this situation the adding
if (sourceOffset + sourceSize > source.length) throw new ArrayIndexOutOfBoundsException();
to the code is incorrect, because IOTA uses
public Hash create(byte[] trits, int sourceOffset) { |
and
public Hash create(Class<?> modelClass, byte[] source) { |
As you can see the methods don't get
sourceSize
as input parameter and use Hash.SIZE_IN_TRITS
or Hash.SIZE_IN_BYTES
as values for sourceSize
to invoke the corresponding constructor.
BTW, I have checked the constructor with the code
if (sourceOffset + sourceSize > source.length) throw new ArrayIndexOutOfBoundsException();
and got errors for existing unit-tests:
TransactionViewModelTest.findShouldBeSuccessful:339 » ArrayIndexOutOfBounds
TransactionViewModelTest.findShouldReturnNull:352 » ArrayIndexOutOfBounds
As a result I suggest using the code I provided in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Description
Fixes #1566
Correct data setting into Hash object:
Type of change
How Has This Been Tested?
All existing unit-tests are passed.
Checklist: