Skip to content

Commit cfd3b5c

Browse files
committed
UuidHelper copies the array before modifying it
Previously, the assumption was that the caller owned the array and didn't care if it was modified, but that assumptions was not correct JAVA-3634
1 parent 892d0de commit cfd3b5c

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

bson/src/main/org/bson/internal/UuidHelper.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.bson.BsonSerializationException;
2222
import org.bson.UuidRepresentation;
2323

24+
import java.util.Arrays;
2425
import java.util.UUID;
2526

2627
/**
@@ -85,21 +86,28 @@ public static byte[] encodeUuidToBinary(final UUID uuid, final UuidRepresentatio
8586
return binaryData;
8687
}
8788

89+
// This method will NOT modify the contents of the byte array
8890
public static UUID decodeBinaryToUuid(final byte[] data, final byte type, final UuidRepresentation uuidRepresentation) {
8991
if (data.length != 16) {
9092
throw new BsonSerializationException(String.format("Expected length to be 16, not %d.", data.length));
9193
}
9294

95+
byte[] localData = data;
96+
9397
if (type == BsonBinarySubType.UUID_LEGACY.getValue()) {
9498
switch(uuidRepresentation) {
9599
case C_SHARP_LEGACY:
96-
reverseByteArray(data, 0, 4);
97-
reverseByteArray(data, 4, 2);
98-
reverseByteArray(data, 6, 2);
100+
localData = Arrays.copyOf(data, 16);
101+
102+
reverseByteArray(localData, 0, 4);
103+
reverseByteArray(localData, 4, 2);
104+
reverseByteArray(localData, 6, 2);
99105
break;
100106
case JAVA_LEGACY:
101-
reverseByteArray(data, 0, 8);
102-
reverseByteArray(data, 8, 8);
107+
localData = Arrays.copyOf(data, 16);
108+
109+
reverseByteArray(localData, 0, 8);
110+
reverseByteArray(localData, 8, 8);
103111
break;
104112
case PYTHON_LEGACY:
105113
break;
@@ -111,7 +119,7 @@ public static UUID decodeBinaryToUuid(final byte[] data, final byte type, final
111119
}
112120
}
113121

114-
return new UUID(readLongFromArrayBigEndian(data, 0), readLongFromArrayBigEndian(data, 8));
122+
return new UUID(readLongFromArrayBigEndian(localData, 0), readLongFromArrayBigEndian(localData, 8));
115123
}
116124

117125
private UuidHelper() {

bson/src/test/unit/org/bson/internal/UuidHelperSpecification.groovy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ class UuidHelperSpecification extends Specification {
2626
@Unroll
2727
def 'should decode different types of UUID'() {
2828
given:
29-
byte[] expectedBytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
29+
byte[] expectedBytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] as byte[]
3030

3131
expect:
3232
uuid == UuidHelper.decodeBinaryToUuid(expectedBytes, (byte) type, uuidRepresentation)
33+
expectedBytes == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] as byte[]
3334

3435
where:
3536
uuid | type | uuidRepresentation

0 commit comments

Comments
 (0)