You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by mg...@apache.org on 2022/10/18 07:41:19 UTC

[avro] branch master updated: AVRO-3642: [RUST] Fix GenericSingleObjectReader::read_value for non-exhaustive reads (#1914)

This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/master by this push:
     new 6d90ec4b1 AVRO-3642: [RUST] Fix GenericSingleObjectReader::read_value for non-exhaustive reads (#1914)
6d90ec4b1 is described below

commit 6d90ec4b1c4ba47dba16650c54b4c15265016190
Author: David Peklak <dp...@gmail.com>
AuthorDate: Tue Oct 18 09:41:13 2022 +0200

    AVRO-3642: [RUST] Fix GenericSingleObjectReader::read_value for non-exhaustive reads (#1914)
    
    * AVRO-3642: Add test to reader.rs to expose bug on non-exhaustive read
    
    * AVRO-3642: Call read_exact in GenericSingleObjectReader when reading header
    
    * AVRO-3642: Correct name reader::tests::avro_3642_test_single_object_reader_incomplete_reads
    
    Co-authored-by: Martin Grigorov <ma...@users.noreply.github.com>
    
    * AVRO-3642: In test, initialize vector with two-byte marker
    
    Co-authored-by: Martin Grigorov <ma...@users.noreply.github.com>
---
 lang/rust/avro/src/reader.rs | 38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/lang/rust/avro/src/reader.rs b/lang/rust/avro/src/reader.rs
index a1dfffde9..3c8ea09b1 100644
--- a/lang/rust/avro/src/reader.rs
+++ b/lang/rust/avro/src/reader.rs
@@ -396,9 +396,9 @@ impl GenericSingleObjectReader {
 
     pub fn read_value<R: Read>(&self, reader: &mut R) -> AvroResult<Value> {
         let mut header: [u8; 10] = [0; 10];
-        match reader.read(&mut header) {
-            Ok(size) => {
-                if size == 10 && self.expected_header == header {
+        match reader.read_exact(&mut header) {
+            Ok(_) => {
+                if self.expected_header == header {
                     decode_internal(
                         self.write_schema.get_root_schema(),
                         self.write_schema.get_names(),
@@ -804,6 +804,38 @@ mod tests {
         assert_eq!(expected_value, val);
     }
 
+    #[test]
+    fn avro_3642_test_single_object_reader_incomplete_reads() {
+        let obj = TestSingleObjectReader {
+            a: 42,
+            b: 3.33,
+            c: vec!["cat".into(), "dog".into()],
+        };
+        // The two-byte marker, to show that the message uses this single-record format
+        let to_read_1 = vec![0xC3, 0x01];
+        let mut to_read_2 = Vec::<u8>::new();
+        to_read_2.extend_from_slice(
+            &TestSingleObjectReader::get_schema()
+                .fingerprint::<Rabin>()
+                .bytes[..],
+        );
+        let mut to_read_3 = Vec::<u8>::new();
+        encode(
+            &obj.clone().into(),
+            &TestSingleObjectReader::get_schema(),
+            &mut to_read_3,
+        )
+        .expect("Encode should succeed");
+        let mut to_read = (&to_read_1[..]).chain(&to_read_2[..]).chain(&to_read_3[..]);
+        let generic_reader = GenericSingleObjectReader::new(TestSingleObjectReader::get_schema())
+            .expect("Schema should resolve");
+        let val = generic_reader
+            .read_value(&mut to_read)
+            .expect("Should read");
+        let expected_value: Value = obj.into();
+        assert_eq!(expected_value, val);
+    }
+
     #[test]
     fn test_avro_3507_reader_parity() {
         let obj = TestSingleObjectReader {