This is an automated email from the ASF dual-hosted git repository.
mgrigorov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/main by this push:
new e45b60503 Fix long encoding (#3303)
e45b60503 is described below
commit e45b60503de3fd57c05aed5b70afb531ddca67b9
Author: Jonas Trevisan <[email protected]>
AuthorDate: Wed Feb 19 06:52:48 2025 -0300
Fix long encoding (#3303)
---
lang/php/lib/Datum/AvroIOBinaryDecoder.php | 2 +-
lang/php/lib/Datum/AvroIOBinaryEncoder.php | 23 ++++++++++++++-----
lang/php/test/DatumIOTest.php | 36 ++++++++++++++++++++++++++----
3 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/lang/php/lib/Datum/AvroIOBinaryDecoder.php
b/lang/php/lib/Datum/AvroIOBinaryDecoder.php
index 870f56bd4..31a007f0a 100644
--- a/lang/php/lib/Datum/AvroIOBinaryDecoder.php
+++ b/lang/php/lib/Datum/AvroIOBinaryDecoder.php
@@ -124,7 +124,7 @@ class AvroIOBinaryDecoder
$n |= (($b & 0x7f) << $shift);
$shift += 7;
}
- return (($n >> 1) ^ -($n & 1));
+ return ($n >> 1) ^ (($n >> 63) << 63) ^ -($n & 1);
}
/**
diff --git a/lang/php/lib/Datum/AvroIOBinaryEncoder.php
b/lang/php/lib/Datum/AvroIOBinaryEncoder.php
index 0a42b7480..d4c47248c 100644
--- a/lang/php/lib/Datum/AvroIOBinaryEncoder.php
+++ b/lang/php/lib/Datum/AvroIOBinaryEncoder.php
@@ -101,13 +101,24 @@ class AvroIOBinaryEncoder
{
$n = (int) $n;
$n = ($n << 1) ^ ($n >> 63);
- $str = '';
- while (0 != ($n & ~0x7F)) {
- $str .= chr(($n & 0x7F) | 0x80);
- $n >>= 7;
+
+ if ($n >= 0 && $n < 0x80) {
+ return chr($n);
}
- $str .= chr($n);
- return $str;
+
+ $buf = [];
+ if (($n & ~0x7F) != 0) {
+ $buf[] = ($n | 0x80) & 0xFF;
+ $n = ($n >> 7) ^ (($n >> 63) << 57); // unsigned shift right ($n
>>> 7)
+
+ while ($n > 0x7F) {
+ $buf[] = ($n | 0x80) & 0xFF;
+ $n >>= 7; // $n is always positive here
+ }
+ }
+
+ $buf[] = $n;
+ return pack("C*", ...$buf);
}
/**
diff --git a/lang/php/test/DatumIOTest.php b/lang/php/test/DatumIOTest.php
index f8db66989..b2b879c1c 100644
--- a/lang/php/test/DatumIOTest.php
+++ b/lang/php/test/DatumIOTest.php
@@ -28,6 +28,12 @@ use Apache\Avro\IO\AvroStringIO;
use Apache\Avro\Schema\AvroSchema;
use PHPUnit\Framework\TestCase;
+/**
+ * @covers AvroIOBinaryDecoder
+ * @covers AvroIOBinaryEncoder
+ * @covers AvroIODatumReader
+ * @covers AvroIODatumWriter
+ */
class DatumIOTest extends TestCase
{
/**
@@ -68,11 +74,33 @@ class DatumIOTest extends TestCase
array('"int"', 1, "\002"),
array('"int"', 2147483647, "\xFE\xFF\xFF\xFF\x0F"),
- // array('"long"', (int) -9223372036854775808, "\001"),
+ array('"long"', (int) -9223372036854775808,
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"),
+ array('"long"', -(1<<62), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F"),
+ array('"long"', -(1<<61), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x3F"),
+ array('"long"', -4294967295, "\xFD\xFF\xFF\xFF\x1F"),
+ array('"long"', -1<<24, "\xFF\xFF\xFF\x0F"),
+ array('"long"', -1<<16, "\xFF\xFF\x07"),
+ array('"long"', -255, "\xFD\x03"),
+ array('"long"', -128, "\xFF\x01"),
+ array('"long"', -127, "\xFD\x01"),
+ array('"long"', -10, "\x13"),
+ array('"long"', -3, "\005"),
+ array('"long"', -2, "\003"),
array('"long"', -1, "\001"),
- array('"long"', 0, "\000"),
- array('"long"', 1, "\002"),
- // array('"long"', 9223372036854775807, "\002")
+ array('"long"', 0, "\000"),
+ array('"long"', 1, "\002"),
+ array('"long"', 2, "\004"),
+ array('"long"', 3, "\006"),
+ array('"long"', 10, "\x14"),
+ array('"long"', 127, "\xFE\x01"),
+ array('"long"', 128, "\x80\x02"),
+ array('"long"', 255, "\xFE\x03"),
+ array('"long"', 1<<16, "\x80\x80\x08"),
+ array('"long"', 1<<24, "\x80\x80\x80\x10"),
+ array('"long"', 4294967295, "\xFE\xFF\xFF\xFF\x1F"),
+ array('"long"', 1<<61, "\x80\x80\x80\x80\x80\x80\x80\x80\x40"),
+ array('"long"', 1<<62, "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01"),
+ array('"long"', 9223372036854775807,
"\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"),
array('"float"', (float) -10.0, "\000\000 \301"),
array('"float"', (float) -1.0, "\000\000\200\277"),