Skip to content

Commit 6e1b83f

Browse files
committed
Fixed BinaryData.compareBytes to treat bytes as unsigned
This is a regression fix introudeced in 1.12.1 added unit test
1 parent c39d0ac commit 6e1b83f

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

lang/java/avro/src/main/java/org/apache/avro/io/BinaryData.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,10 @@ private static int compare(Decoders d, Schema schema) throws IOException {
181181

182182
/**
183183
* Lexicographically compare bytes. If equal, return zero. If greater-than,
184-
* return a positive value, if less than return a negative value.
184+
* return a positive value, if less than, return a negative value.
185185
*/
186186
public static int compareBytes(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
187-
return Arrays.compare(b1, s1, s1 + l1, b2, s2, s2 + l2);
187+
return Arrays.compareUnsigned(b1, s1, s1 + l1, b2, s2, s2 + l2);
188188
}
189189

190190
private static class HashData {

lang/java/avro/src/test/java/org/apache/avro/io/TestBinaryData.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@
1818

1919
package org.apache.avro.io;
2020

21+
import org.junit.jupiter.api.Test;
22+
2123
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
2224
import static org.junit.jupiter.api.Assertions.assertEquals;
23-
24-
import org.junit.jupiter.api.Test;
25+
import static org.junit.jupiter.api.Assertions.assertTrue;
2526

2627
public class TestBinaryData {
2728

@@ -60,4 +61,34 @@ void testIntLongVleEquality() {
6061
BinaryData.encodeLong(Integer.MIN_VALUE, longResult, 0);
6162
assertArrayEquals(intResult, longResult);
6263
}
64+
65+
@Test
66+
void testCompareBytesUnsigned() {
67+
// Test case: byte value 0xFF (-1 as signed, 255 as unsigned)
68+
// should be greater than 0x7F (127)
69+
byte[] b1 = new byte[] { (byte) 0xFF };
70+
byte[] b2 = new byte[] { (byte) 0x7F };
71+
int result = BinaryData.compareBytes(b1, 0, 1, b2, 0, 1);
72+
assertTrue(result > 0, "0xFF (255 unsigned) should be greater than 0x7F (127)");
73+
result = BinaryData.compareBytes(b2, 0, 1, b1, 0, 1);
74+
assertTrue(result < 0, "0x7F (127) should be less than 0xFF (255 unsigned)");
75+
result = BinaryData.compareBytes(b1, 0, 1, b1, 0, 1);
76+
assertEquals(0, result, "Equal byte arrays should return 0");
77+
78+
// Test with multiple bytes: {0x00, 0xFF} vs {0x00, 0x7F}
79+
byte[] b3 = new byte[] { 0x00, (byte) 0xFF };
80+
byte[] b4 = new byte[] { 0x00, (byte) 0x7F };
81+
byte[] b5 = new byte[] { (byte) 0xFF, 0x00 };
82+
byte[] b6 = new byte[] { (byte) 0x7F, 0x00 };
83+
result = BinaryData.compareBytes(b3, 0, 2, b4, 0, 2);
84+
assertTrue(result > 1, "{0x00, 0xFF} should be greater than {0x00, 0x7F}");
85+
result = BinaryData.compareBytes(b5, 0, 2, b6, 0, 2);
86+
assertTrue(result > 1, "{0xFF, 0x00} should be greater than {0x7F, 0x00}");
87+
88+
// Test with negative byte values: -1 (0xFF) should be greater than -128 (0x80)
89+
byte[] b7 = new byte[] { (byte) -1 };
90+
byte[] b8 = new byte[] { (byte) -128 };
91+
result = BinaryData.compareBytes(b7, 0, 1, b8, 0, 1);
92+
assertTrue(result > 0, "-1 (0xFF=255 unsigned) should be greater than -128 (0x80=128 unsigned)");
93+
}
6394
}

0 commit comments

Comments
 (0)