Commit 0da5680b authored by Mattias Finné's avatar Mattias Finné
Browse files

Explicitly fails on trying to encode too large ID in importer

A couple of higher-order bits of the long values when using INTEGER
id type in the importer are reserved for internal use, but the
LongEncoder didn't check that the incoming ID values were not using
any of those bits. This would instead produce unexpected ordering
failures later on in the sorting process.
parent a3430d09
Showing with 33 additions and 0 deletions
+33 -0
......@@ -21,16 +21,22 @@ package org.neo4j.internal.batchimport.cache.idmapping.string;
import static java.lang.Math.log10;
import static java.lang.Math.max;
import static org.neo4j.util.Preconditions.checkArgument;
/**
* {@link Encoder} that assumes that the entered strings can be parsed to {@link Long} directly.
* The 8 higher-order bits are reserved for internal use and therefore the IDs cannot use the whole range of the long.
*/
public class LongEncoder implements Encoder
{
private static final long ID_BITS = 0x00FFFFFF_FFFFFFFFL;
private static final long RESERVED_BITS = ~ID_BITS;
@Override
public long encode( Object value )
{
long longValue = ((Number)value).longValue();
checkArgument( (longValue & RESERVED_BITS) == 0, "Invalid integer ID %d, it must be %d <= id <= 0", longValue, ID_BITS );
long length = numberOfDigits( longValue );
length = length << 57;
long returnVal = length | longValue;
......
......@@ -22,6 +22,7 @@ package org.neo4j.internal.batchimport.cache.idmapping.string;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class LongEncoderTest
{
......@@ -38,4 +39,30 @@ class LongEncoderTest
// THEN
assertNotEquals( a, b );
}
@Test
void shouldThrowOnEncodingTooLargeID()
{
// GIVEN
Encoder encoder = new LongEncoder();
// WHEN
long invalidValue = 0x01ABC123_4567890FL;
// THEN
assertThrows( IllegalArgumentException.class, () -> encoder.encode( invalidValue ) );
}
@Test
void shouldThrowOnEncodingNegativeID()
{
// GIVEN
Encoder encoder = new LongEncoder();
// WHEN
long invalidValue = -1;
// THEN
assertThrows( IllegalArgumentException.class, () -> encoder.encode( invalidValue ) );
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment