Skip to content

Commit de369c5

Browse files
authored
fix(rust/cbork): Modify decode_any function (#151)
* modify `decode_any` function * fix spelling * update tests
1 parent e182213 commit de369c5

File tree

2 files changed

+62
-114
lines changed

2 files changed

+62
-114
lines changed

rust/cbork-utils/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ workspace = true
1212

1313
[dependencies]
1414
minicbor = { version = "0.25.1", features = ["std"] }
15+
16+
[dev-dependencies]
17+
proptest = { version = "1.5.0" }
18+
# Potentially it could be replaced with using `proptest::property_test` attribute macro,
19+
# after this PR will be merged https://github.com/proptest-rs/proptest/pull/523
20+
test-strategy = "0.4.0"

rust/cbork-utils/src/decode_helper.rs

Lines changed: 56 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -74,163 +74,105 @@ pub fn decode_tag(d: &mut Decoder, from: &str) -> Result<Tag, decode::Error> {
7474
.map_err(|e| decode::Error::message(format!("Failed to decode tag in {from}: {e}")))
7575
}
7676

77-
/// Decode any in CDDL, only support basic datatype
77+
/// Decode any in CDDL (any CBOR type) and return its bytes.
7878
///
7979
/// # Errors
8080
///
8181
/// Error if the decoding fails.
82-
pub fn decode_any(d: &mut Decoder, from: &str) -> Result<Vec<u8>, decode::Error> {
83-
match d.datatype()? {
84-
minicbor::data::Type::String => {
85-
match decode_helper::<String, _>(d, &format!("{from} Any"), &mut ()) {
86-
Ok(i) => Ok(i.as_bytes().to_vec()),
87-
Err(e) => Err(e),
88-
}
89-
},
90-
minicbor::data::Type::U8 => {
91-
match decode_helper::<u8, _>(d, &format!("{from} Any"), &mut ()) {
92-
Ok(i) => Ok(i.to_be_bytes().to_vec()),
93-
Err(e) => Err(e),
94-
}
95-
},
96-
minicbor::data::Type::U16 => {
97-
match decode_helper::<u16, _>(d, &format!("{from} Any"), &mut ()) {
98-
Ok(i) => Ok(i.to_be_bytes().to_vec()),
99-
Err(e) => Err(e),
100-
}
101-
},
102-
minicbor::data::Type::U32 => {
103-
match decode_helper::<u32, _>(d, &format!("{from} Any"), &mut ()) {
104-
Ok(i) => Ok(i.to_be_bytes().to_vec()),
105-
Err(e) => Err(e),
106-
}
107-
},
108-
minicbor::data::Type::U64 => {
109-
match decode_helper::<u64, _>(d, &format!("{from} Any"), &mut ()) {
110-
Ok(i) => Ok(i.to_be_bytes().to_vec()),
111-
Err(e) => Err(e),
112-
}
113-
},
114-
minicbor::data::Type::I8 => {
115-
match decode_helper::<i8, _>(d, &format!("{from} Any"), &mut ()) {
116-
Ok(i) => Ok(i.to_be_bytes().to_vec()),
117-
Err(e) => Err(e),
118-
}
119-
},
120-
minicbor::data::Type::I16 => {
121-
match decode_helper::<i16, _>(d, &format!("{from} Any"), &mut ()) {
122-
Ok(i) => Ok(i.to_be_bytes().to_vec()),
123-
Err(e) => Err(e),
124-
}
125-
},
126-
minicbor::data::Type::I32 => {
127-
match decode_helper::<i32, _>(d, &format!("{from} Any"), &mut ()) {
128-
Ok(i) => Ok(i.to_be_bytes().to_vec()),
129-
Err(e) => Err(e),
130-
}
131-
},
132-
minicbor::data::Type::I64 => {
133-
match decode_helper::<i64, _>(d, &format!("{from} Any"), &mut ()) {
134-
Ok(i) => Ok(i.to_be_bytes().to_vec()),
135-
Err(e) => Err(e),
136-
}
137-
},
138-
minicbor::data::Type::Bytes => Ok(decode_bytes(d, &format!("{from} Any"))?),
139-
minicbor::data::Type::Array => {
140-
Ok(decode_array_len(d, &format!("{from} Any"))?
141-
.to_be_bytes()
142-
.to_vec())
143-
},
144-
_ => {
145-
Err(decode::Error::message(format!(
146-
"{from} Any, Data type not supported"
147-
)))
148-
},
149-
}
82+
pub fn decode_any<'d>(d: &mut Decoder<'d>, from: &str) -> Result<&'d [u8], decode::Error> {
83+
let start = d.position();
84+
d.skip()?;
85+
let end = d.position();
86+
let bytes = d
87+
.input()
88+
.get(start..end)
89+
.ok_or(decode::Error::message(format!(
90+
"Failed to get any CBOR bytes in {from}. Invalid CBOR bytes."
91+
)))?;
92+
Ok(bytes)
15093
}
15194

15295
#[cfg(test)]
15396
mod tests {
154-
15597
use minicbor::Encoder;
98+
use test_strategy::proptest;
15699

157100
use super::*;
158101

159-
#[test]
160-
fn test_decode_any_bytes() {
102+
#[proptest]
103+
fn test_decode_any_bytes(random_bytes: Vec<u8>) {
161104
let mut buf = Vec::new();
162105
let mut e = Encoder::new(&mut buf);
163-
e.bytes(&[1, 2, 3, 4]).expect("Error encoding bytes");
106+
e.bytes(&random_bytes).expect("Error encoding bytes");
164107

165108
let mut d = Decoder::new(&buf);
166-
let result = decode_any(&mut d, "test").expect("Error decoding bytes");
167-
assert_eq!(result, vec![1, 2, 3, 4]);
109+
let cbor_bytes = decode_any(&mut d, "test").expect("Error decoding bytes");
110+
111+
let result = decode_bytes(&mut Decoder::new(cbor_bytes), "test").unwrap();
112+
assert_eq!(result, random_bytes);
168113
}
169114

170-
#[test]
171-
fn test_decode_any_string() {
115+
#[proptest]
116+
fn test_decode_any_string(random_string: String) {
172117
let mut buf = Vec::new();
173118
let mut e = Encoder::new(&mut buf);
174-
e.str("hello").expect("Error encoding string");
119+
e.str(&random_string).expect("Error encoding string");
175120

176121
let mut d = Decoder::new(&buf);
177-
let result = decode_any(&mut d, "test").expect("Error decoding string");
178-
assert_eq!(result, b"hello".to_vec());
122+
let cbor_bytes = decode_any(&mut d, "test").expect("Error decoding string");
123+
124+
let result =
125+
decode_helper::<String, _>(&mut Decoder::new(cbor_bytes), "test", &mut ()).unwrap();
126+
assert_eq!(result, random_string);
179127
}
180128

181-
#[test]
182-
fn test_decode_any_array() {
129+
#[proptest]
130+
fn test_decode_any_array(random_array: Vec<u8>) {
183131
// The array should contain a supported type
184132
let mut buf = Vec::new();
185133
let mut e = Encoder::new(&mut buf);
186-
e.array(2).expect("Error encoding array");
187-
e.u8(1).expect("Error encoding u8");
188-
e.u8(2).expect("Error encoding u8");
134+
e.array(random_array.len() as u64)
135+
.expect("Error encoding array");
136+
for el in &random_array {
137+
e.u8(*el).expect("Error encoding u8");
138+
}
189139
let mut d = Decoder::new(&buf);
190-
let result = decode_any(&mut d, "test").expect("Error decoding array");
140+
let cbor_bytes = decode_any(&mut d, "test").expect("Error decoding array");
191141
// The decode of array is just a length of the array
192-
assert_eq!(
193-
u64::from_be_bytes(result.try_into().expect("Error converting bytes to u64")),
194-
2
195-
);
142+
let result = decode_array_len(&mut Decoder::new(cbor_bytes), "test").unwrap();
143+
assert_eq!(result, random_array.len() as u64);
196144
}
197145

198-
#[test]
199-
fn test_decode_any_u32() {
146+
#[proptest]
147+
fn test_decode_any_u32(random_u32: u32) {
200148
let mut buf = Vec::new();
201149
let mut e = Encoder::new(&mut buf);
202-
let num: u32 = 123_456_789;
203-
e.u32(num).expect("Error encoding u32");
150+
e.u32(random_u32).expect("Error encoding u32");
204151

205152
let mut d = Decoder::new(&buf);
206-
let result = decode_any(&mut d, "test").expect("Error decoding u32");
207-
assert_eq!(
208-
u32::from_be_bytes(result.try_into().expect("Error converting bytes to u32")),
209-
num
210-
);
153+
let cbor_bytes = decode_any(&mut d, "test").expect("Error decoding u32");
154+
155+
let result =
156+
decode_helper::<u32, _>(&mut Decoder::new(cbor_bytes), "test", &mut ()).unwrap();
157+
assert_eq!(result, random_u32);
211158
}
212159

213-
#[test]
214-
fn test_decode_any_i32() {
160+
#[proptest]
161+
fn test_decode_any_i32(random_i32: i32) {
215162
let mut buf = Vec::new();
216163
let mut e = Encoder::new(&mut buf);
217-
let num: i32 = -123_456_789;
218-
e.i32(num).expect("Error encoding i32");
164+
e.i32(random_i32).expect("Error encoding i32");
219165
let mut d = Decoder::new(&buf);
220-
let result = decode_any(&mut d, "test").expect("Error decoding i32");
221-
assert_eq!(
222-
i32::from_be_bytes(result.try_into().expect("Error converting bytes to i32")),
223-
num
224-
);
166+
let cbor_bytes = decode_any(&mut d, "test").expect("Error decoding i32");
167+
168+
let result =
169+
decode_helper::<i32, _>(&mut Decoder::new(cbor_bytes), "test", &mut ()).unwrap();
170+
assert_eq!(result, random_i32);
225171
}
226172

227173
#[test]
228-
fn test_decode_any_unsupported_type() {
229-
let mut buf = Vec::new();
230-
let mut e = Encoder::new(&mut buf);
231-
e.null().expect("Error encoding null"); // Encode a null type which is unsupported
232-
233-
let mut d = Decoder::new(&buf);
174+
fn test_decode_any_not_cbor() {
175+
let mut d = Decoder::new(&[]);
234176
let result = decode_any(&mut d, "test");
235177
// Should print out the error message with the location of the error
236178
assert!(result.is_err());

0 commit comments

Comments
 (0)