From 7a4f1f2fb1ff2fcaf45373647a53d69e6ce10c8b Mon Sep 17 00:00:00 2001 From: Chili Palmer Date: Sun, 9 Aug 2026 00:29:07 +0000 Subject: [PATCH] Implement bounded Binary LLSD codec --- README.md | 7 +- api/SHIM-COVERAGE.md | 2 +- .../src/binary.rs | 681 ++++++++++++++++++ .../src/dispatch.rs | 8 +- .../src/generated.rs | 52 +- .../libremetaverse-structured-data/src/lib.rs | 1 + .../src/model.rs | 6 +- crates/libremetaverse-types/src/compat.rs | 4 +- crates/libremetaverse-types/src/shim.rs | 11 + fuzz/corpus/binary_llsd/README.md | 11 + fuzz/corpus/binary_llsd/malformed.hex | 15 + tests/PARITY.md | 156 ++-- tests/compat/tests/structured_data.rs | 8 +- tests/red-suite-baseline.json | 28 +- tests/upstream-tests.json | 156 ++-- tools/generate_api_shims.py | 26 + tools/generate_rust_mapping.py | 1 + 17 files changed, 965 insertions(+), 208 deletions(-) create mode 100644 crates/libremetaverse-structured-data/src/binary.rs create mode 100644 fuzz/corpus/binary_llsd/README.md create mode 100644 fuzz/corpus/binary_llsd/malformed.hex diff --git a/README.md b/README.md index dfbef64..1064a38 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,11 @@ integer/date byte order, synchronized snapshot-based arrays and maps, and bounded parser dispatch. OSD map order is intentionally unspecified at the public model boundary; encoders must choose and document any stable ordering they require. Untrusted dispatch limits input bytes, nesting depth, decoded -nodes, and aggregate binary allocation before returning a value. +nodes, and aggregate binary allocation before returning a value. The native +Binary LLSD codec covers every reference marker, both accepted headers, exact +numeric and date byte order, seekable stream overloads, and position-bearing +errors for malformed or truncated input. Its parser and encoder enforce the +same byte, depth, node, and allocation bounds; map keys are encoded in sorted +order to make output stable despite the model's intentionally unordered maps. The controlled audit aggregates every expected failure by standardized C# member ID and rejects unrelated fixture, assertion, compile, or symbol errors. diff --git a/api/SHIM-COVERAGE.md b/api/SHIM-COVERAGE.md index e9888b2..826d970 100644 --- a/api/SHIM-COVERAGE.md +++ b/api/SHIM-COVERAGE.md @@ -12,7 +12,7 @@ Generated by `python3 tools/generate_api_shims.py`; do not edit by hand. | `LibreMetaverse.RLV` | 28 | 499 | callable failure-only shim | | `LibreMetaverse.Rendering.MeshFoundry` | 1 | 14 | callable failure-only shim | | `LibreMetaverse.Rendering.Simple` | 1 | 6 | callable failure-only shim | -| `LibreMetaverse.StructuredData` | 16 | 295 | native implementation: 15 types / 255 members; remaining surface is callable failure-only shims | +| `LibreMetaverse.StructuredData` | 16 | 295 | native implementation: 15 types / 268 members; remaining surface is callable failure-only shims | | `LibreMetaverse.Types` | 45 | 942 | native implementation: 45 types / 942 members; no generated shims remain | | `LibreMetaverse.Utilities` | 3 | 13 | callable failure-only shim | | `LibreMetaverse.Voice.Vivox` | 64 | 531 | callable failure-only shim | diff --git a/crates/libremetaverse-structured-data/src/binary.rs b/crates/libremetaverse-structured-data/src/binary.rs new file mode 100644 index 0000000..afe57f5 --- /dev/null +++ b/crates/libremetaverse-structured-data/src/binary.rs @@ -0,0 +1,681 @@ +//! Bounded Binary LLSD codec compatible with `LibreMetaverse`'s marker grammar. + +#![allow(clippy::missing_errors_doc)] // Public Result shapes are fixed by the mapped API. +#![allow(clippy::needless_pass_by_value)] // Owned arguments mirror mapped C# value parameters. +#![allow(clippy::unnecessary_wraps)] // Result return shapes are fixed by the mapped API. +#![allow(clippy::unused_self)] // Parser error helpers retain local cursor context call sites. + +use crate::{Error, OSD}; +use libremetaverse_types::UUID; +use libremetaverse_types::compat::{ReadWrite, Uri}; +use std::collections::HashMap; +use std::io::{Cursor, Read as _, Seek as _, SeekFrom}; +use std::time::{Duration, UNIX_EPOCH}; + +const HEADER: &[u8] = b""; +const ALT_HEADER: &[u8] = b""; +const MAX_INPUT_BYTES: usize = OSD::DEFAULT_MAX_BINARY_BYTES; + +const fn is_binary_whitespace(byte: u8) -> bool { + matches!(byte, b' ' | b'\t' | b'\n' | b'\r') +} + +pub(crate) fn deserialize_bytes(data: Vec) -> Result { + if data.len() > MAX_INPUT_BYTES { + return Err(parse_error(0, "binary LLSD input exceeds allocation limit")); + } + let mut parser = Parser::new(&data); + parser.skip_whitespace(); + if parser.consume_prefix_ignore_ascii_case(ALT_HEADER) + || parser.consume_prefix_ignore_ascii_case(HEADER) + { + parser.skip_whitespace(); + } + let value = parser.parse_value(0)?; + value.validate_limits( + OSD::DEFAULT_MAX_DEPTH, + OSD::DEFAULT_MAX_NODES, + OSD::DEFAULT_MAX_BINARY_BYTES, + )?; + Ok(value) +} + +pub(crate) fn deserialize_stream(mut stream: Box) -> Result { + let mut data = Vec::new(); + (&mut *stream) + .take((MAX_INPUT_BYTES + 1) as u64) + .read_to_end(&mut data) + .map_err(|_| Error::InvalidOperation)?; + deserialize_bytes(data) +} + +pub(crate) fn serialize(value: OSD) -> Result, Error> { + serialize_with_header(value, true) +} + +pub(crate) fn serialize_with_header(value: OSD, prepend_header: bool) -> Result, Error> { + value.validate_limits( + OSD::DEFAULT_MAX_DEPTH, + OSD::DEFAULT_MAX_NODES, + OSD::DEFAULT_MAX_BINARY_BYTES, + )?; + let mut encoder = Encoder::new(); + if prepend_header { + encoder.extend(HEADER)?; + encoder.push(b'\n')?; + } + encoder.write_value(&value, 0)?; + Ok(encoder.finish()) +} + +pub(crate) fn serialize_stream(value: OSD) -> Result>, Error> { + serialize_stream_with_header(value, true) +} + +pub(crate) fn serialize_stream_with_header( + value: OSD, + prepend_header: bool, +) -> Result>, Error> { + let bytes = serialize_with_header(value, prepend_header)?; + let position = bytes.len() as u64; + let mut cursor = Cursor::new(bytes); + cursor.set_position(position); + Ok(cursor) +} + +pub(crate) fn consume_bytes( + mut stream: Box, + consume_bytes: i32, +) -> Result, Error> { + let length = usize::try_from(consume_bytes).map_err(|_| Error::Argument)?; + if length > MAX_INPUT_BYTES { + return Err(Error::Argument); + } + let mut bytes = vec![0_u8; length]; + stream + .read_exact(&mut bytes) + .map_err(|_| Error::IndexOutOfRange)?; + Ok(bytes) +} + +pub(crate) fn find_byte(mut stream: Box, to_find: u8) -> Result { + let start = stream + .stream_position() + .map_err(|_| Error::InvalidOperation)?; + let mut byte = [0_u8; 1]; + if stream + .read(&mut byte) + .map_err(|_| Error::InvalidOperation)? + == 0 + { + return Ok(false); + } + if byte[0] == to_find { + Ok(true) + } else { + stream + .seek(SeekFrom::Start(start)) + .map_err(|_| Error::InvalidOperation)?; + Ok(false) + } +} + +pub(crate) fn find_string( + mut stream: Box, + to_find: String, +) -> Result { + let start = stream + .stream_position() + .map_err(|_| Error::InvalidOperation)?; + let expected = to_find.as_bytes(); + if expected.len() > MAX_INPUT_BYTES { + return Err(Error::Argument); + } + let mut actual = vec![0_u8; expected.len()]; + let matched = stream.read_exact(&mut actual).is_ok() + && actual + .iter() + .zip(expected) + .all(|(left, right)| left.eq_ignore_ascii_case(right)); + if !matched { + stream + .seek(SeekFrom::Start(start)) + .map_err(|_| Error::InvalidOperation)?; + } + Ok(matched) +} + +pub(crate) fn skip_whitespace(mut stream: Box) -> Result<(), Error> { + loop { + let start = stream + .stream_position() + .map_err(|_| Error::InvalidOperation)?; + let mut byte = [0_u8; 1]; + if stream + .read(&mut byte) + .map_err(|_| Error::InvalidOperation)? + == 0 + { + return Ok(()); + } + if !is_binary_whitespace(byte[0]) { + stream + .seek(SeekFrom::Start(start)) + .map_err(|_| Error::InvalidOperation)?; + return Ok(()); + } + } +} + +pub(crate) fn host_to_network_int_bytes(value: i32) -> Result, Error> { + Ok(value.to_be_bytes().to_vec()) +} + +pub(crate) fn network_to_host_int(bytes: Vec) -> Result { + let bytes: [u8; 4] = bytes + .get(..4) + .ok_or(Error::IndexOutOfRange)? + .try_into() + .map_err(|_| Error::IndexOutOfRange)?; + Ok(i32::from_be_bytes(bytes)) +} + +pub(crate) fn network_to_host_double(bytes: Vec) -> Result { + let bytes: [u8; 8] = bytes + .get(..8) + .ok_or(Error::IndexOutOfRange)? + .try_into() + .map_err(|_| Error::IndexOutOfRange)?; + Ok(f64::from_be_bytes(bytes)) +} + +struct Parser<'a> { + bytes: &'a [u8], + position: usize, + nodes: usize, + allocated: usize, +} + +impl<'a> Parser<'a> { + const fn new(bytes: &'a [u8]) -> Self { + Self { + bytes, + position: 0, + nodes: 0, + allocated: 0, + } + } + + fn parse_value(&mut self, depth: usize) -> Result { + if depth > OSD::DEFAULT_MAX_DEPTH { + return Err(self.error("binary LLSD nesting depth exceeded")); + } + self.nodes = self + .nodes + .checked_add(1) + .ok_or_else(|| self.error("binary LLSD node count overflow"))?; + if self.nodes > OSD::DEFAULT_MAX_NODES { + return Err(self.error("binary LLSD node limit exceeded")); + } + self.skip_whitespace(); + let marker_position = self.position; + let marker = self.read_byte("missing binary LLSD value marker")?; + match marker { + b'!' => Ok(OSD::Undefined), + b'1' => Ok(OSD::Boolean(true)), + b'0' => Ok(OSD::Boolean(false)), + b'i' => Ok(OSD::Integer(i32::from_be_bytes( + self.read_array("truncated binary LLSD integer")?, + ))), + b'r' => Ok(OSD::Real(f64::from_be_bytes( + self.read_array("truncated binary LLSD real")?, + ))), + b'u' => { + let bytes = self.read_exact(16, "truncated binary LLSD UUID")?; + Ok(OSD::UUID(UUID::new_with_bytes_int32(bytes.to_vec(), 0)?)) + } + b'b' => { + let length = self.read_length("invalid binary LLSD binary length")?; + self.add_allocation(length, "binary LLSD binary allocation limit exceeded")?; + Ok(OSD::Binary( + self.read_exact(length, "truncated binary LLSD binary value")? + .to_vec(), + )) + } + b's' => { + let bytes = self.read_sized_text("string")?; + Ok(OSD::String(String::from_utf8_lossy(bytes).into_owned())) + } + b'l' => { + let bytes = self.read_sized_text("URI")?; + let text = String::from_utf8_lossy(bytes).into_owned(); + let uri = OSD::String(text.clone()) + .as_uri()? + .ok_or_else(|| self.error_at(marker_position, "invalid binary LLSD URI"))?; + Ok(OSD::Uri(uri)) + } + b'd' => { + let timestamp = f64::from_le_bytes(self.read_array("truncated binary LLSD date")?); + Ok(OSD::Date(system_time_from_seconds(timestamp).ok_or_else( + || self.error_at(marker_position, "invalid binary LLSD date"), + )?)) + } + b'[' => self.parse_array(depth), + b'{' => self.parse_map(depth), + _ => Err(self.error_at(marker_position, "unknown binary LLSD type marker")), + } + } + + fn parse_array(&mut self, depth: usize) -> Result { + let count = self.read_length("invalid binary LLSD array count")?; + if count > OSD::DEFAULT_MAX_NODES || count > self.remaining() { + return Err(self.error("binary LLSD array count exceeds available input")); + } + let allocation = count + .checked_mul(std::mem::size_of::()) + .ok_or_else(|| self.error("binary LLSD array allocation overflow"))?; + self.add_allocation(allocation, "binary LLSD array allocation limit exceeded")?; + let mut values = Vec::with_capacity(count); + for _ in 0..count { + values.push(self.parse_value(depth + 1)?); + } + self.expect_byte(b']', "missing binary LLSD array end marker")?; + Ok(OSD::Array(values)) + } + + fn parse_map(&mut self, depth: usize) -> Result { + let count = self.read_length("invalid binary LLSD map count")?; + if count > OSD::DEFAULT_MAX_NODES || count > self.remaining() { + return Err(self.error("binary LLSD map count exceeds available input")); + } + let allocation = count + .checked_mul(std::mem::size_of::<(String, OSD)>()) + .ok_or_else(|| self.error("binary LLSD map allocation overflow"))?; + self.add_allocation(allocation, "binary LLSD map allocation limit exceeded")?; + let mut values = HashMap::with_capacity(count); + for _ in 0..count { + self.expect_byte(b'k', "missing binary LLSD map key marker")?; + let key_bytes = self.read_sized_text("map key")?; + let key = String::from_utf8_lossy(key_bytes).into_owned(); + let value = self.parse_value(depth + 1)?; + values.insert(key, value); + } + self.expect_byte(b'}', "missing binary LLSD map end marker")?; + Ok(OSD::Map(values)) + } + + fn read_sized_text(&mut self, context: &'static str) -> Result<&'a [u8], Error> { + let length = self.read_length(match context { + "string" => "invalid binary LLSD string length", + "URI" => "invalid binary LLSD URI length", + _ => "invalid binary LLSD map key length", + })?; + self.add_allocation(length, "binary LLSD text allocation limit exceeded")?; + self.read_exact( + length, + match context { + "string" => "truncated binary LLSD string", + "URI" => "truncated binary LLSD URI", + _ => "truncated binary LLSD map key", + }, + ) + } + + fn read_length(&mut self, context: &'static str) -> Result { + let position = self.position; + let raw = i32::from_be_bytes(self.read_array(context)?); + usize::try_from(raw).map_err(|_| self.error_at(position, context)) + } + + fn read_array(&mut self, context: &'static str) -> Result<[u8; N], Error> { + self.read_exact(N, context)? + .try_into() + .map_err(|_| self.error(context)) + } + + fn read_exact(&mut self, length: usize, context: &'static str) -> Result<&'a [u8], Error> { + let end = self + .position + .checked_add(length) + .ok_or_else(|| self.error(context))?; + let value = self + .bytes + .get(self.position..end) + .ok_or_else(|| self.error(context))?; + self.position = end; + Ok(value) + } + + fn read_byte(&mut self, context: &'static str) -> Result { + let byte = *self + .bytes + .get(self.position) + .ok_or_else(|| self.error(context))?; + self.position += 1; + Ok(byte) + } + + fn expect_byte(&mut self, expected: u8, context: &'static str) -> Result<(), Error> { + let position = self.position; + if self.read_byte(context)? == expected { + Ok(()) + } else { + Err(self.error_at(position, context)) + } + } + + fn add_allocation(&mut self, amount: usize, context: &'static str) -> Result<(), Error> { + self.allocated = self + .allocated + .checked_add(amount) + .ok_or_else(|| self.error(context))?; + if self.allocated > OSD::DEFAULT_MAX_BINARY_BYTES { + Err(self.error(context)) + } else { + Ok(()) + } + } + + fn skip_whitespace(&mut self) { + while self + .bytes + .get(self.position) + .is_some_and(|byte| is_binary_whitespace(*byte)) + { + self.position += 1; + } + } + + fn consume_prefix_ignore_ascii_case(&mut self, prefix: &[u8]) -> bool { + let Some(candidate) = self.bytes.get(self.position..self.position + prefix.len()) else { + return false; + }; + if candidate.eq_ignore_ascii_case(prefix) { + self.position += prefix.len(); + true + } else { + false + } + } + + const fn remaining(&self) -> usize { + self.bytes.len() - self.position + } + + const fn error(&self, context: &'static str) -> Error { + self.error_at(self.position, context) + } + + const fn error_at(&self, position: usize, context: &'static str) -> Error { + parse_error(position, context) + } +} + +struct Encoder { + bytes: Vec, +} + +impl Encoder { + fn new() -> Self { + Self { + bytes: Vec::with_capacity(128), + } + } + + fn finish(self) -> Vec { + self.bytes + } + + fn write_value(&mut self, value: &OSD, depth: usize) -> Result<(), Error> { + if depth > OSD::DEFAULT_MAX_DEPTH { + return Err(parse_error( + self.bytes.len(), + "binary LLSD nesting depth exceeded", + )); + } + match value { + OSD::Undefined => self.push(b'!'), + OSD::Boolean(value) => self.push(if *value { b'1' } else { b'0' }), + OSD::Integer(value) => { + self.push(b'i')?; + self.extend(&value.to_be_bytes()) + } + OSD::Real(value) => { + self.push(b'r')?; + self.extend(&value.to_be_bytes()) + } + OSD::UUID(value) => { + self.push(b'u')?; + self.extend(&value.get_bytes()?) + } + OSD::String(value) => { + self.push(b's')?; + self.write_sized(value.as_bytes()) + } + OSD::Binary(value) => { + self.push(b'b')?; + self.write_sized(value) + } + OSD::Date(value) => { + self.push(b'd')?; + self.extend(&crate::model::unix_seconds_for_codec(*value).to_le_bytes()) + } + OSD::Uri(Uri(value)) => { + self.push(b'l')?; + self.write_sized(value.as_bytes()) + } + OSD::Array(values) => { + self.push(b'[')?; + self.write_length(values.len())?; + for value in values { + self.write_value(value, depth + 1)?; + } + self.push(b']') + } + OSD::Map(values) => { + self.push(b'{')?; + self.write_length(values.len())?; + let mut entries: Vec<_> = values.iter().collect(); + entries.sort_unstable_by_key(|(key, _)| *key); + for (key, value) in entries { + self.push(b'k')?; + self.write_sized(key.as_bytes())?; + self.write_value(value, depth + 1)?; + } + self.push(b'}') + } + OSD::LlsdXml(_) => Err(parse_error( + self.bytes.len(), + "LLSD XML fragments have no Binary LLSD marker", + )), + } + } + + fn write_sized(&mut self, value: &[u8]) -> Result<(), Error> { + self.write_length(value.len())?; + self.extend(value) + } + + fn write_length(&mut self, length: usize) -> Result<(), Error> { + let length = i32::try_from(length).map_err(|_| Error::Argument)?; + self.extend(&length.to_be_bytes()) + } + + fn push(&mut self, value: u8) -> Result<(), Error> { + if self.bytes.len() >= MAX_INPUT_BYTES { + return Err(Error::Argument); + } + self.bytes.push(value); + Ok(()) + } + + fn extend(&mut self, value: &[u8]) -> Result<(), Error> { + let length = self + .bytes + .len() + .checked_add(value.len()) + .ok_or(Error::Argument)?; + if length > MAX_INPUT_BYTES { + return Err(Error::Argument); + } + self.bytes.extend_from_slice(value); + Ok(()) + } +} + +fn system_time_from_seconds(seconds: f64) -> Option { + if !seconds.is_finite() { + return None; + } + if seconds >= 0.0 { + UNIX_EPOCH.checked_add(Duration::try_from_secs_f64(seconds).ok()?) + } else { + UNIX_EPOCH.checked_sub(Duration::try_from_secs_f64(-seconds).ok()?) + } +} + +const fn parse_error(position: usize, context: &'static str) -> Error { + Error::Parse { position, context } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn every_variant_round_trips_with_header_and_nested_values() { + let uuid = UUID::new_with_string("97f4aeca-88a1-42a1-b385-b97b18abb255".into()).unwrap(); + let value = OSD::Array(vec![ + OSD::Undefined, + OSD::Boolean(true), + OSD::Integer(-42), + OSD::Real(12.5), + OSD::String("text 𐄷".into()), + OSD::UUID(uuid), + OSD::Date(UNIX_EPOCH + Duration::from_millis(1_199_218_231_125)), + OSD::Uri(Uri("https://example.test/a".into())), + OSD::Binary(vec![0, 1, 255]), + OSD::Map(HashMap::from([("nested".into(), OSD::Array(vec![]))])), + ]); + let encoded = serialize(value.clone()).unwrap(); + assert!(encoded.starts_with(b"\n")); + assert_eq!(deserialize_bytes(encoded).unwrap(), value); + assert_eq!( + deserialize_bytes(b" \t\r\n\r\ni\0\0\0\x07".to_vec()).unwrap(), + OSD::Integer(7) + ); + assert!(matches!( + deserialize_bytes(b"\x0b!".to_vec()), + Err(Error::Parse { + position: 0, + context: "unknown binary LLSD type marker" + }) + )); + + let mut encoded_stream = serialize_stream_with_header(value.clone(), false).unwrap(); + assert_eq!( + encoded_stream.position(), + encoded_stream.get_ref().len() as u64 + ); + encoded_stream.set_position(0); + assert_eq!(deserialize_stream(Box::new(encoded_stream)).unwrap(), value); + + assert_eq!( + host_to_network_int_bytes(-42).unwrap(), + (-42_i32).to_be_bytes() + ); + assert_eq!( + network_to_host_int((-42_i32).to_be_bytes().to_vec()).unwrap(), + -42 + ); + assert_eq!( + network_to_host_double(12.5_f64.to_be_bytes().to_vec()) + .unwrap() + .to_bits(), + 12.5_f64.to_bits() + ); + } + + #[test] + fn malformed_seed_corpus_is_rejected_with_positions() { + let expected: &[(&str, &str)] = &[ + ("empty", "missing binary LLSD value marker"), + ("unknown_marker", "unknown binary LLSD type marker"), + ("truncated_integer", "truncated binary LLSD integer"), + ("truncated_real", "truncated binary LLSD real"), + ("truncated_uuid", "truncated binary LLSD UUID"), + ( + "negative_binary_length", + "invalid binary LLSD binary length", + ), + ( + "truncated_binary_length", + "invalid binary LLSD binary length", + ), + ( + "negative_string_length", + "invalid binary LLSD string length", + ), + ("negative_array_count", "invalid binary LLSD array count"), + ("negative_map_count", "invalid binary LLSD map count"), + ( + "oversized_string_length", + "binary LLSD text allocation limit exceeded", + ), + ("missing_array_end", "missing binary LLSD array end marker"), + ( + "missing_map_key_marker", + "missing binary LLSD map key marker", + ), + ("missing_map_end", "missing binary LLSD map end marker"), + ("non_finite_date", "invalid binary LLSD date"), + ]; + let corpus = include_str!("../../../fuzz/corpus/binary_llsd/malformed.hex"); + let seeds: HashMap<_, _> = corpus + .lines() + .map(|line| { + let (name, hex) = line.split_once(':').expect("named fuzz seed"); + (name, decode_hex(hex)) + }) + .collect(); + assert_eq!(seeds.len(), expected.len()); + for (name, expected_context) in expected { + let seed = seeds.get(name).expect("fuzz seed named by test"); + let Error::Parse { position, context } = deserialize_bytes(seed.clone()).unwrap_err() + else { + panic!("malformed seed did not return a positional parse error"); + }; + assert!(position <= seed.len()); + assert_eq!(context, *expected_context); + } + } + + fn decode_hex(value: &str) -> Vec { + assert_eq!(value.len() % 2, 0, "fuzz seed hex must contain byte pairs"); + value + .as_bytes() + .chunks_exact(2) + .map(|pair| { + let text = std::str::from_utf8(pair).expect("ASCII fuzz seed hex"); + u8::from_str_radix(text, 16).expect("valid fuzz seed hex") + }) + .collect() + } + + #[test] + fn excessive_depth_is_rejected_before_stack_growth() { + let mut bytes = Vec::new(); + for _ in 0..=OSD::DEFAULT_MAX_DEPTH { + bytes.extend_from_slice(b"[\0\0\0\x01"); + } + bytes.push(b'!'); + bytes.extend(std::iter::repeat_n(b']', OSD::DEFAULT_MAX_DEPTH + 1)); + assert!(matches!( + deserialize_bytes(bytes), + Err(Error::Parse { + context: "binary LLSD nesting depth exceeded", + .. + }) + )); + } +} diff --git a/crates/libremetaverse-structured-data/src/dispatch.rs b/crates/libremetaverse-structured-data/src/dispatch.rs index 6a8b0b2..33f046b 100644 --- a/crates/libremetaverse-structured-data/src/dispatch.rs +++ b/crates/libremetaverse-structured-data/src/dispatch.rs @@ -156,11 +156,11 @@ mod tests { deserialize_bytes(b"Unknown conference".to_vec()), Err(Error::Argument) ); + assert_eq!( + deserialize_bytes(b"i\0\0\0\0".to_vec()), + Ok(OSD::Integer(0)) + ); let cases: &[(&[u8], &str)] = &[ - ( - b"i\0\0\0\0", - "M:LibreMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.Byte[])", - ), ( b"", "M:LibreMetaverse.StructuredData.OSDParser.DeserializeLLSDProtobuf(System.Byte[])", diff --git a/crates/libremetaverse-structured-data/src/generated.rs b/crates/libremetaverse-structured-data/src/generated.rs index 1d52255..9632bba 100644 --- a/crates/libremetaverse-structured-data/src/generated.rs +++ b/crates/libremetaverse-structured-data/src/generated.rs @@ -251,9 +251,7 @@ impl OSDParser { stream: Box, consume_bytes: i32, ) -> Result, crate::Error> { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.ConsumeBytes(System.IO.Stream,System.Int32)", - ) + crate::binary::consume_bytes(stream, consume_bytes) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.Deserialize(System.Byte[])`. pub fn deserialize_with_bytes( @@ -293,17 +291,13 @@ impl OSDParser { pub fn deserialize_llsd_binary_with_bytes( binary_data: Vec, ) -> Result { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.Byte[])", - ) + crate::binary::deserialize_bytes(binary_data) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.IO.Stream)`. pub fn deserialize_llsd_binary_with_stream( stream: Box, ) -> Result { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.IO.Stream)", - ) + crate::binary::deserialize_stream(stream) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.DeserializeLLSDNotation(System.IO.StringReader)`. pub fn deserialize_llsd_notation_with_string_reader( @@ -383,18 +377,14 @@ impl OSDParser { stream: Box, to_find: u8, ) -> Result { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.FindByte(System.IO.Stream,System.Byte)", - ) + crate::binary::find_byte(stream, to_find) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.FindString(System.IO.Stream,System.String)`. pub fn find_string( stream: Box, to_find: String, ) -> Result { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.FindString(System.IO.Stream,System.String)", - ) + crate::binary::find_string(stream, to_find) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.GetLengthInBrackets(System.IO.StringReader)`. pub fn get_length_in_brackets( @@ -415,21 +405,15 @@ impl OSDParser { } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.HostToNetworkIntBytes(System.Int32)`. pub fn host_to_network_int_bytes(int_host_end: i32) -> Result, crate::Error> { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.HostToNetworkIntBytes(System.Int32)", - ) + crate::binary::host_to_network_int_bytes(int_host_end) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.NetworkToHostDouble(System.Byte[])`. pub fn network_to_host_double(binary_net_end: Vec) -> Result { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.NetworkToHostDouble(System.Byte[])", - ) + crate::binary::network_to_host_double(binary_net_end) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.NetworkToHostInt(System.Byte[])`. pub fn network_to_host_int(binary_net_end: Vec) -> Result { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.NetworkToHostInt(System.Byte[])", - ) + crate::binary::network_to_host_int(binary_net_end) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.PeekAndSkipWhitespace(System.IO.StringReader)`. pub fn peek_and_skip_whitespace( @@ -460,35 +444,27 @@ impl OSDParser { pub fn serialize_llsd_binary_with_osd( osd: libremetaverse_structured_data::OSD, ) -> Result, crate::Error> { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinary(LibreMetaverse.StructuredData.OSD)", - ) + crate::binary::serialize(osd) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinary(LibreMetaverse.StructuredData.OSD,System.Boolean)`. pub fn serialize_llsd_binary_with_osd_boolean( osd: libremetaverse_structured_data::OSD, prepend_header: bool, ) -> Result, crate::Error> { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinary(LibreMetaverse.StructuredData.OSD,System.Boolean)", - ) + crate::binary::serialize_with_header(osd, prepend_header) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinaryStream(LibreMetaverse.StructuredData.OSD)`. pub fn serialize_llsd_binary_stream_with_osd( data: libremetaverse_structured_data::OSD, ) -> Result>, crate::Error> { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinaryStream(LibreMetaverse.StructuredData.OSD)", - ) + crate::binary::serialize_stream(data) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinaryStream(LibreMetaverse.StructuredData.OSD,System.Boolean)`. pub fn serialize_llsd_binary_stream_with_osd_boolean( data: libremetaverse_structured_data::OSD, prepend_header: bool, ) -> Result>, crate::Error> { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinaryStream(LibreMetaverse.StructuredData.OSD,System.Boolean)", - ) + crate::binary::serialize_stream_with_header(data, prepend_header) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDInnerXmlString(LibreMetaverse.StructuredData.OSD)`. pub fn serialize_llsd_inner_xml_string( @@ -568,9 +544,7 @@ impl OSDParser { pub fn skip_white_space( stream: Box, ) -> Result<(), crate::Error> { - libremetaverse_types::not_implemented( - "M:LibreMetaverse.StructuredData.OSDParser.SkipWhiteSpace(System.IO.Stream)", - ) + crate::binary::skip_whitespace(stream) } /// C# member: `M:LibreMetaverse.StructuredData.OSDParser.UnescapeCharacter(System.String,System.Char)`. pub fn unescape_character( diff --git a/crates/libremetaverse-structured-data/src/lib.rs b/crates/libremetaverse-structured-data/src/lib.rs index 2a975f2..8a35102 100644 --- a/crates/libremetaverse-structured-data/src/lib.rs +++ b/crates/libremetaverse-structured-data/src/lib.rs @@ -2,6 +2,7 @@ extern crate self as libremetaverse_structured_data; +mod binary; mod dispatch; mod generated; mod model; diff --git a/crates/libremetaverse-structured-data/src/model.rs b/crates/libremetaverse-structured-data/src/model.rs index bbb8cae..c7e4435 100644 --- a/crates/libremetaverse-structured-data/src/model.rs +++ b/crates/libremetaverse-structured-data/src/model.rs @@ -188,7 +188,7 @@ impl OSD { Self::Real(value) => value.to_be_bytes().to_vec(), Self::String(value) | Self::LlsdXml(value) => value.as_bytes().to_vec(), Self::UUID(value) => value.get_bytes()?, - Self::Date(value) => unix_seconds_f64(*value).to_le_bytes().to_vec(), + Self::Date(value) => unix_seconds_for_codec(*value).to_le_bytes().to_vec(), Self::Uri(value) => value.0.as_bytes().to_vec(), Self::Binary(value) => value.clone(), Self::Array(values) => values @@ -842,7 +842,7 @@ impl OSDUUID { scalar_wrapper!(OSDDate, SystemTime, Date, Date); impl OSDDate { pub fn as_binary(&self) -> Result, Error> { - Ok(unix_seconds_f64(self.value).to_le_bytes().to_vec()) + Ok(unix_seconds_for_codec(self.value).to_le_bytes().to_vec()) } pub const fn as_date(&self) -> Result { Ok(self.value) @@ -1425,7 +1425,7 @@ fn format_real(value: f64) -> String { value.to_string() } } -fn unix_seconds_f64(value: SystemTime) -> f64 { +pub(crate) fn unix_seconds_for_codec(value: SystemTime) -> f64 { match value.duration_since(UNIX_EPOCH) { Ok(duration) => duration.as_secs_f64(), Err(error) => -error.duration().as_secs_f64(), diff --git a/crates/libremetaverse-types/src/compat.rs b/crates/libremetaverse-types/src/compat.rs index a348c83..3f21477 100644 --- a/crates/libremetaverse-types/src/compat.rs +++ b/crates/libremetaverse-types/src/compat.rs @@ -16,9 +16,9 @@ use std::sync::{ pub trait Collection {} -pub trait ReadWrite: std::io::Read + std::io::Write {} +pub trait ReadWrite: std::io::Read + std::io::Write + std::io::Seek {} -impl ReadWrite for T {} +impl ReadWrite for T {} #[derive(Clone, Debug)] pub enum Object { diff --git a/crates/libremetaverse-types/src/shim.rs b/crates/libremetaverse-types/src/shim.rs index bfab496..b190653 100644 --- a/crates/libremetaverse-types/src/shim.rs +++ b/crates/libremetaverse-types/src/shim.rs @@ -55,6 +55,13 @@ pub enum Error { InvalidOperation, /// An index or destination buffer boundary was exceeded. IndexOutOfRange, + /// Structured input was malformed at a byte or character position. + Parse { + /// Zero-based offset at which validation failed. + position: usize, + /// Static parser context suitable for diagnostics and fuzz triage. + context: &'static str, + }, /// An operation observed a requested cancellation. Cancelled, /// An HTTP request completed with an unsuccessful response. @@ -73,6 +80,7 @@ impl Error { | Self::Argument | Self::InvalidOperation | Self::IndexOutOfRange + | Self::Parse { .. } | Self::Cancelled | Self::HttpRequest | Self::Socket => None, @@ -96,6 +104,9 @@ impl fmt::Display for Error { formatter.write_str("operation was invalid for the current state") } Self::IndexOutOfRange => formatter.write_str("index was out of range"), + Self::Parse { position, context } => { + write!(formatter, "parse error at offset {position}: {context}") + } Self::Cancelled => formatter.write_str("operation was cancelled"), Self::HttpRequest => formatter.write_str("HTTP request failed"), Self::Socket => formatter.write_str("socket operation failed"), diff --git a/fuzz/corpus/binary_llsd/README.md b/fuzz/corpus/binary_llsd/README.md new file mode 100644 index 0000000..f2ed2a3 --- /dev/null +++ b/fuzz/corpus/binary_llsd/README.md @@ -0,0 +1,11 @@ +# Binary LLSD malformed seed corpus + +`malformed.hex` contains one named, hex-encoded input per line. The native +Binary LLSD unit test covers the same cases directly, so corpus drift is caught +without requiring a fuzzing tool in the normal workspace. A fuzz runner should +decode each even-length hex payload to raw bytes before mutation. + +The seeds cover empty/truncated scalar payloads, unknown markers, negative and +oversized lengths, missing array/map/key terminators, non-finite dates, and +excessive nesting. There are currently no upstream translated malformed Binary +LLSD cases beyond these issue-owned hardening cases. diff --git a/fuzz/corpus/binary_llsd/malformed.hex b/fuzz/corpus/binary_llsd/malformed.hex new file mode 100644 index 0000000..45c2e36 --- /dev/null +++ b/fuzz/corpus/binary_llsd/malformed.hex @@ -0,0 +1,15 @@ +empty: +unknown_marker:3f +truncated_integer:690000 +truncated_real:72000000 +truncated_uuid:75313233 +negative_binary_length:62ffffffff +truncated_binary_length:62 +negative_string_length:73ffffffff +negative_array_count:5bffffffff +negative_map_count:7bffffffff +oversized_string_length:737fffffff +missing_array_end:5b0000000121 +missing_map_key_marker:7b0000000178 +missing_map_end:7b000000005d +non_finite_date:64000000000000f87f diff --git a/tests/PARITY.md b/tests/PARITY.md index c396992..f013785 100644 --- a/tests/PARITY.md +++ b/tests/PARITY.md @@ -139,32 +139,32 @@ Reviewed Rust tests live outside `generated_parity.rs` and carry a `parity-case` | `LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.CreateLinksAsync_ServerError_CallbackFalse::test` | `BatchLinkTests.CreateLinksAsync_ServerError_CallbackFalse` | `` | `LibreMetaverse.Tests/BatchLinkTests.cs:270` | `` | `LibreMetaverse.Tests/TestHelpers/FakeGridClient.cs` | `crates/libremetaverse/src/batch_link_internal_semantics.rs:401 (`create_links_server_error_callback_false`)` | `translated` | `5fd9b2967bc61933cea80e01c55ee809f6ade246f10fb4048ec2668e0cc71dbf` | | `LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.GetCategoryLinks_UsesGetWithNoTidParameter::test` | `BatchLinkTests.GetCategoryLinks_UsesGetWithNoTidParameter` | `` | `LibreMetaverse.Tests/BatchLinkTests.cs:289` | `` | `LibreMetaverse.Tests/TestHelpers/FakeGridClient.cs` | `crates/libremetaverse/src/batch_link_internal_semantics.rs:423 (`get_category_links_uses_get_with_no_tid_parameter`)` | `translated` | `3079c03ab4b14d4ac10a410b3685f1593ea267c52de7b6323f9e8e8387314f29` | | `LibreMetaverse.Tests/BatchLinkTests.cs::BatchLinkTests.GetCategory_UsesGetWithNoTidParameter::test` | `BatchLinkTests.GetCategory_UsesGetWithNoTidParameter` | `` | `LibreMetaverse.Tests/BatchLinkTests.cs:304` | `` | `LibreMetaverse.Tests/TestHelpers/FakeGridClient.cs` | `crates/libremetaverse/src/batch_link_internal_semantics.rs:444 (`get_category_uses_get_with_no_tid_parameter`)` | `translated` | `98cd0aa58ce9640263d07aecd45337113b07acfc76640d17c5812abe05d35c73` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.HelperFunctions::test` | `BinarySDTests.HelperFunctions` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:55` | `` | `` | `tests/compat/tests/structured_data.rs:183 (`binary_helper_functions`)` | `translated` | `2e76ce199c2d56677831b18d049db19098e36a3a6c648785450e30b457833b03` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeUndef::test` | `BinarySDTests.DeserializeUndef` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:104` | `` | `` | `tests/compat/tests/structured_data.rs:219 (`binary_deserialize_undef`)` | `translated` | `9bd23543dfef3ad9ac7df278ad70f4d115ee429aea1575ca4f7ae81ac42d6d5c` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeUndef::test` | `BinarySDTests.SerializeUndef` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:111` | `` | `` | `tests/compat/tests/structured_data.rs:227 (`binary_serialize_undef`)` | `translated` | `e40b444801b08d08b1df4817855f8965d44302c77bc544bc06745a5bd41af7e3` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeBool::test` | `BinarySDTests.DeserializeBool` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:126` | `` | `` | `tests/compat/tests/structured_data.rs:235 (`binary_deserialize_bool`)` | `translated` | `531ee8ef1cb630baf895ae6509e018f71f1866f1d57e9d97efd7869ecaef39c7` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeBool::test` | `BinarySDTests.SerializeBool` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:138` | `` | `` | `tests/compat/tests/structured_data.rs:246 (`binary_serialize_bool`)` | `translated` | `854f22dcb119617ef83528c9b9879c8924fdae7830edff4031aef8826a1bba63` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeInteger::test` | `BinarySDTests.DeserializeInteger` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:156` | `` | `` | `tests/compat/tests/structured_data.rs:257 (`binary_deserialize_integer`)` | `translated` | `09feba2ef1a3357273b677ee8ee35c72528e68ca0fe92b6a0b1b5491025147d1` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeInteger::test` | `BinarySDTests.SerializeInteger` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:169` | `` | `` | `tests/compat/tests/structured_data.rs:269 (`binary_serialize_integer`)` | `translated` | `789d62f170c3e92d9dad187484c0e4c6fd554f6e0b025f08086878551ea9119c` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeReal::test` | `BinarySDTests.DeserializeReal` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:190` | `` | `` | `tests/compat/tests/structured_data.rs:288 (`binary_deserialize_real`)` | `translated` | `1acda53f2049f062f359a4dd3271796a8051a37a1dff02150794107fc743c934` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeReal::test` | `BinarySDTests.SerializeReal` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:198` | `` | `` | `tests/compat/tests/structured_data.rs:298 (`binary_serialize_real`)` | `translated` | `94d74ae4767824e9702515204529543281b83521a085343c76204650ec96ed57` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeUUID::test` | `BinarySDTests.DeserializeUUID` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:217` | `` | `` | `tests/compat/tests/structured_data.rs:316 (`binary_deserialize_uuid`)` | `translated` | `c1a9206927342fecc0c9ff4ed4b80cc50f288b794996e1668ed4b6a6433ea977` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeUUID::test` | `BinarySDTests.SerializeUUID` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:230` | `` | `` | `tests/compat/tests/structured_data.rs:332 (`binary_serialize_uuid`)` | `translated` | `5a236b468cedd7667d58641cb067ce30f6135aa95f2291538083e4254f52c2ad` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeLLSDBinary::test` | `BinarySDTests.DeserializeLLSDBinary` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:255` | `` | `` | `tests/compat/tests/structured_data.rs:352 (`binary_deserialize_llsd_binary`)` | `translated` | `b2cad2218f203d740c2863713248bc0f8083980f30c34cc244535eebc5f1aae1` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeLLSDBinary::test` | `BinarySDTests.SerializeLLSDBinary` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:267` | `` | `` | `tests/compat/tests/structured_data.rs:362 (`binary_serialize_llsd_binary`)` | `translated` | `b715f3475dfe6e0876409a10c55548e345b7caf332939ff25489662500e05511` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeString::test` | `BinarySDTests.DeserializeString` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:290` | `` | `` | `tests/compat/tests/structured_data.rs:373 (`binary_deserialize_string`)` | `translated` | `d95f0156c50cd49eef0d8da231bf9128e95b274de92ac88409294ef9f925bada` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeString::test` | `BinarySDTests.SerializeString` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:304` | `` | `` | `tests/compat/tests/structured_data.rs:387 (`binary_serialize_string`)` | `translated` | `75b2c0e402cfdea326a1262287172353538d73ce343d7df99ec51f8531340cab` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeURI::test` | `BinarySDTests.DeserializeURI` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:349` | `` | `` | `tests/compat/tests/structured_data.rs:411 (`binary_deserialize_uri`)` | `translated` | `3ff6c2dce1e709e446259c9154dbe297ccb21b8bff87be8b53cbf43356f0ccf7` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeURI::test` | `BinarySDTests.SerializeURI` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:359` | `` | `` | `tests/compat/tests/structured_data.rs:419 (`binary_serialize_uri`)` | `translated` | `20914654e0b2b746d95ef1f7664e1bd732116326d45d1b823e484032edb1a7e8` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeDateTime::test` | `BinarySDTests.DeserializeDateTime` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:375` | `` | `` | `tests/compat/tests/structured_data.rs:427 (`binary_deserialize_date_time`)` | `translated` | `b417d525ccfeb449264e09dfe0589bd920429ade3014c8d24f8d7d913f1d6145` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeDateTime::test` | `BinarySDTests.SerializeDateTime` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:385` | `` | `` | `tests/compat/tests/structured_data.rs:437 (`binary_serialize_date_time`)` | `translated` | `5bb705bbd2f45058eb8fc498ca4f7a0318b448f2e175e21e760ff7156ecbce0f` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeArray::test` | `BinarySDTests.DeserializeArray` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:424` | `` | `` | `tests/compat/tests/structured_data.rs:456 (`binary_deserialize_array`)` | `translated` | `72b9700cfe07cb399985db485a75f34e483ddab520e26906995a601014451e53` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeArray::test` | `BinarySDTests.SerializeArray` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:451` | `` | `` | `tests/compat/tests/structured_data.rs:476 (`binary_serialize_array`)` | `translated` | `2a0e692a44bae8b3d058524a765e57355fec7bda6ae9a063465332acce2eb9f8` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeDictionary::test` | `BinarySDTests.DeserializeDictionary` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:506` | `` | `` | `tests/compat/tests/structured_data.rs:528 (`binary_deserialize_dictionary`)` | `translated` | `b2c5f1535e388417b7d4561b0e69de7e9f96468bd101864e3ba63deb95a872de` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeDictionary::test` | `BinarySDTests.SerializeDictionary` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:531` | `` | `` | `tests/compat/tests/structured_data.rs:542 (`binary_serialize_dictionary`)` | `translated` | `01b7a8fc0c0f7cc588ed23d15f01e30d8a5d9cd07954e84046945b95cd031373` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeNestedComposite::test` | `BinarySDTests.DeserializeNestedComposite` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:598` | `` | `` | `tests/compat/tests/structured_data.rs:579 (`binary_deserialize_nested_composite`)` | `translated` | `60f8cf739fecf42c98ae4e0878d06234278b9d8370afc38f0d501d62f8ff9cdf` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeNestedComposite::test` | `BinarySDTests.SerializeNestedComposite` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:632` | `` | `` | `tests/compat/tests/structured_data.rs:587 (`binary_serialize_nested_composite`)` | `translated` | `092b52da3f0cf720595fdb84c929c8ad033c60ff978429cb1d27f9e215936b10` | -| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeLongMessage::test` | `BinarySDTests.SerializeLongMessage` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:676` | `` | `` | `tests/compat/tests/structured_data.rs:598 (`binary_serialize_long_message`)` | `translated` | `b49afb91578e6c19193cd48acf161a9f8c57bbd20245783054709a509f63780e` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.HelperFunctions::test` | `BinarySDTests.HelperFunctions` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:55` | `` | `` | `tests/compat/tests/structured_data.rs:189 (`binary_helper_functions`)` | `translated` | `2e76ce199c2d56677831b18d049db19098e36a3a6c648785450e30b457833b03` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeUndef::test` | `BinarySDTests.DeserializeUndef` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:104` | `` | `` | `tests/compat/tests/structured_data.rs:225 (`binary_deserialize_undef`)` | `translated` | `9bd23543dfef3ad9ac7df278ad70f4d115ee429aea1575ca4f7ae81ac42d6d5c` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeUndef::test` | `BinarySDTests.SerializeUndef` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:111` | `` | `` | `tests/compat/tests/structured_data.rs:233 (`binary_serialize_undef`)` | `translated` | `e40b444801b08d08b1df4817855f8965d44302c77bc544bc06745a5bd41af7e3` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeBool::test` | `BinarySDTests.DeserializeBool` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:126` | `` | `` | `tests/compat/tests/structured_data.rs:241 (`binary_deserialize_bool`)` | `translated` | `531ee8ef1cb630baf895ae6509e018f71f1866f1d57e9d97efd7869ecaef39c7` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeBool::test` | `BinarySDTests.SerializeBool` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:138` | `` | `` | `tests/compat/tests/structured_data.rs:252 (`binary_serialize_bool`)` | `translated` | `854f22dcb119617ef83528c9b9879c8924fdae7830edff4031aef8826a1bba63` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeInteger::test` | `BinarySDTests.DeserializeInteger` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:156` | `` | `` | `tests/compat/tests/structured_data.rs:263 (`binary_deserialize_integer`)` | `translated` | `09feba2ef1a3357273b677ee8ee35c72528e68ca0fe92b6a0b1b5491025147d1` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeInteger::test` | `BinarySDTests.SerializeInteger` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:169` | `` | `` | `tests/compat/tests/structured_data.rs:275 (`binary_serialize_integer`)` | `translated` | `789d62f170c3e92d9dad187484c0e4c6fd554f6e0b025f08086878551ea9119c` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeReal::test` | `BinarySDTests.DeserializeReal` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:190` | `` | `` | `tests/compat/tests/structured_data.rs:294 (`binary_deserialize_real`)` | `translated` | `1acda53f2049f062f359a4dd3271796a8051a37a1dff02150794107fc743c934` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeReal::test` | `BinarySDTests.SerializeReal` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:198` | `` | `` | `tests/compat/tests/structured_data.rs:304 (`binary_serialize_real`)` | `translated` | `94d74ae4767824e9702515204529543281b83521a085343c76204650ec96ed57` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeUUID::test` | `BinarySDTests.DeserializeUUID` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:217` | `` | `` | `tests/compat/tests/structured_data.rs:322 (`binary_deserialize_uuid`)` | `translated` | `c1a9206927342fecc0c9ff4ed4b80cc50f288b794996e1668ed4b6a6433ea977` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeUUID::test` | `BinarySDTests.SerializeUUID` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:230` | `` | `` | `tests/compat/tests/structured_data.rs:338 (`binary_serialize_uuid`)` | `translated` | `5a236b468cedd7667d58641cb067ce30f6135aa95f2291538083e4254f52c2ad` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeLLSDBinary::test` | `BinarySDTests.DeserializeLLSDBinary` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:255` | `` | `` | `tests/compat/tests/structured_data.rs:358 (`binary_deserialize_llsd_binary`)` | `translated` | `b2cad2218f203d740c2863713248bc0f8083980f30c34cc244535eebc5f1aae1` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeLLSDBinary::test` | `BinarySDTests.SerializeLLSDBinary` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:267` | `` | `` | `tests/compat/tests/structured_data.rs:368 (`binary_serialize_llsd_binary`)` | `translated` | `b715f3475dfe6e0876409a10c55548e345b7caf332939ff25489662500e05511` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeString::test` | `BinarySDTests.DeserializeString` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:290` | `` | `` | `tests/compat/tests/structured_data.rs:379 (`binary_deserialize_string`)` | `translated` | `d95f0156c50cd49eef0d8da231bf9128e95b274de92ac88409294ef9f925bada` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeString::test` | `BinarySDTests.SerializeString` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:304` | `` | `` | `tests/compat/tests/structured_data.rs:393 (`binary_serialize_string`)` | `translated` | `75b2c0e402cfdea326a1262287172353538d73ce343d7df99ec51f8531340cab` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeURI::test` | `BinarySDTests.DeserializeURI` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:349` | `` | `` | `tests/compat/tests/structured_data.rs:417 (`binary_deserialize_uri`)` | `translated` | `3ff6c2dce1e709e446259c9154dbe297ccb21b8bff87be8b53cbf43356f0ccf7` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeURI::test` | `BinarySDTests.SerializeURI` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:359` | `` | `` | `tests/compat/tests/structured_data.rs:425 (`binary_serialize_uri`)` | `translated` | `20914654e0b2b746d95ef1f7664e1bd732116326d45d1b823e484032edb1a7e8` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeDateTime::test` | `BinarySDTests.DeserializeDateTime` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:375` | `` | `` | `tests/compat/tests/structured_data.rs:433 (`binary_deserialize_date_time`)` | `translated` | `b417d525ccfeb449264e09dfe0589bd920429ade3014c8d24f8d7d913f1d6145` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeDateTime::test` | `BinarySDTests.SerializeDateTime` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:385` | `` | `` | `tests/compat/tests/structured_data.rs:443 (`binary_serialize_date_time`)` | `translated` | `5bb705bbd2f45058eb8fc498ca4f7a0318b448f2e175e21e760ff7156ecbce0f` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeArray::test` | `BinarySDTests.DeserializeArray` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:424` | `` | `` | `tests/compat/tests/structured_data.rs:462 (`binary_deserialize_array`)` | `translated` | `72b9700cfe07cb399985db485a75f34e483ddab520e26906995a601014451e53` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeArray::test` | `BinarySDTests.SerializeArray` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:451` | `` | `` | `tests/compat/tests/structured_data.rs:482 (`binary_serialize_array`)` | `translated` | `2a0e692a44bae8b3d058524a765e57355fec7bda6ae9a063465332acce2eb9f8` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeDictionary::test` | `BinarySDTests.DeserializeDictionary` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:506` | `` | `` | `tests/compat/tests/structured_data.rs:534 (`binary_deserialize_dictionary`)` | `translated` | `b2c5f1535e388417b7d4561b0e69de7e9f96468bd101864e3ba63deb95a872de` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeDictionary::test` | `BinarySDTests.SerializeDictionary` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:531` | `` | `` | `tests/compat/tests/structured_data.rs:548 (`binary_serialize_dictionary`)` | `translated` | `01b7a8fc0c0f7cc588ed23d15f01e30d8a5d9cd07954e84046945b95cd031373` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeNestedComposite::test` | `BinarySDTests.DeserializeNestedComposite` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:598` | `` | `` | `tests/compat/tests/structured_data.rs:585 (`binary_deserialize_nested_composite`)` | `translated` | `60f8cf739fecf42c98ae4e0878d06234278b9d8370afc38f0d501d62f8ff9cdf` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeNestedComposite::test` | `BinarySDTests.SerializeNestedComposite` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:632` | `` | `` | `tests/compat/tests/structured_data.rs:593 (`binary_serialize_nested_composite`)` | `translated` | `092b52da3f0cf720595fdb84c929c8ad033c60ff978429cb1d27f9e215936b10` | +| `LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeLongMessage::test` | `BinarySDTests.SerializeLongMessage` | `` | `LibreMetaverse.Tests/BinaryLLSDTests.cs:676` | `` | `` | `tests/compat/tests/structured_data.rs:604 (`binary_serialize_long_message`)` | `translated` | `b49afb91578e6c19193cd48acf161a9f8c57bbd20245783054709a509f63780e` | | `LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.InventoryAISClient_Null_Throws::test` | `ConstructorNullArgumentTests.InventoryAISClient_Null_Throws` | `` | `LibreMetaverse.Tests/ConstructorNullArgumentTests.cs:9` | `` | `` | `tests/compat/tests/inventory_ais_semantics.rs:120 (`inventory_ais_client_null_throws`)` | `translated` | `ac92e375efc45c50b37e6c82aea372d605fceb470ce053a025e05ff47a5c7121` | | `LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.GridManager_Null_Throws::test` | `ConstructorNullArgumentTests.GridManager_Null_Throws` | `` | `LibreMetaverse.Tests/ConstructorNullArgumentTests.cs:15` | `` | `` | `tests/compat/tests/world_constructor_semantics.rs:7 (`grid_manager_null_throws`)` | `translated` | `e972a95f334b0f46948cda34c27124c28c44faf4372d0e598d7dc60050b49be4` | | `LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.InventoryManager_Null_Throws::test` | `ConstructorNullArgumentTests.InventoryManager_Null_Throws` | `` | `LibreMetaverse.Tests/ConstructorNullArgumentTests.cs:21` | `` | `` | `tests/compat/tests/inventory_manager_semantics.rs:16 (`inventory_manager_null_throws`)` | `translated` | `5e7498066c944800354abbc71eea825fe90d0c40a25a6065967a3ebcc9efea74` | @@ -435,30 +435,30 @@ Reviewed Rust tests live outside `generated_parity.rs` and carry a `parity-case` | `LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs::MisclassifiedLinkRegressionTests.InventoryStore_NotContains_WhenTargetAbsent::test` | `MisclassifiedLinkRegressionTests.InventoryStore_NotContains_WhenTargetAbsent` | `` | `LibreMetaverse.Tests/MisclassifiedLinkRegressionTests.cs:216` | `Inventory` | `` | `tests/compat/tests/misclassified_link_semantics.rs:136 (`inventory_store_not_contains_when_target_absent`)` | `translated` | `6900e220c33ec135d02c55e047c7052a095d5dd9d71da4a857ae70bc151c472b` | | `LibreMetaverse.Tests/NetworkTests.cs::NetworkTests.DetectObjects::test` | `NetworkTests.DetectObjects` | `` | `LibreMetaverse.Tests/NetworkTests.cs:121` | `Network, RequiresLiveServer` | `` | `tests/compat/tests/network_semantics.rs:409 (`detect_objects_live`)` | `ignored-live` | `8b72f1ca30feda2fad0812faf3a2f83d691d3cca9268054b3cc3bf89ad786e87` | | `LibreMetaverse.Tests/NetworkTests.cs::NetworkTests.CapsQueue::test` | `NetworkTests.CapsQueue` | `` | `LibreMetaverse.Tests/NetworkTests.cs:188` | `Network, RequiresLiveServer` | `` | `tests/compat/tests/network_semantics.rs:488 (`caps_queue_live`)` | `ignored-live` | `cd5af4e7d69df3e938540711877d167fe28efb9af8af7518a62b8f406e46cc18` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.HelperFunctions::test` | `NotationSDTests.HelperFunctions` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:53` | `` | `` | `tests/compat/tests/structured_data.rs:622 (`notation_helper_functions`)` | `translated` | `a521ca5407ed3afd1d59f5b65a283bcebe9d34b4c384d68c5fc674b3a1eeb9df` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeUndef::test` | `NotationSDTests.DeserializeUndef` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:80` | `` | `` | `tests/compat/tests/structured_data.rs:644 (`notation_deserialize_undef`)` | `translated` | `8c802fb14244cb423223c7c25702e4120da261f5dd1b378d2eca597277371406` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeUndef::test` | `NotationSDTests.SerializeUndef` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:88` | `` | `` | `tests/compat/tests/structured_data.rs:652 (`notation_serialize_undef`)` | `translated` | `2ceee97b1826a3ba88a50798dba184b48998196192e31527171a9980f06c3281` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeBoolean::test` | `NotationSDTests.DeserializeBoolean` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:98` | `` | `` | `tests/compat/tests/structured_data.rs:662 (`notation_deserialize_boolean`)` | `translated` | `9279106aebdcab8c8b179963bd3e9beb3d6fec89e53c376e56eed7b7c17213a2` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeBoolean::test` | `NotationSDTests.SerializeBoolean` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:152` | `` | `` | `tests/compat/tests/structured_data.rs:677 (`notation_serialize_boolean`)` | `translated` | `101bb91e58a4fe924f6137b948c4e5d3efa46875a8a118031fc657b59f6f4bdf` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeInteger::test` | `NotationSDTests.DeserializeInteger` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:168` | `` | `` | `tests/compat/tests/structured_data.rs:689 (`notation_deserialize_integer`)` | `translated` | `5a8e2d8eeab4fbdc46b0487fb65cf35905c3e640e1a06e227443e5aae990a265` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeInteger::test` | `NotationSDTests.SerializeInteger` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:182` | `` | `` | `tests/compat/tests/structured_data.rs:700 (`notation_serialize_integer`)` | `translated` | `8bb1b1752c8bc23499b6f77167fc307e22a6572719c45a36280bee36ff645d93` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeReal::test` | `NotationSDTests.DeserializeReal` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:198` | `` | `` | `tests/compat/tests/structured_data.rs:724 (`notation_deserialize_real`)` | `translated` | `ffe387948b423b9fe47e4b3df9ae7c21306200f3afba8cd4944933c274691d79` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeReal::test` | `NotationSDTests.SerializeReal` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:227` | `` | `` | `tests/compat/tests/structured_data.rs:740 (`notation_serialize_real`)` | `translated` | `c40b06b0496191186c6cdc5cc9e03952cb3a31fc8fdc98ecd671c446cbd0c0be` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeUUID::test` | `NotationSDTests.DeserializeUUID` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:267` | `` | `` | `tests/compat/tests/structured_data.rs:760 (`notation_deserialize_uuid`)` | `translated` | `1ab05a03d422d0450dba3571f009ee9af6ee151d8a1ee1c248cc48f93196d242` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeUUID::test` | `NotationSDTests.SerializeUUID` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:281` | `` | `` | `tests/compat/tests/structured_data.rs:778 (`notation_serialize_uuid`)` | `translated` | `122f917c29076476e11dc9d36f943e4910168a516be234189047e8b51b09e539` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeString::test` | `NotationSDTests.DeserializeString` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:297` | `` | `` | `tests/compat/tests/structured_data.rs:793 (`notation_deserialize_string`)` | `translated` | `a29dc440ccde574c1302c57d3ef4c5404aa4fd419a5f160ba4920ab5a3349cc7` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeString::test` | `NotationSDTests.SerializeString` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:361` | `` | `` | `tests/compat/tests/structured_data.rs:815 (`notation_serialize_string`)` | `translated` | `1cca05a4cf0fbbd516f1fe1c43b9fc617840a6374680c9085087adc1d9ae41cd` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeURI::test` | `NotationSDTests.DeserializeURI` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:395` | `` | `` | `tests/compat/tests/structured_data.rs:843 (`notation_deserialize_uri`)` | `translated` | `4ed3cbdce17f8e7e2b3294a8a85db9775458fcc0fecd9052bfef4110280ef55d` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeURI::test` | `NotationSDTests.SerializeURI` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:409` | `` | `` | `tests/compat/tests/structured_data.rs:864 (`notation_serialize_uri`)` | `translated` | `ed474ac9185db97d779cb9c598d6908c2d5e7c23cc09871f75ba04161cb843f1` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeDate::test` | `NotationSDTests.DeserializeDate` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:427` | `` | `` | `tests/compat/tests/structured_data.rs:879 (`notation_deserialize_date`)` | `translated` | `bd7b2ae076622734844b844c374223e174706f48f37bf18d875ecf3b14c81e4c` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeDate::test` | `NotationSDTests.SerializeDate` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:438` | `` | `` | `tests/compat/tests/structured_data.rs:888 (`notation_serialize_date`)` | `translated` | `987524a4caf7bdfaf3db138493cdc1a7a585b7730a11d8feea92e32860453997` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeBinary::test` | `NotationSDTests.SerializeBinary` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:466` | `` | `` | `tests/compat/tests/structured_data.rs:908 (`notation_serialize_binary`)` | `translated` | `07f940143dd6212080fee783bf3c493157a5099fbd0646bf91a5024d12e55d6b` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeArray::test` | `NotationSDTests.DeserializeArray` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:479` | `` | `` | `tests/compat/tests/structured_data.rs:919 (`notation_deserialize_array`)` | `translated` | `b1313ef5f375a1511fffe4c593dedc046e4ebfcca2a41cac6fafa65b99abc38e` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeArray::test` | `NotationSDTests.SerializeArray` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:522` | `` | `` | `tests/compat/tests/structured_data.rs:959 (`notation_serialize_array`)` | `translated` | `2c0a7af66c707280621a03423a6b56b24acdcc26b5f34d6bc5427ba98a111c50` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeMap::test` | `NotationSDTests.DeserializeMap` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:559` | `` | `` | `tests/compat/tests/structured_data.rs:971 (`notation_deserialize_map`)` | `translated` | `75348b6dde6ff642f3f19e48009565fb82410ed522583d20c3833bdd4121b258` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeMap::test` | `NotationSDTests.SerializeMap` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:600` | `` | `` | `tests/compat/tests/structured_data.rs:1037 (`notation_serialize_map`)` | `translated` | `71bf4cf86acc617623d904f5d1a1f892e45e5f6298e057ab7670281da1d6b541` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeRealWorldExamples::test` | `NotationSDTests.DeserializeRealWorldExamples` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:653` | `` | `` | `tests/compat/tests/structured_data.rs:1053 (`notation_deserialize_real_world_examples`)` | `translated` | `684c4f3ad342010bc466699fc921375f3df16b63c600ac85f970d63b57d62ae2` | -| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeFormattedTest::test` | `NotationSDTests.SerializeFormattedTest` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:707` | `` | `` | `tests/compat/tests/structured_data.rs:1126 (`notation_serialize_formatted_test`)` | `translated` | `de64ee1e02e47116c580a7340e0ce8a908787eff63d46a56ee04379330932ee5` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.HelperFunctions::test` | `NotationSDTests.HelperFunctions` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:53` | `` | `` | `tests/compat/tests/structured_data.rs:628 (`notation_helper_functions`)` | `translated` | `a521ca5407ed3afd1d59f5b65a283bcebe9d34b4c384d68c5fc674b3a1eeb9df` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeUndef::test` | `NotationSDTests.DeserializeUndef` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:80` | `` | `` | `tests/compat/tests/structured_data.rs:650 (`notation_deserialize_undef`)` | `translated` | `8c802fb14244cb423223c7c25702e4120da261f5dd1b378d2eca597277371406` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeUndef::test` | `NotationSDTests.SerializeUndef` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:88` | `` | `` | `tests/compat/tests/structured_data.rs:658 (`notation_serialize_undef`)` | `translated` | `2ceee97b1826a3ba88a50798dba184b48998196192e31527171a9980f06c3281` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeBoolean::test` | `NotationSDTests.DeserializeBoolean` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:98` | `` | `` | `tests/compat/tests/structured_data.rs:668 (`notation_deserialize_boolean`)` | `translated` | `9279106aebdcab8c8b179963bd3e9beb3d6fec89e53c376e56eed7b7c17213a2` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeBoolean::test` | `NotationSDTests.SerializeBoolean` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:152` | `` | `` | `tests/compat/tests/structured_data.rs:683 (`notation_serialize_boolean`)` | `translated` | `101bb91e58a4fe924f6137b948c4e5d3efa46875a8a118031fc657b59f6f4bdf` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeInteger::test` | `NotationSDTests.DeserializeInteger` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:168` | `` | `` | `tests/compat/tests/structured_data.rs:695 (`notation_deserialize_integer`)` | `translated` | `5a8e2d8eeab4fbdc46b0487fb65cf35905c3e640e1a06e227443e5aae990a265` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeInteger::test` | `NotationSDTests.SerializeInteger` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:182` | `` | `` | `tests/compat/tests/structured_data.rs:706 (`notation_serialize_integer`)` | `translated` | `8bb1b1752c8bc23499b6f77167fc307e22a6572719c45a36280bee36ff645d93` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeReal::test` | `NotationSDTests.DeserializeReal` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:198` | `` | `` | `tests/compat/tests/structured_data.rs:730 (`notation_deserialize_real`)` | `translated` | `ffe387948b423b9fe47e4b3df9ae7c21306200f3afba8cd4944933c274691d79` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeReal::test` | `NotationSDTests.SerializeReal` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:227` | `` | `` | `tests/compat/tests/structured_data.rs:746 (`notation_serialize_real`)` | `translated` | `c40b06b0496191186c6cdc5cc9e03952cb3a31fc8fdc98ecd671c446cbd0c0be` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeUUID::test` | `NotationSDTests.DeserializeUUID` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:267` | `` | `` | `tests/compat/tests/structured_data.rs:766 (`notation_deserialize_uuid`)` | `translated` | `1ab05a03d422d0450dba3571f009ee9af6ee151d8a1ee1c248cc48f93196d242` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeUUID::test` | `NotationSDTests.SerializeUUID` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:281` | `` | `` | `tests/compat/tests/structured_data.rs:784 (`notation_serialize_uuid`)` | `translated` | `122f917c29076476e11dc9d36f943e4910168a516be234189047e8b51b09e539` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeString::test` | `NotationSDTests.DeserializeString` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:297` | `` | `` | `tests/compat/tests/structured_data.rs:799 (`notation_deserialize_string`)` | `translated` | `a29dc440ccde574c1302c57d3ef4c5404aa4fd419a5f160ba4920ab5a3349cc7` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeString::test` | `NotationSDTests.SerializeString` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:361` | `` | `` | `tests/compat/tests/structured_data.rs:821 (`notation_serialize_string`)` | `translated` | `1cca05a4cf0fbbd516f1fe1c43b9fc617840a6374680c9085087adc1d9ae41cd` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeURI::test` | `NotationSDTests.DeserializeURI` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:395` | `` | `` | `tests/compat/tests/structured_data.rs:849 (`notation_deserialize_uri`)` | `translated` | `4ed3cbdce17f8e7e2b3294a8a85db9775458fcc0fecd9052bfef4110280ef55d` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeURI::test` | `NotationSDTests.SerializeURI` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:409` | `` | `` | `tests/compat/tests/structured_data.rs:870 (`notation_serialize_uri`)` | `translated` | `ed474ac9185db97d779cb9c598d6908c2d5e7c23cc09871f75ba04161cb843f1` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeDate::test` | `NotationSDTests.DeserializeDate` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:427` | `` | `` | `tests/compat/tests/structured_data.rs:885 (`notation_deserialize_date`)` | `translated` | `bd7b2ae076622734844b844c374223e174706f48f37bf18d875ecf3b14c81e4c` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeDate::test` | `NotationSDTests.SerializeDate` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:438` | `` | `` | `tests/compat/tests/structured_data.rs:894 (`notation_serialize_date`)` | `translated` | `987524a4caf7bdfaf3db138493cdc1a7a585b7730a11d8feea92e32860453997` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeBinary::test` | `NotationSDTests.SerializeBinary` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:466` | `` | `` | `tests/compat/tests/structured_data.rs:914 (`notation_serialize_binary`)` | `translated` | `07f940143dd6212080fee783bf3c493157a5099fbd0646bf91a5024d12e55d6b` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeArray::test` | `NotationSDTests.DeserializeArray` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:479` | `` | `` | `tests/compat/tests/structured_data.rs:925 (`notation_deserialize_array`)` | `translated` | `b1313ef5f375a1511fffe4c593dedc046e4ebfcca2a41cac6fafa65b99abc38e` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeArray::test` | `NotationSDTests.SerializeArray` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:522` | `` | `` | `tests/compat/tests/structured_data.rs:965 (`notation_serialize_array`)` | `translated` | `2c0a7af66c707280621a03423a6b56b24acdcc26b5f34d6bc5427ba98a111c50` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeMap::test` | `NotationSDTests.DeserializeMap` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:559` | `` | `` | `tests/compat/tests/structured_data.rs:977 (`notation_deserialize_map`)` | `translated` | `75348b6dde6ff642f3f19e48009565fb82410ed522583d20c3833bdd4121b258` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeMap::test` | `NotationSDTests.SerializeMap` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:600` | `` | `` | `tests/compat/tests/structured_data.rs:1043 (`notation_serialize_map`)` | `translated` | `71bf4cf86acc617623d904f5d1a1f892e45e5f6298e057ab7670281da1d6b541` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeRealWorldExamples::test` | `NotationSDTests.DeserializeRealWorldExamples` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:653` | `` | `` | `tests/compat/tests/structured_data.rs:1059 (`notation_deserialize_real_world_examples`)` | `translated` | `684c4f3ad342010bc466699fc921375f3df16b63c600ac85f970d63b57d62ae2` | +| `LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeFormattedTest::test` | `NotationSDTests.SerializeFormattedTest` | `` | `LibreMetaverse.Tests/NotationLLSDTests.cs:707` | `` | `` | `tests/compat/tests/structured_data.rs:1132 (`notation_serialize_formatted_test`)` | `translated` | `de64ee1e02e47116c580a7340e0ce8a908787eff63d46a56ee04379330932ee5` | | `LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_StandardRegion_Loads256x256::test` | `OarFileTerrainTests.LoadTerrain_StandardRegion_Loads256x256` | `` | `LibreMetaverse.Tests/OarFileTerrainTests.cs:38` | `OarFile` | `` | `crates/libremetaverse/src/asset_archive_semantics.rs:16 (`load_standard_region_terrain`)` | `translated` | `c4e3a994baf06b0106a6614e9c3efbcc27e45ff1725f5470d2db6ded1fff6014` | | `LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_Varregion_Loads512x512::test` | `OarFileTerrainTests.LoadTerrain_Varregion_Loads512x512` | `` | `LibreMetaverse.Tests/OarFileTerrainTests.cs:52` | `OarFile` | `` | `crates/libremetaverse/src/asset_archive_semantics.rs:45 (`load_varregion_terrain`)` | `translated` | `4820338f10acbb4987e26992d7a7957be58ab6bc548674bf18943ef312962894` | | `LibreMetaverse.Tests/OarFileTerrainTests.cs::OarFileTerrainTests.LoadTerrain_WrongByteCount_FailsGracefully::test` | `OarFileTerrainTests.LoadTerrain_WrongByteCount_FailsGracefully` | `` | `LibreMetaverse.Tests/OarFileTerrainTests.cs:65` | `OarFile` | `` | `crates/libremetaverse/src/asset_archive_semantics.rs:73 (`reject_terrain_with_wrong_byte_count`)` | `translated` | `ff6fb4feb2773c93397d412d0ecf6aef1f3636e823dabb729a7a6cbe94d1513f` | @@ -487,18 +487,18 @@ Reviewed Rust tests live outside `generated_parity.rs` and carry a `parity-case` | `LibreMetaverse.Tests/PrimitiveTests.cs::PrimitiveTests.FromOSD_PartialProfile_UsesDefaultsForMissingFields::test` | `PrimitiveTests.FromOSD_PartialProfile_UsesDefaultsForMissingFields` | `` | `LibreMetaverse.Tests/PrimitiveTests.cs:173` | `` | `` | `tests/compat/tests/world_object_semantics.rs:635 (`primitive_from_osd_partial_profile_uses_defaults`)` | `translated` | `f3a3e506e3ef417f6323875db82179a4ffbdc1d4ee383417f2b0bd5afd0d0dba` | | `LibreMetaverse.Tests/ProductInfoRequestMessageTests.cs::ProductInfoRequestMessageTests.Deserialize_BareArray_ReadsSkuNameDescription::test` | `ProductInfoRequestMessageTests.Deserialize_BareArray_ReadsSkuNameDescription` | `` | `LibreMetaverse.Tests/ProductInfoRequestMessageTests.cs:45` | `ProductInfo` | `` | `tests/compat/tests/social_message_semantics.rs:119 (`product_info_deserialize_bare_array_reads_fields`)` | `translated` | `5d51fdbb1bec1ff74df59778d214413e78fb650679d36e7c44be92d1b2e3205f` | | `LibreMetaverse.Tests/ProductInfoRequestMessageTests.cs::ProductInfoRequestMessageTests.SerializeDeserialize_RoundTrips::test` | `ProductInfoRequestMessageTests.SerializeDeserialize_RoundTrips` | `` | `LibreMetaverse.Tests/ProductInfoRequestMessageTests.cs:68` | `ProductInfo` | `` | `tests/compat/tests/social_message_semantics.rs:141 (`product_info_serialize_deserialize_round_trips`)` | `translated` | `5cb54bed4150cf13f815b223d6b7e35e7427004a12e98c7328c7674b6fe6309b` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeBoolean::test` | `ProtobufTests.SerializeBoolean` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:36` | `` | `` | `tests/compat/tests/structured_data.rs:1158 (`protobuf_serialize_boolean`)` | `translated` | `06d71d5ad54dab8236458e6cf3c9893728d4a13c348441822f674164a285150b` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeInteger::test` | `ProtobufTests.SerializeInteger` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:52` | `` | `` | `tests/compat/tests/structured_data.rs:1170 (`protobuf_serialize_integer`)` | `translated` | `8a20e00e06a1a01a39c6cc3f1de100015abb0446ee07e42fbbfc89d4351d9f5b` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeReal::test` | `ProtobufTests.SerializeReal` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:74` | `` | `` | `tests/compat/tests/structured_data.rs:1183 (`protobuf_serialize_real`)` | `translated` | `4aae9af41d534a2c4755f40f9da4d7b780a4552b52c7816d0aa70f640d64cfd3` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeUUID::test` | `ProtobufTests.SerializeUUID` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:84` | `` | `` | `tests/compat/tests/structured_data.rs:1194 (`protobuf_serialize_uuid`)` | `translated` | `7fa09c08d627d04b66651d0f50cbf6a4373536315c121bab59f43b57c0cbf064` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeString::test` | `ProtobufTests.SerializeString` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:100` | `` | `` | `tests/compat/tests/structured_data.rs:1219 (`protobuf_serialize_string`)` | `translated` | `880195caac721a93349f902efb2615342d84eca86a64c8340dd314044d8a3ade` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeArray::test` | `ProtobufTests.SerializeArray` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:116` | `` | `` | `tests/compat/tests/structured_data.rs:1234 (`protobuf_serialize_array`)` | `translated` | `2bdfc891534aeafa4a0729f4f3ba34d9fb4cc0ea4e88c6ac1aab63224b95f230` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeMap::test` | `ProtobufTests.SerializeMap` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:137` | `` | `` | `tests/compat/tests/structured_data.rs:1249 (`protobuf_serialize_map`)` | `translated` | `d2a14b977d843249e2569a2287981ee9fc903c07cf19b5e3cd613c340725de51` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeNestedComposite::test` | `ProtobufTests.SerializeNestedComposite` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:158` | `` | `` | `tests/compat/tests/structured_data.rs:1264 (`protobuf_serialize_nested_composite`)` | `translated` | `bae0fbd2740466f84376f8f98ec4bf93143ce9cc7ad60cdd15907411280ff0a6` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.AutoDetectProtobuf::test` | `ProtobufTests.AutoDetectProtobuf` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:191` | `` | `` | `tests/compat/tests/structured_data.rs:1284 (`protobuf_auto_detect`)` | `translated` | `2c319b85ae1615fcb9c5804ac01bcb108c6ab235d51b971447fd2576054d8191` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeBinary::test` | `ProtobufTests.SerializeBinary` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:203` | `` | `` | `tests/compat/tests/structured_data.rs:1298 (`protobuf_serialize_binary`)` | `translated` | `f5b3aa5e551371f05d90f20f5552844c71e9abb337d33ed178e72297e5d7435d` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeDate::test` | `ProtobufTests.SerializeDate` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:214` | `` | `` | `tests/compat/tests/structured_data.rs:1309 (`protobuf_serialize_date`)` | `translated` | `2a972308d04e49c41fabe1d240cd8d4398a53fa7264ffd588cedde7e0c76c9b9` | -| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeUri::test` | `ProtobufTests.SerializeUri` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:226` | `` | `` | `tests/compat/tests/structured_data.rs:1325 (`protobuf_serialize_uri`)` | `translated` | `1561f2747cba4be4f9ab5af31d08f2a24e199e2193b3fcabb7925d79f4d70a5e` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeBoolean::test` | `ProtobufTests.SerializeBoolean` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:36` | `` | `` | `tests/compat/tests/structured_data.rs:1164 (`protobuf_serialize_boolean`)` | `translated` | `06d71d5ad54dab8236458e6cf3c9893728d4a13c348441822f674164a285150b` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeInteger::test` | `ProtobufTests.SerializeInteger` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:52` | `` | `` | `tests/compat/tests/structured_data.rs:1176 (`protobuf_serialize_integer`)` | `translated` | `8a20e00e06a1a01a39c6cc3f1de100015abb0446ee07e42fbbfc89d4351d9f5b` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeReal::test` | `ProtobufTests.SerializeReal` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:74` | `` | `` | `tests/compat/tests/structured_data.rs:1189 (`protobuf_serialize_real`)` | `translated` | `4aae9af41d534a2c4755f40f9da4d7b780a4552b52c7816d0aa70f640d64cfd3` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeUUID::test` | `ProtobufTests.SerializeUUID` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:84` | `` | `` | `tests/compat/tests/structured_data.rs:1200 (`protobuf_serialize_uuid`)` | `translated` | `7fa09c08d627d04b66651d0f50cbf6a4373536315c121bab59f43b57c0cbf064` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeString::test` | `ProtobufTests.SerializeString` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:100` | `` | `` | `tests/compat/tests/structured_data.rs:1225 (`protobuf_serialize_string`)` | `translated` | `880195caac721a93349f902efb2615342d84eca86a64c8340dd314044d8a3ade` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeArray::test` | `ProtobufTests.SerializeArray` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:116` | `` | `` | `tests/compat/tests/structured_data.rs:1240 (`protobuf_serialize_array`)` | `translated` | `2bdfc891534aeafa4a0729f4f3ba34d9fb4cc0ea4e88c6ac1aab63224b95f230` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeMap::test` | `ProtobufTests.SerializeMap` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:137` | `` | `` | `tests/compat/tests/structured_data.rs:1255 (`protobuf_serialize_map`)` | `translated` | `d2a14b977d843249e2569a2287981ee9fc903c07cf19b5e3cd613c340725de51` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeNestedComposite::test` | `ProtobufTests.SerializeNestedComposite` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:158` | `` | `` | `tests/compat/tests/structured_data.rs:1270 (`protobuf_serialize_nested_composite`)` | `translated` | `bae0fbd2740466f84376f8f98ec4bf93143ce9cc7ad60cdd15907411280ff0a6` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.AutoDetectProtobuf::test` | `ProtobufTests.AutoDetectProtobuf` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:191` | `` | `` | `tests/compat/tests/structured_data.rs:1290 (`protobuf_auto_detect`)` | `translated` | `2c319b85ae1615fcb9c5804ac01bcb108c6ab235d51b971447fd2576054d8191` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeBinary::test` | `ProtobufTests.SerializeBinary` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:203` | `` | `` | `tests/compat/tests/structured_data.rs:1304 (`protobuf_serialize_binary`)` | `translated` | `f5b3aa5e551371f05d90f20f5552844c71e9abb337d33ed178e72297e5d7435d` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeDate::test` | `ProtobufTests.SerializeDate` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:214` | `` | `` | `tests/compat/tests/structured_data.rs:1315 (`protobuf_serialize_date`)` | `translated` | `2a972308d04e49c41fabe1d240cd8d4398a53fa7264ffd588cedde7e0c76c9b9` | +| `LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeUri::test` | `ProtobufTests.SerializeUri` | `` | `LibreMetaverse.Tests/ProtobufTests.cs:226` | `` | `` | `tests/compat/tests/structured_data.rs:1331 (`protobuf_serialize_uri`)` | `translated` | `1561f2747cba4be4f9ab5af31d08f2a24e199e2193b3fcabb7925d79f4d70a5e` | | `LibreMetaverse.Tests/QueryExperiencesOnParcelTests.cs::QueryExperiencesOnParcelTests.QueryExperiencesOnParcelAsync_HappyPath_ParsesAllowedMapAndBuildsExpectedQuery::test` | `QueryExperiencesOnParcelTests.QueryExperiencesOnParcelAsync_HappyPath_ParsesAllowedMapAndBuildsExpectedQuery` | `` | `LibreMetaverse.Tests/QueryExperiencesOnParcelTests.cs:66` | `` | `LibreMetaverse.Tests/TestHelpers/FakeGridClient.cs` | `tests/compat/tests/world_capability_semantics.rs:195 (`query_experiences_on_parcel_happy_path`)` | `translated` | `2571d3a4100face21268d7ca2401cc8468e711c03c808704aacc7a50006125d5` | | `LibreMetaverse.Tests/QueryExperiencesOnParcelTests.cs::QueryExperiencesOnParcelTests.QueryExperiencesOnParcelAsync_NoExperienceIds_OmitsExperiencesParam::test` | `QueryExperiencesOnParcelTests.QueryExperiencesOnParcelAsync_NoExperienceIds_OmitsExperiencesParam` | `` | `LibreMetaverse.Tests/QueryExperiencesOnParcelTests.cs:87` | `` | `LibreMetaverse.Tests/TestHelpers/FakeGridClient.cs` | `tests/compat/tests/world_capability_semantics.rs:227 (`query_experiences_on_parcel_no_ids_omits_parameter`)` | `translated` | `ddbaa53aa8c63262c2241588b4281c42bbb66efdecac95e297deb0fb81797455` | | `LibreMetaverse.Tests/QueryExperiencesOnParcelTests.cs::QueryExperiencesOnParcelTests.QueryExperiencesOnParcelAsync_NoCapability_ReturnsNullWithoutRequest::test` | `QueryExperiencesOnParcelTests.QueryExperiencesOnParcelAsync_NoCapability_ReturnsNullWithoutRequest` | `` | `LibreMetaverse.Tests/QueryExperiencesOnParcelTests.cs:103` | `` | `LibreMetaverse.Tests/TestHelpers/FakeGridClient.cs` | `tests/compat/tests/world_capability_semantics.rs:248 (`query_experiences_on_parcel_no_capability_returns_none_without_request`)` | `translated` | `5c6a6584fba8ddc66200367217f658d342fb2c26d6be9e49ccf3892bea420095` | @@ -1199,7 +1199,7 @@ Reviewed Rust tests live outside `generated_parity.rs` and carry a `parity-case` | `LibreMetaverse.Tests/TypeTests.cs::TypeTests.FloatsToTerseStrings::test` | `TypeTests.FloatsToTerseStrings` | `` | `LibreMetaverse.Tests/TypeTests.cs:223` | `` | `` | `tests/compat/tests/types_utilities.rs:194 (`floats_to_terse_strings`)` | `translated` | `ce34cdfe106d5dadfa82056e7aa7690d2da748c7e753b9d2a2ad682d86327def` | | `LibreMetaverse.Tests/TypeTests.cs::TypeTests.BitUnpacking::test` | `TypeTests.BitUnpacking` | `` | `LibreMetaverse.Tests/TypeTests.cs:252` | `` | `` | `tests/compat/tests/wire_semantics.rs:271 (`bit_unpacking`)` | `translated` | `741470d770a0a71853d84e26abaf927fc7dc385dedf0d7de87f63e7a22cb4dd7` | | `LibreMetaverse.Tests/TypeTests.cs::TypeTests.BitPacking::test` | `TypeTests.BitPacking` | `` | `LibreMetaverse.Tests/TypeTests.cs:279` | `` | `` | `tests/compat/tests/wire_semantics.rs:285 (`bit_packing`)` | `translated` | `fe3cac4216b588667d56b35496a803097dbc39f84c7a82fd95aa101836588948` | -| `LibreMetaverse.Tests/TypeTests.cs::TypeTests.LLSDTerseParsing::test` | `TypeTests.LLSDTerseParsing` | `` | `LibreMetaverse.Tests/TypeTests.cs:322` | `` | `` | `tests/compat/tests/structured_data.rs:1336 (`llsd_terse_parsing`)` | `translated` | `c5fcc05c15fa60c43cd40f5fc2b1349d9fbd1f5bb3537d8b04e91f37302e77f1` | +| `LibreMetaverse.Tests/TypeTests.cs::TypeTests.LLSDTerseParsing::test` | `TypeTests.LLSDTerseParsing` | `` | `LibreMetaverse.Tests/TypeTests.cs:322` | `` | `` | `tests/compat/tests/structured_data.rs:1342 (`llsd_terse_parsing`)` | `translated` | `c5fcc05c15fa60c43cd40f5fc2b1349d9fbd1f5bb3537d8b04e91f37302e77f1` | | `LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_AgentInventoryItem_SendsBareItemIdAndReturnsNewAsset::test` | `UploadThumbnailTests.UploadThumbnailAsync_AgentInventoryItem_SendsBareItemIdAndReturnsNewAsset` | `` | `LibreMetaverse.Tests/UploadThumbnailTests.cs:73` | `` | `LibreMetaverse.Tests/TestHelpers/FakeGridClient.cs` | `tests/compat/tests/asset_capability_semantics.rs:670 (`thumbnail_agent_item_sends_bare_item_id`)` | `translated` | `40ca874a37dade3bfbb391a2b4a75c684cfd7509b269286ccc14d747340d095d` | | `LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_TaskInventoryItem_SendsItemIdAndTaskId::test` | `UploadThumbnailTests.UploadThumbnailAsync_TaskInventoryItem_SendsItemIdAndTaskId` | `` | `LibreMetaverse.Tests/UploadThumbnailTests.cs:92` | `` | `LibreMetaverse.Tests/TestHelpers/FakeGridClient.cs` | `tests/compat/tests/asset_capability_semantics.rs:699 (`thumbnail_task_item_sends_item_and_task_ids`)` | `translated` | `dae80f9a7ba6222a651165f779c123d8472f88a17490e69a1112acc3cec6d108` | | `LibreMetaverse.Tests/UploadThumbnailTests.cs::UploadThumbnailTests.UploadThumbnailAsync_KnownLocalFolder_SendsCategoryId::test` | `UploadThumbnailTests.UploadThumbnailAsync_KnownLocalFolder_SendsCategoryId` | `` | `LibreMetaverse.Tests/UploadThumbnailTests.cs:110` | `` | `LibreMetaverse.Tests/TestHelpers/FakeGridClient.cs` | `tests/compat/tests/asset_capability_semantics.rs:725 (`thumbnail_known_local_folder_sends_category_id`)` | `translated` | `1ccca44bbead54fd5041c41fc6560478ba17f9e5d9bacff21096b254d2f526db` | @@ -1214,21 +1214,21 @@ Reviewed Rust tests live outside `generated_parity.rs` and carry a `parity-case` | `LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.Helpers_SplitAndFloatToTerseString::test` | `UtilUnitTests.Helpers_SplitAndFloatToTerseString` | `` | `LibreMetaverse.Tests/UtilUnitTests.cs:153` | `Utilities` | `` | `tests/compat/tests/types_utilities.rs:483 (`helpers_split_and_float_to_terse_string`)` | `translated` | `aa2c378f56cfd04d6d4cfa50cd3efafd2b2d479d681336d72fbb9d5ec5c363e6` | | `LibreMetaverse.Tests/UtilUnitTests.cs::UtilUnitTests.DisposalHelper_SafeDisposeAndUsing::test` | `UtilUnitTests.DisposalHelper_SafeDisposeAndUsing` | `` | `LibreMetaverse.Tests/UtilUnitTests.cs:163` | `Utilities` | `` | `tests/compat/tests/types_utilities.rs:520 (`disposal_helper_safe_dispose_and_using`)` | `translated` | `433ebbfeb69eeb7ceaac86c4b3637468152a1f5a9f4c12ea8d7a74e1cb0c4fec` | | `LibreMetaverse.Tests/UtilsConversionsTests.cs::UtilsConversionsTests.StringToBytes::test` | `UtilsConversionsTests.StringToBytes` | `` | `LibreMetaverse.Tests/UtilsConversionsTests.cs:35` | `Utilities` | `` | `tests/compat/tests/types_utilities.rs:663 (`string_to_bytes`)` | `translated` | `0bef42801dc2a50e132b05440424c44da54b53c853708ee2c0ec9799dbe0e8b2` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeLLSDSample::test` | `XmlSDTests.DeserializeLLSDSample` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:46` | `` | `` | `tests/compat/tests/structured_data.rs:1388 (`xml_deserialize_llsd_sample`)` | `translated` | `2495e7d5c414b59962f03282c51fe1c0d5de350b51c1bdfcee9ced7c32acbe4d` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeNoDTD::test` | `XmlSDTests.DeserializeNoDTD` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:159` | `` | `` | `tests/compat/tests/structured_data.rs:1440 (`xml_deserialize_no_dtd`)` | `translated` | `9bc25ce11695355a0b81622301db687495d414c9a293505f6d421f27ac24eb70` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeSillyPI::test` | `XmlSDTests.DeserializeSillyPI` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:184` | `` | `` | `tests/compat/tests/structured_data.rs:1456 (`xml_deserialize_silly_pi`)` | `translated` | `08f94779e33e1dff4bd88eb75c7e032947dfb75f9ac7b14432847e705f08176d` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeSillyPI_NoWhitespaceAfterPI::test` | `XmlSDTests.DeserializeSillyPI_NoWhitespaceAfterPI` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:207` | `` | `` | `tests/compat/tests/structured_data.rs:1473 (`xml_deserialize_silly_pi_no_whitespace_after_pi`)` | `translated` | `931129de5766458c7dc9ebefd5c1a8a8eeefd04715703c2997ff7da0d67f4bca` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeSillyPI_LowercasePI::test` | `XmlSDTests.DeserializeSillyPI_LowercasePI` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:229` | `` | `` | `tests/compat/tests/structured_data.rs:1482 (`xml_deserialize_silly_pi_lowercase_pi`)` | `translated` | `6a041c98c805419ed16b0caf3c249054be9f3f0fcc5884abd6b2ece2f23cf72d` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeReals::test` | `XmlSDTests.DeserializeReals` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:254` | `` | `` | `tests/compat/tests/structured_data.rs:1491 (`xml_deserialize_reals`)` | `translated` | `c1e1db52fb2c1f023376d40b795461767f573555ddd4b4372182345bf99164e0` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeStrings::test` | `XmlSDTests.DeserializeStrings` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:302` | `` | `` | `tests/compat/tests/structured_data.rs:1516 (`xml_deserialize_strings`)` | `translated` | `e2b49b6bfbaecd26243fbcaa93abe48a340f4203c88aad874f2aef83f169baed` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeIntegers::test` | `XmlSDTests.DeserializeIntegers` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:351` | `` | `` | `tests/compat/tests/structured_data.rs:1539 (`xml_deserialize_integers`)` | `translated` | `281793a4a04cecd610065a70d0d3b54ad62fd2d6cc614b476d07f69d83c3dcb9` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeUUID::test` | `XmlSDTests.DeserializeUUID` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:399` | `` | `` | `tests/compat/tests/structured_data.rs:1564 (`xml_deserialize_uuid`)` | `translated` | `bd2d0c2d4e583931174355724d948a0dbf6e79ec8fe907048f627b013a43bbea` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeDates::test` | `XmlSDTests.DeserializeDates` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:432` | `` | `` | `tests/compat/tests/structured_data.rs:1583 (`xml_deserialize_dates`)` | `translated` | `55507ef1bf9d7749d05c4941f645d37a48b4c9f16dda10b05a7e73673ee2be33` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeBoolean::test` | `XmlSDTests.DeserializeBoolean` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:472` | `` | `` | `tests/compat/tests/structured_data.rs:1604 (`xml_deserialize_boolean`)` | `translated` | `0f3d00c5f93b9f8d13938c77dd791dac4b8b093db926c164d92a3dd9bd38e741` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeBinary::test` | `XmlSDTests.DeserializeBinary` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:520` | `` | `` | `tests/compat/tests/structured_data.rs:1634 (`xml_deserialize_binary`)` | `translated` | `f6c61bed3a3e6d97b203006e42a6c7b7b131aee08712ad4974f34d2e221e3ff9` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeUndef::test` | `XmlSDTests.DeserializeUndef` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:565` | `` | `` | `tests/compat/tests/structured_data.rs:1655 (`xml_deserialize_undef`)` | `translated` | `45991c825d7d4f758c9650362df499e2f0afb079cc68f81973b5cd1eb704184c` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeURI::test` | `XmlSDTests.DeserializeURI` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:584` | `` | `` | `tests/compat/tests/structured_data.rs:1666 (`xml_deserialize_uri`)` | `translated` | `da322601509a3520b8ee2c303396f0d13a86a38727ce39ad043b9bc48d2302bf` | -| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeNestedContainers::test` | `XmlSDTests.DeserializeNestedContainers` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:619` | `` | `` | `tests/compat/tests/structured_data.rs:1685 (`xml_deserialize_nested_containers`)` | `translated` | `d0100e0e1f1de74a6060199f0cc7d4f94c745f073fadf8333b4eff51fd08af0a` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeLLSDSample::test` | `XmlSDTests.DeserializeLLSDSample` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:46` | `` | `` | `tests/compat/tests/structured_data.rs:1394 (`xml_deserialize_llsd_sample`)` | `translated` | `2495e7d5c414b59962f03282c51fe1c0d5de350b51c1bdfcee9ced7c32acbe4d` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeNoDTD::test` | `XmlSDTests.DeserializeNoDTD` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:159` | `` | `` | `tests/compat/tests/structured_data.rs:1446 (`xml_deserialize_no_dtd`)` | `translated` | `9bc25ce11695355a0b81622301db687495d414c9a293505f6d421f27ac24eb70` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeSillyPI::test` | `XmlSDTests.DeserializeSillyPI` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:184` | `` | `` | `tests/compat/tests/structured_data.rs:1462 (`xml_deserialize_silly_pi`)` | `translated` | `08f94779e33e1dff4bd88eb75c7e032947dfb75f9ac7b14432847e705f08176d` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeSillyPI_NoWhitespaceAfterPI::test` | `XmlSDTests.DeserializeSillyPI_NoWhitespaceAfterPI` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:207` | `` | `` | `tests/compat/tests/structured_data.rs:1479 (`xml_deserialize_silly_pi_no_whitespace_after_pi`)` | `translated` | `931129de5766458c7dc9ebefd5c1a8a8eeefd04715703c2997ff7da0d67f4bca` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeSillyPI_LowercasePI::test` | `XmlSDTests.DeserializeSillyPI_LowercasePI` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:229` | `` | `` | `tests/compat/tests/structured_data.rs:1488 (`xml_deserialize_silly_pi_lowercase_pi`)` | `translated` | `6a041c98c805419ed16b0caf3c249054be9f3f0fcc5884abd6b2ece2f23cf72d` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeReals::test` | `XmlSDTests.DeserializeReals` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:254` | `` | `` | `tests/compat/tests/structured_data.rs:1497 (`xml_deserialize_reals`)` | `translated` | `c1e1db52fb2c1f023376d40b795461767f573555ddd4b4372182345bf99164e0` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeStrings::test` | `XmlSDTests.DeserializeStrings` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:302` | `` | `` | `tests/compat/tests/structured_data.rs:1522 (`xml_deserialize_strings`)` | `translated` | `e2b49b6bfbaecd26243fbcaa93abe48a340f4203c88aad874f2aef83f169baed` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeIntegers::test` | `XmlSDTests.DeserializeIntegers` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:351` | `` | `` | `tests/compat/tests/structured_data.rs:1545 (`xml_deserialize_integers`)` | `translated` | `281793a4a04cecd610065a70d0d3b54ad62fd2d6cc614b476d07f69d83c3dcb9` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeUUID::test` | `XmlSDTests.DeserializeUUID` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:399` | `` | `` | `tests/compat/tests/structured_data.rs:1570 (`xml_deserialize_uuid`)` | `translated` | `bd2d0c2d4e583931174355724d948a0dbf6e79ec8fe907048f627b013a43bbea` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeDates::test` | `XmlSDTests.DeserializeDates` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:432` | `` | `` | `tests/compat/tests/structured_data.rs:1589 (`xml_deserialize_dates`)` | `translated` | `55507ef1bf9d7749d05c4941f645d37a48b4c9f16dda10b05a7e73673ee2be33` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeBoolean::test` | `XmlSDTests.DeserializeBoolean` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:472` | `` | `` | `tests/compat/tests/structured_data.rs:1610 (`xml_deserialize_boolean`)` | `translated` | `0f3d00c5f93b9f8d13938c77dd791dac4b8b093db926c164d92a3dd9bd38e741` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeBinary::test` | `XmlSDTests.DeserializeBinary` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:520` | `` | `` | `tests/compat/tests/structured_data.rs:1640 (`xml_deserialize_binary`)` | `translated` | `f6c61bed3a3e6d97b203006e42a6c7b7b131aee08712ad4974f34d2e221e3ff9` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeUndef::test` | `XmlSDTests.DeserializeUndef` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:565` | `` | `` | `tests/compat/tests/structured_data.rs:1661 (`xml_deserialize_undef`)` | `translated` | `45991c825d7d4f758c9650362df499e2f0afb079cc68f81973b5cd1eb704184c` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeURI::test` | `XmlSDTests.DeserializeURI` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:584` | `` | `` | `tests/compat/tests/structured_data.rs:1672 (`xml_deserialize_uri`)` | `translated` | `da322601509a3520b8ee2c303396f0d13a86a38727ce39ad043b9bc48d2302bf` | +| `LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeNestedContainers::test` | `XmlSDTests.DeserializeNestedContainers` | `` | `LibreMetaverse.Tests/XmlLLSDTests.cs:619` | `` | `` | `tests/compat/tests/structured_data.rs:1691 (`xml_deserialize_nested_containers`)` | `translated` | `d0100e0e1f1de74a6060199f0cc7d4f94c745f073fadf8333b4eff51fd08af0a` | | `LibreMetaverse.Rendering.Tests/Avatar/AvatarBoneMathTests.cs::AvatarBoneMathTests.BuildBoneWorldMatrices_UnitScale_MatchesNaiveMatrixChain::test` | `AvatarBoneMathTests.BuildBoneWorldMatrices_UnitScale_MatchesNaiveMatrixChain` | `` | `LibreMetaverse.Rendering.Tests/Avatar/AvatarBoneMathTests.cs:37` | `` | `` | `tests/compat/tests/imaging_meshing_semantics.rs:218 (`reviewed_avatarbonemathtests_buildboneworldmatrices_unitscale_matchesnaivematrixchain`)` | `translated` | `32ea442e98ebfe42238424274aefa960d9bac9a5048c4c971b315b712f870291` | | `LibreMetaverse.Rendering.Tests/Avatar/AvatarBoneMathTests.cs::AvatarBoneMathTests.BuildBoneWorldMatrices_AnisotropicParentScale_OffsetsChildPositionButNotChildScale::test` | `AvatarBoneMathTests.BuildBoneWorldMatrices_AnisotropicParentScale_OffsetsChildPositionButNotChildScale` | `` | `LibreMetaverse.Rendering.Tests/Avatar/AvatarBoneMathTests.cs:66` | `` | `` | `tests/compat/tests/imaging_meshing_semantics.rs:263 (`reviewed_avatarbonemathtests_buildboneworldmatrices_anisotropicparentscale_offsetschildpositionbutnotchildscale`)` | `translated` | `c82d9c6df0612703729e75ec955e4ef90651bb290d3daebe8d8bed7bba8891a3` | | `LibreMetaverse.Rendering.Tests/MeshFoundry/MeshFoundryTests.cs::MeshFoundryTests.GenerateSimpleMesh_Box_ReturnsNonNull::test` | `MeshFoundryTests.GenerateSimpleMesh_Box_ReturnsNonNull` | `` | `LibreMetaverse.Rendering.Tests/MeshFoundry/MeshFoundryTests.cs:125` | `` | `` | `tests/compat/tests/imaging_meshing_semantics.rs:311 (`reviewed_meshfoundrytests_generatesimplemesh_box_returnsnonnull`)` | `translated` | `cc5f4d8a21dd21e23e21c6372a4b21e100bffb0fc2a6b9a745d4283c1b05286d` | diff --git a/tests/compat/tests/structured_data.rs b/tests/compat/tests/structured_data.rs index 3bafed6..fbe74d6 100644 --- a/tests/compat/tests/structured_data.rs +++ b/tests/compat/tests/structured_data.rs @@ -17,7 +17,7 @@ use libremetaverse_compat_tests::{assert_bytes_eq, assert_close}; use libremetaverse_structured_data::{OSD, OSDParser, OSDType}; use libremetaverse_types::compat::{StringReader, Uri, Utf16CodeUnit}; use libremetaverse_types::{UUID, Utils}; -use std::io::{Cursor, Read, Write}; +use std::io::{Cursor, Read, Seek, SeekFrom, Write}; use std::sync::{Arc, Mutex}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -173,6 +173,12 @@ impl Write for SharedCursor { } } +impl Seek for SharedCursor { + fn seek(&mut self, position: SeekFrom) -> std::io::Result { + self.0.lock().expect("cursor lock").seek(position) + } +} + const BINARY_STRING_CONTENT: &[u8] = b"testing a simple binary conversion for this string\n\r"; const BINARY_NESTED_VALUE: &[u8] = &[ 0x5b, 0, 0, 0, 3, 0x7b, 0, 0, 0, 2, 0x6b, 0, 0, 0, 4, b't', b'e', b's', b't', 0x73, 0, 0, 0, 4, diff --git a/tests/red-suite-baseline.json b/tests/red-suite-baseline.json index 91630cb..9eb0d12 100644 --- a/tests/red-suite-baseline.json +++ b/tests/red-suite-baseline.json @@ -12,6 +12,32 @@ }, "allowed_parity_passes": [ "LibreMetaverse.Tests/AppearanceManagerTests.cs::AppearanceManagerTests.BAKED_TEXTURE_COUNT_Is11::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeArray::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeBool::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeDateTime::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeDictionary::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeInteger::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeLLSDBinary::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeNestedComposite::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeReal::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeString::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeURI::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeUUID::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeUndef::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.HelperFunctions::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeArray::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeBool::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeDateTime::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeDictionary::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeInteger::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeLLSDBinary::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeLongMessage::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeNestedComposite::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeReal::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeString::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeURI::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeUUID::test", + "LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeUndef::test", "LibreMetaverse.Tests/MarketplaceFolderClassifierTests.cs::MarketplaceFolderClassifierTests.ValidateListing_ValidFlags_AreBitmaskComposable::test", "LibreMetaverse.Tests/TypeTests.cs::TypeTests.Quaternions::test", "LibreMetaverse.Tests/TypeTests.cs::TypeTests.TestMatrix::test", @@ -20,5 +46,5 @@ "LibreMetaverse.Tests/TypeTests.cs::TypeTests.VectorCasting::test", "LibreMetaverse.Tests/UtilsConversionsTests.cs::UtilsConversionsTests.StringToBytes::test" ], - "support_passes": 73 + "support_passes": 76 } diff --git a/tests/upstream-tests.json b/tests/upstream-tests.json index 5af05cb..16b7684 100644 --- a/tests/upstream-tests.json +++ b/tests/upstream-tests.json @@ -2544,7 +2544,7 @@ "rust_body_sha256": "139e85573692ac97b9e70fd5ba48db5561f091fb559f5149820d1ea0e2ab2643", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 183, + "rust_line": 189, "rust_test": "binary_helper_functions", "semantic_review": "reviewed" }, @@ -2563,7 +2563,7 @@ "rust_body_sha256": "e199ef859542e5a47d6a25fe948b8c2f33d28f60096960a71b4740f3ebc653a5", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 219, + "rust_line": 225, "rust_test": "binary_deserialize_undef", "semantic_review": "reviewed" }, @@ -2582,7 +2582,7 @@ "rust_body_sha256": "1fc7e8fefec20550e603849598e045e508e4bec0f9d2cf0cb30306316189be7a", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 227, + "rust_line": 233, "rust_test": "binary_serialize_undef", "semantic_review": "reviewed" }, @@ -2601,7 +2601,7 @@ "rust_body_sha256": "0679d5f3999f3632a999d94c83d7ddcf5566dcac576b70f1d4855c832857c40c", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 235, + "rust_line": 241, "rust_test": "binary_deserialize_bool", "semantic_review": "reviewed" }, @@ -2620,7 +2620,7 @@ "rust_body_sha256": "530592920bd884c13f2aba77d73a57a3fe85484f080510d0c63ed4f6aa0a627c", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 246, + "rust_line": 252, "rust_test": "binary_serialize_bool", "semantic_review": "reviewed" }, @@ -2639,7 +2639,7 @@ "rust_body_sha256": "95b87ef2efbbb88ad18b66a17a66d5ab12afc62f95674cc0f1bf5fd054981474", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 257, + "rust_line": 263, "rust_test": "binary_deserialize_integer", "semantic_review": "reviewed" }, @@ -2658,7 +2658,7 @@ "rust_body_sha256": "d2dfc7cd3d1c919325685fda81531b06a67019313ad7dc8526c42fd1a3ebc2d3", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 269, + "rust_line": 275, "rust_test": "binary_serialize_integer", "semantic_review": "reviewed" }, @@ -2677,7 +2677,7 @@ "rust_body_sha256": "a7b75694ad7d76829d2f4b8295916ffcbf9afa423edcd32bdfe20c97cd44e95e", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 288, + "rust_line": 294, "rust_test": "binary_deserialize_real", "semantic_review": "reviewed" }, @@ -2696,7 +2696,7 @@ "rust_body_sha256": "ef8b51033c9ff0fff3c38a44dcb4839713a0e3f5109131837e92f35b070229ea", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 298, + "rust_line": 304, "rust_test": "binary_serialize_real", "semantic_review": "reviewed" }, @@ -2715,7 +2715,7 @@ "rust_body_sha256": "f6a7b4ce58945642da77b7aef5240e78d447b5c70f5ec64d7aa8712680c584cb", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 316, + "rust_line": 322, "rust_test": "binary_deserialize_uuid", "semantic_review": "reviewed" }, @@ -2734,7 +2734,7 @@ "rust_body_sha256": "1652f4e3bd787d24ee27d6baeaeebeb53813820186d064dab34b9a9251e1bd4b", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 332, + "rust_line": 338, "rust_test": "binary_serialize_uuid", "semantic_review": "reviewed" }, @@ -2753,7 +2753,7 @@ "rust_body_sha256": "c20517efaf79996f3da242d53729023f7d4f98541aaf1cdf5371c9f83b8358eb", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 352, + "rust_line": 358, "rust_test": "binary_deserialize_llsd_binary", "semantic_review": "reviewed" }, @@ -2772,7 +2772,7 @@ "rust_body_sha256": "6f53ecc367aa17486200794e48d43c2a09da15693424e60b18486674b2b4e01b", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 362, + "rust_line": 368, "rust_test": "binary_serialize_llsd_binary", "semantic_review": "reviewed" }, @@ -2791,7 +2791,7 @@ "rust_body_sha256": "2f84a2922837845118389e650311622e6d38ae39ffe28017e08a9c31fac95cf7", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 373, + "rust_line": 379, "rust_test": "binary_deserialize_string", "semantic_review": "reviewed" }, @@ -2810,7 +2810,7 @@ "rust_body_sha256": "9f60a79e30b67af73a6aaf139757b4141c51a1d977537f6ee6acec0e430f8f8a", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 387, + "rust_line": 393, "rust_test": "binary_serialize_string", "semantic_review": "reviewed" }, @@ -2829,7 +2829,7 @@ "rust_body_sha256": "fcbb39d35e3d997cec6fa418c8468b8cc5113aee3b4094733bdc2a8bcfdef774", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 411, + "rust_line": 417, "rust_test": "binary_deserialize_uri", "semantic_review": "reviewed" }, @@ -2848,7 +2848,7 @@ "rust_body_sha256": "7791ba2c8d1975b94452ca66c9426e5b8c82cff3028bf82dc833a4f4c1fda9c3", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 419, + "rust_line": 425, "rust_test": "binary_serialize_uri", "semantic_review": "reviewed" }, @@ -2867,7 +2867,7 @@ "rust_body_sha256": "928dba3314732e81ab0385e9f90715ea1f486d0439e6ae54465f274541fda828", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 427, + "rust_line": 433, "rust_test": "binary_deserialize_date_time", "semantic_review": "reviewed" }, @@ -2886,7 +2886,7 @@ "rust_body_sha256": "c8505f0186b42129c2a60d834c08056a5fd29530abbd780031cc52cb46ce0ec1", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 437, + "rust_line": 443, "rust_test": "binary_serialize_date_time", "semantic_review": "reviewed" }, @@ -2905,7 +2905,7 @@ "rust_body_sha256": "2d5bd7293bd6e2a053a89272478aa5a044d7d891a36c8a9b06ff62bf57131d7a", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 456, + "rust_line": 462, "rust_test": "binary_deserialize_array", "semantic_review": "reviewed" }, @@ -2924,7 +2924,7 @@ "rust_body_sha256": "31c98005d72b9d4cfec74a7949387500b09a06fe2af80a6468fc8a7eac91358c", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 476, + "rust_line": 482, "rust_test": "binary_serialize_array", "semantic_review": "reviewed" }, @@ -2943,7 +2943,7 @@ "rust_body_sha256": "e4202709eaec5425eb1e1606f6ce14b5603f98157a145eb34e772576e6d0782e", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 528, + "rust_line": 534, "rust_test": "binary_deserialize_dictionary", "semantic_review": "reviewed" }, @@ -2962,7 +2962,7 @@ "rust_body_sha256": "a2c7b4f4cc9675b34c967c850701e222f128708aeb1ee4a7ce1460f20c2d8743", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 542, + "rust_line": 548, "rust_test": "binary_serialize_dictionary", "semantic_review": "reviewed" }, @@ -2981,7 +2981,7 @@ "rust_body_sha256": "b6917b624c23e4e0e8b1b43eeb34df9bfe72722a42bf3b7ff8db8aefc58847f6", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 579, + "rust_line": 585, "rust_test": "binary_deserialize_nested_composite", "semantic_review": "reviewed" }, @@ -3000,7 +3000,7 @@ "rust_body_sha256": "1ab79a5e1f5a2ad1f2e12d1a7d0f5effbe2a3636196093e358dd938b0114a27e", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 587, + "rust_line": 593, "rust_test": "binary_serialize_nested_composite", "semantic_review": "reviewed" }, @@ -3019,7 +3019,7 @@ "rust_body_sha256": "1eded4163aa1f8f94d35ec697049c8f2c55b89b2a4a15d8ce82b272799bc566c", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 598, + "rust_line": 604, "rust_test": "binary_serialize_long_message", "semantic_review": "reviewed" }, @@ -8405,7 +8405,7 @@ "rust_body_sha256": "bd91e4bed26ff8b9957ea8396569e32872487427ce7d9ae5a5e11e30b8453050", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 622, + "rust_line": 628, "rust_test": "notation_helper_functions", "semantic_review": "reviewed" }, @@ -8424,7 +8424,7 @@ "rust_body_sha256": "353628582e66a2da6022afce3e086f1b89349c58932944adf7513a812c2d74d0", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 644, + "rust_line": 650, "rust_test": "notation_deserialize_undef", "semantic_review": "reviewed" }, @@ -8443,7 +8443,7 @@ "rust_body_sha256": "9fc19fc58b25ecc639cdd5406274b67d5e5ea64461e836f420c121a34a97e621", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 652, + "rust_line": 658, "rust_test": "notation_serialize_undef", "semantic_review": "reviewed" }, @@ -8462,7 +8462,7 @@ "rust_body_sha256": "d45a6a0a60f771a2797e3f071fbfd8d849f3ebe55be3bb872628e1fdc9016230", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 662, + "rust_line": 668, "rust_test": "notation_deserialize_boolean", "semantic_review": "reviewed" }, @@ -8481,7 +8481,7 @@ "rust_body_sha256": "f306cde45cb45483f66e69fb215075eefb6e0e1de75f5edee6465e1a2ec53cdf", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 677, + "rust_line": 683, "rust_test": "notation_serialize_boolean", "semantic_review": "reviewed" }, @@ -8500,7 +8500,7 @@ "rust_body_sha256": "c0f91154a5ba57161c74ad26161ceb86a8be11f14536a3c0c6f0f40c1bee0722", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 689, + "rust_line": 695, "rust_test": "notation_deserialize_integer", "semantic_review": "reviewed" }, @@ -8519,7 +8519,7 @@ "rust_body_sha256": "5855c008fa33ca9d766f97176fc562e0ce44b25b70a370fd3637e9f83ffc1606", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 700, + "rust_line": 706, "rust_test": "notation_serialize_integer", "semantic_review": "reviewed" }, @@ -8538,7 +8538,7 @@ "rust_body_sha256": "144c61e452a90f19ef9426a960dd7414dc504afe6c300ae62081444ded8d484b", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 724, + "rust_line": 730, "rust_test": "notation_deserialize_real", "semantic_review": "reviewed" }, @@ -8557,7 +8557,7 @@ "rust_body_sha256": "528c7b01de7daba1c255616beda4a52363d02b0b1e220b67f6cf258c78247cd6", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 740, + "rust_line": 746, "rust_test": "notation_serialize_real", "semantic_review": "reviewed" }, @@ -8576,7 +8576,7 @@ "rust_body_sha256": "a2228425187e555ac26975d5295c46484a0add9e6418bfdaf6d5e5370f42df9d", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 760, + "rust_line": 766, "rust_test": "notation_deserialize_uuid", "semantic_review": "reviewed" }, @@ -8595,7 +8595,7 @@ "rust_body_sha256": "26cdee8ce4c0889350ea9718cc676d0180730ef20200b03beec8248fd499c7a4", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 778, + "rust_line": 784, "rust_test": "notation_serialize_uuid", "semantic_review": "reviewed" }, @@ -8614,7 +8614,7 @@ "rust_body_sha256": "0bec6e4d609c3acd083b0e7e4c0588cb2fc3be1dcde3ed685866e559ec567e49", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 793, + "rust_line": 799, "rust_test": "notation_deserialize_string", "semantic_review": "reviewed" }, @@ -8633,7 +8633,7 @@ "rust_body_sha256": "b82ca6ca743c25ee126abad46d12b71a6fa5023a7fe78e9717253a8f2b78706c", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 815, + "rust_line": 821, "rust_test": "notation_serialize_string", "semantic_review": "reviewed" }, @@ -8652,7 +8652,7 @@ "rust_body_sha256": "0da999b5a1518e77cc5fd44b178e4ceaa7bc6520154768ca4271ca915893a3c6", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 843, + "rust_line": 849, "rust_test": "notation_deserialize_uri", "semantic_review": "reviewed" }, @@ -8671,7 +8671,7 @@ "rust_body_sha256": "0e557ff35c6f524b9c8fca19e8103ca6e9e9cdac6479ef454327e99faeab284f", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 864, + "rust_line": 870, "rust_test": "notation_serialize_uri", "semantic_review": "reviewed" }, @@ -8690,7 +8690,7 @@ "rust_body_sha256": "cdabecf1579ee010ced6276f98d3198818d09a12f5f86b311e9a7d096899100d", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 879, + "rust_line": 885, "rust_test": "notation_deserialize_date", "semantic_review": "reviewed" }, @@ -8709,7 +8709,7 @@ "rust_body_sha256": "ad0f5d1e09abd7b9ae509e027f5ff081a3db9f103aedd5f37788f085f03fffc9", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 888, + "rust_line": 894, "rust_test": "notation_serialize_date", "semantic_review": "reviewed" }, @@ -8728,7 +8728,7 @@ "rust_body_sha256": "1219e8c3ff726d7dde0f8ea2b1b3b7c6cdada428dcad0efd695f10f851d582df", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 908, + "rust_line": 914, "rust_test": "notation_serialize_binary", "semantic_review": "reviewed" }, @@ -8747,7 +8747,7 @@ "rust_body_sha256": "613d31c2a2d688d9d27077219c569dee13421da40a2edaccf1ca9a8b1373deec", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 919, + "rust_line": 925, "rust_test": "notation_deserialize_array", "semantic_review": "reviewed" }, @@ -8766,7 +8766,7 @@ "rust_body_sha256": "31671ebc34badd192afe695bc8e0bdfb91dd7d3730b19aa0c438d99ac81b90cb", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 959, + "rust_line": 965, "rust_test": "notation_serialize_array", "semantic_review": "reviewed" }, @@ -8785,7 +8785,7 @@ "rust_body_sha256": "9f5221ec1c1c23981f40b813659ea2a4268197bfe4bc583c3bdfe365bcf9ca0f", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 971, + "rust_line": 977, "rust_test": "notation_deserialize_map", "semantic_review": "reviewed" }, @@ -8804,7 +8804,7 @@ "rust_body_sha256": "9815d159688524140c6ac33d7be70339ac77e7e032134c63eca268c5d9ca13f5", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1037, + "rust_line": 1043, "rust_test": "notation_serialize_map", "semantic_review": "reviewed" }, @@ -8823,7 +8823,7 @@ "rust_body_sha256": "049b7be206118bab367c78269625245255c4635d283070b2e5cc98721746895d", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1053, + "rust_line": 1059, "rust_test": "notation_deserialize_real_world_examples", "semantic_review": "reviewed" }, @@ -8842,7 +8842,7 @@ "rust_body_sha256": "63e33a176f4f48ef31857ef6f29ee577708335c41b8126785b81c74201a37a12", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1126, + "rust_line": 1132, "rust_test": "notation_serialize_formatted_test", "semantic_review": "reviewed" }, @@ -9413,7 +9413,7 @@ "rust_body_sha256": "284a0d8233710b9c7b48683f243eeb8fe025165cafe49f1a653413f70cb94199", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1158, + "rust_line": 1164, "rust_test": "protobuf_serialize_boolean", "semantic_review": "reviewed" }, @@ -9432,7 +9432,7 @@ "rust_body_sha256": "b6b7e36491b30003f1fba7b65cd25afd024f272bd140b22558ffe02364159484", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1170, + "rust_line": 1176, "rust_test": "protobuf_serialize_integer", "semantic_review": "reviewed" }, @@ -9451,7 +9451,7 @@ "rust_body_sha256": "98b180adec329b027452c084fcffa01bab021e2db35e220329cb412da0b4b935", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1183, + "rust_line": 1189, "rust_test": "protobuf_serialize_real", "semantic_review": "reviewed" }, @@ -9470,7 +9470,7 @@ "rust_body_sha256": "1cf5f87e7069ff5d6833b9d4ad121a32deca862c4dcd1b477d5cadcff77c7711", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1194, + "rust_line": 1200, "rust_test": "protobuf_serialize_uuid", "semantic_review": "reviewed" }, @@ -9489,7 +9489,7 @@ "rust_body_sha256": "68de9e65ba21233b460ea3042099e1d56f7c7fbc056b4fab0a7496b417a0bb9d", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1219, + "rust_line": 1225, "rust_test": "protobuf_serialize_string", "semantic_review": "reviewed" }, @@ -9508,7 +9508,7 @@ "rust_body_sha256": "c84e5810cc6d0bebcb11bdfdbd964de35f9e91b3686e4d470aa9685a467e3fe6", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1234, + "rust_line": 1240, "rust_test": "protobuf_serialize_array", "semantic_review": "reviewed" }, @@ -9527,7 +9527,7 @@ "rust_body_sha256": "c49956529dd57be2348f4283c08faf95a19c0421db00bc7f0fb09783c8c9c28d", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1249, + "rust_line": 1255, "rust_test": "protobuf_serialize_map", "semantic_review": "reviewed" }, @@ -9546,7 +9546,7 @@ "rust_body_sha256": "5d609d99febaba898599fd6869ad4dc29117ebc4e23ecdff87109791aa695774", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1264, + "rust_line": 1270, "rust_test": "protobuf_serialize_nested_composite", "semantic_review": "reviewed" }, @@ -9565,7 +9565,7 @@ "rust_body_sha256": "7863c2beda231492049167980a8bfaa1221c68acce54434818b07294f1a67827", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1284, + "rust_line": 1290, "rust_test": "protobuf_auto_detect", "semantic_review": "reviewed" }, @@ -9584,7 +9584,7 @@ "rust_body_sha256": "55085cfc7037362434e5d74f5424681bc18e65869245b694e315647d2ae78e61", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1298, + "rust_line": 1304, "rust_test": "protobuf_serialize_binary", "semantic_review": "reviewed" }, @@ -9603,7 +9603,7 @@ "rust_body_sha256": "6a59fe76da6e1a9e199324cae49658be92aa89117254535fa6c8ca462d5cdbcb", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1309, + "rust_line": 1315, "rust_test": "protobuf_serialize_date", "semantic_review": "reviewed" }, @@ -9622,7 +9622,7 @@ "rust_body_sha256": "597ceaa8572c071ebf2f17bce35eef8d450cbaab41274d74dfd700d6726cdf6a", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1325, + "rust_line": 1331, "rust_test": "protobuf_serialize_uri", "semantic_review": "reviewed" }, @@ -24552,7 +24552,7 @@ "rust_body_sha256": "f4772ad9aa910866898dbb56fd432adbffe41858753f48a9f09b9a656623b4a1", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1336, + "rust_line": 1342, "rust_test": "llsd_terse_parsing", "semantic_review": "reviewed" }, @@ -24865,7 +24865,7 @@ "rust_body_sha256": "b4f02694cc643092911895f321a55ece3a3caa3585837eb80d9cb56280151fe6", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1388, + "rust_line": 1394, "rust_test": "xml_deserialize_llsd_sample", "semantic_review": "reviewed" }, @@ -24884,7 +24884,7 @@ "rust_body_sha256": "2d3d63b1305c34aac9a3f448e033d6e1207c78276a1d1e886f1f696fc485adb1", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1440, + "rust_line": 1446, "rust_test": "xml_deserialize_no_dtd", "semantic_review": "reviewed" }, @@ -24903,7 +24903,7 @@ "rust_body_sha256": "2cfa2b8fb6ac0f88d2a13879d058ed7ec13f39612cfef64f0c54a36234d3aa03", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1456, + "rust_line": 1462, "rust_test": "xml_deserialize_silly_pi", "semantic_review": "reviewed" }, @@ -24922,7 +24922,7 @@ "rust_body_sha256": "a20d46510d89f93a948388f6b0928e7254f6183edc87aceee341619bb3ea5a6d", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1473, + "rust_line": 1479, "rust_test": "xml_deserialize_silly_pi_no_whitespace_after_pi", "semantic_review": "reviewed" }, @@ -24941,7 +24941,7 @@ "rust_body_sha256": "24aa7f70d44eb5d6ffb456e96dd6398b001bcd2b3cafe08e7bcd73eb1472b5e9", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1482, + "rust_line": 1488, "rust_test": "xml_deserialize_silly_pi_lowercase_pi", "semantic_review": "reviewed" }, @@ -24960,7 +24960,7 @@ "rust_body_sha256": "ba8c6bc66b53cd68cf79bf108c43193c89bcd778c59b5afc270ae622addb12f4", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1491, + "rust_line": 1497, "rust_test": "xml_deserialize_reals", "semantic_review": "reviewed" }, @@ -24979,7 +24979,7 @@ "rust_body_sha256": "752a5c129915f2c4b9eea232a4867d9367a38fbca57bbb4eb109a745ce7dbd97", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1516, + "rust_line": 1522, "rust_test": "xml_deserialize_strings", "semantic_review": "reviewed" }, @@ -24998,7 +24998,7 @@ "rust_body_sha256": "aa25dc721c43e7354210b01e130b11596143ffb3ad15bad00c912f976b7bffab", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1539, + "rust_line": 1545, "rust_test": "xml_deserialize_integers", "semantic_review": "reviewed" }, @@ -25017,7 +25017,7 @@ "rust_body_sha256": "4dc2aa4995dcd6432a4a84181f4f22602bceb2f595e2600835433d7ca90fdd86", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1564, + "rust_line": 1570, "rust_test": "xml_deserialize_uuid", "semantic_review": "reviewed" }, @@ -25036,7 +25036,7 @@ "rust_body_sha256": "eb732d2695cbf250e42ddc35d27b62cedd9b199de3735197feed761f8c7e9299", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1583, + "rust_line": 1589, "rust_test": "xml_deserialize_dates", "semantic_review": "reviewed" }, @@ -25055,7 +25055,7 @@ "rust_body_sha256": "b2365645c64e344b2678916913f9a0cfcec6fdc625e786acde1d82740bdcc74d", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1604, + "rust_line": 1610, "rust_test": "xml_deserialize_boolean", "semantic_review": "reviewed" }, @@ -25074,7 +25074,7 @@ "rust_body_sha256": "d8edb705b2fac3be9c959a7385a62b707cc0c7fb9057668cd8fddcad1243c335", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1634, + "rust_line": 1640, "rust_test": "xml_deserialize_binary", "semantic_review": "reviewed" }, @@ -25093,7 +25093,7 @@ "rust_body_sha256": "8d91606bc63f8f678780332e3b1267c7b929f41b0528ec46da4a558f2387e16d", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1655, + "rust_line": 1661, "rust_test": "xml_deserialize_undef", "semantic_review": "reviewed" }, @@ -25112,7 +25112,7 @@ "rust_body_sha256": "82d65f92f402fb40fa3b8e6f456dd69d5ba8e31be14a107282677c1ba7497aa6", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1666, + "rust_line": 1672, "rust_test": "xml_deserialize_uri", "semantic_review": "reviewed" }, @@ -25131,7 +25131,7 @@ "rust_body_sha256": "eb6ab912cae75aac71b4667ac9f289ef4a09f91c56722abe704eab7c26215b12", "status": "translated", "rust_file": "tests/compat/tests/structured_data.rs", - "rust_line": 1685, + "rust_line": 1691, "rust_test": "xml_deserialize_nested_containers", "semantic_review": "reviewed" }, diff --git a/tools/generate_api_shims.py b/tools/generate_api_shims.py index 5a75760..6faf75c 100644 --- a/tools/generate_api_shims.py +++ b/tools/generate_api_shims.py @@ -79,6 +79,32 @@ NATIVE_TYPES = { } NATIVE_MEMBER_BODIES = { + "M:LibreMetaverse.StructuredData.OSDParser.ConsumeBytes(System.IO.Stream,System.Int32)": + "crate::binary::consume_bytes(stream, consume_bytes)", + "M:LibreMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.Byte[])": + "crate::binary::deserialize_bytes(binary_data)", + "M:LibreMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.IO.Stream)": + "crate::binary::deserialize_stream(stream)", + "M:LibreMetaverse.StructuredData.OSDParser.FindByte(System.IO.Stream,System.Byte)": + "crate::binary::find_byte(stream, to_find)", + "M:LibreMetaverse.StructuredData.OSDParser.FindString(System.IO.Stream,System.String)": + "crate::binary::find_string(stream, to_find)", + "M:LibreMetaverse.StructuredData.OSDParser.HostToNetworkIntBytes(System.Int32)": + "crate::binary::host_to_network_int_bytes(int_host_end)", + "M:LibreMetaverse.StructuredData.OSDParser.NetworkToHostDouble(System.Byte[])": + "crate::binary::network_to_host_double(binary_net_end)", + "M:LibreMetaverse.StructuredData.OSDParser.NetworkToHostInt(System.Byte[])": + "crate::binary::network_to_host_int(binary_net_end)", + "M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinary(LibreMetaverse.StructuredData.OSD)": + "crate::binary::serialize(osd)", + "M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinary(LibreMetaverse.StructuredData.OSD,System.Boolean)": + "crate::binary::serialize_with_header(osd, prepend_header)", + "M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinaryStream(LibreMetaverse.StructuredData.OSD)": + "crate::binary::serialize_stream(data)", + "M:LibreMetaverse.StructuredData.OSDParser.SerializeLLSDBinaryStream(LibreMetaverse.StructuredData.OSD,System.Boolean)": + "crate::binary::serialize_stream_with_header(data, prepend_header)", + "M:LibreMetaverse.StructuredData.OSDParser.SkipWhiteSpace(System.IO.Stream)": + "crate::binary::skip_whitespace(stream)", "M:LibreMetaverse.StructuredData.OSDParser.Deserialize(System.Byte[])": "crate::dispatch::deserialize_bytes(data)", "M:LibreMetaverse.StructuredData.OSDParser.Deserialize(System.IO.Stream)": diff --git a/tools/generate_rust_mapping.py b/tools/generate_rust_mapping.py index 912d467..cf25337 100644 --- a/tools/generate_rust_mapping.py +++ b/tools/generate_rust_mapping.py @@ -980,6 +980,7 @@ def validate_generated_shims() -> None: "not_implemented(", "NotImplemented::new(", "crate::byte_order::", + "crate::binary::", "crate::dispatch::", ) ):