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-rs.git

commit e3bce531246d84afec334c89a3d6e1c61d57356d
Author: Kriskras99 <[email protected]>
AuthorDate: Wed Nov 12 13:48:41 2025 +0100

    fix: Make zigzag varint encoding and decoding endianness agnostic
---
 avro/src/util.rs | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/avro/src/util.rs b/avro/src/util.rs
index 1c986f4..ba319d3 100644
--- a/avro/src/util.rs
+++ b/avro/src/util.rs
@@ -78,19 +78,24 @@ pub(crate) fn read_long<R: Read>(reader: &mut R) -> 
AvroResult<i64> {
     zag_i64(reader)
 }
 
+/// Write the number as a zigzagged varint to the writer.
 pub(crate) fn zig_i32<W: Write>(n: i32, buffer: W) -> AvroResult<usize> {
     zig_i64(n as i64, buffer)
 }
 
+/// Write the number as a zigzagged varint to the writer.
 pub(crate) fn zig_i64<W: Write>(n: i64, writer: W) -> AvroResult<usize> {
-    encode_variable(((n << 1) ^ (n >> 63)) as u64, writer)
+    let zigzagged = ((n << 1) ^ (n >> 63)) as u64;
+    encode_variable(zigzagged, writer)
 }
 
+/// Decode a zigzagged varint from the reader.
 pub(crate) fn zag_i32<R: Read>(reader: &mut R) -> AvroResult<i32> {
     let i = zag_i64(reader)?;
     i32::try_from(i).map_err(|e| Details::ZagI32(e, i).into())
 }
 
+/// Decode a zigzagged varint from the reader.
 pub(crate) fn zag_i64<R: Read>(reader: &mut R) -> AvroResult<i64> {
     let z = decode_variable(reader)?;
     Ok(if z & 0x1 == 0 {
@@ -100,18 +105,24 @@ pub(crate) fn zag_i64<R: Read>(reader: &mut R) -> 
AvroResult<i64> {
     })
 }
 
-fn encode_variable<W: Write>(mut z: u64, mut writer: W) -> AvroResult<usize> {
+/// Write the number as a varint to the writer.
+///
+/// Note: this function does not do zigzag encoding, for that see [`zig_i32`] 
and [`zig_i64`].
+fn encode_variable<W: Write>(mut zigzagged: u64, mut writer: W) -> 
AvroResult<usize> {
+    // Ensure the number is little endian for the varint encoding (no-op on LE 
systems)
+    zigzagged = zigzagged.to_le();
+    // Encode the number as a varint
     let mut buffer = [0u8; 10];
     let mut i: usize = 0;
     loop {
-        if z <= 0x7F {
-            buffer[i] = (z & 0x7F) as u8;
+        if zigzagged <= 0x7F {
+            buffer[i] = (zigzagged & 0x7F) as u8;
             i += 1;
             break;
         } else {
-            buffer[i] = (0x80 | (z & 0x7F)) as u8;
+            buffer[i] = (0x80 | (zigzagged & 0x7F)) as u8;
             i += 1;
-            z >>= 7;
+            zigzagged >>= 7;
         }
     }
     writer
@@ -119,6 +130,9 @@ fn encode_variable<W: Write>(mut z: u64, mut writer: W) -> 
AvroResult<usize> {
         .map_err(|e| Details::WriteBytes(e).into())
 }
 
+/// Read a varint from the reader.
+///
+/// Note: this function does not do zigzag decoding, for that see [`zag_i32`] 
and [`zag_i64`].
 fn decode_variable<R: Read>(reader: &mut R) -> AvroResult<u64> {
     let mut i = 0u64;
     let mut buf = [0u8; 1];
@@ -140,7 +154,7 @@ fn decode_variable<R: Read>(reader: &mut R) -> 
AvroResult<u64> {
         }
     }
 
-    Ok(i)
+    Ok(u64::from_le(i))
 }
 
 /// Set the maximum number of bytes that can be allocated when decoding data.

Reply via email to