Skip to content

Commit 167a97e

Browse files
committed
Validate long dictionary indices before narrowing
Signed-off-by: Efe Gökdemir <gokdemirefe1903@gmail.com>
1 parent 4901f98 commit 167a97e

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

‎vector/src/main/java/org/apache/arrow/vector/dictionary/DictionaryEncoder.java‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,12 @@ static void retrieveIndexVector(
164164
BaseIntVector indices, TransferPair transfer, int dictionaryCount, int start, int end) {
165165
for (int i = start; i < end; i++) {
166166
if (!indices.isNull(i)) {
167-
int indexAsInt = (int) indices.getValueAsLong(i);
168-
if (indexAsInt < 0 || indexAsInt >= dictionaryCount) {
167+
long index = indices.getValueAsLong(i);
168+
if (index < 0 || index >= dictionaryCount) {
169169
throw new IllegalArgumentException(
170-
"Provided dictionary does not contain value for index " + indexAsInt);
170+
"Provided dictionary does not contain value for index " + index);
171171
}
172-
transfer.copyValueSafe(indexAsInt, i);
172+
transfer.copyValueSafe((int) index, i);
173173
}
174174
}
175175
}

‎vector/src/test/java/org/apache/arrow/vector/TestDictionaryVector.java‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,32 @@ public void testDecodeRejectsDictionaryIndicesOutsideBounds() {
972972
assertEquals(0, allocator.getAllocatedMemory(), "decode memory leak");
973973
}
974974

975+
@Test
976+
public void testDecodeRejectsBigIntDictionaryIndexOutsideBounds() {
977+
try (final BigIntVector indices = new BigIntVector("indices", allocator);
978+
final VarCharVector dictionaryVector = newVarCharVector("dict", allocator)) {
979+
setVector(dictionaryVector, zero, one);
980+
Dictionary dictionary =
981+
new Dictionary(dictionaryVector, new DictionaryEncoding(1L, false, null));
982+
983+
setVector(indices, 1L);
984+
try (ValueVector decoded = DictionaryEncoder.decode(indices, dictionary, allocator)) {
985+
assertEquals(new Text("bar"), decoded.getObject(0));
986+
}
987+
988+
long largeIndex = 1L << 32;
989+
setVector(indices, largeIndex);
990+
IllegalArgumentException exception =
991+
assertThrows(
992+
IllegalArgumentException.class,
993+
() -> DictionaryEncoder.decode(indices, dictionary, allocator));
994+
assertEquals(
995+
"Provided dictionary does not contain value for index " + largeIndex,
996+
exception.getMessage());
997+
}
998+
assertEquals(0, allocator.getAllocatedMemory(), "decode memory leak");
999+
}
1000+
9751001
@Test
9761002
public void testListNoMemoryLeak() {
9771003
// Create a new value vector

0 commit comments

Comments
 (0)