From 930a44c10569495c22b6c346764cb76400cbd711 Mon Sep 17 00:00:00 2001 From: kaczmarczyck <43844792+kaczmarczyck@users.noreply.github.com> Date: Wed, 22 Sep 2021 10:33:08 +0200 Subject: [PATCH] Fix CBOR fuzzing timeout (#384) * early return for map and array comparison * leaner ordering assignment --- libraries/cbor/src/values.rs | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/libraries/cbor/src/values.rs b/libraries/cbor/src/values.rs index a2e0cab..253d67f 100644 --- a/libraries/cbor/src/values.rs +++ b/libraries/cbor/src/values.rs @@ -14,7 +14,6 @@ //! Types for expressing CBOR values. -use super::writer::write; use alloc::boxed::Box; use alloc::string::{String, ToString}; use alloc::vec::Vec; @@ -124,16 +123,34 @@ impl Ord for Value { (ByteString(b1), ByteString(b2)) => b1.len().cmp(&b2.len()).then(b1.cmp(b2)), (TextString(t1), TextString(t2)) => t1.len().cmp(&t2.len()).then(t1.cmp(t2)), (Array(a1), Array(a2)) if a1.len() != a2.len() => a1.len().cmp(&a2.len()), + (Array(a1), Array(a2)) => { + // Arrays of same length. + let mut ordering = Ordering::Equal; + for (e1, e2) in a1.iter().zip(a2.iter()) { + ordering = e1.cmp(e2); + if !matches!(ordering, Ordering::Equal) { + break; + } + } + ordering + } (Map(m1), Map(m2)) if m1.len() != m2.len() => m1.len().cmp(&m2.len()), + (Map(m1), Map(m2)) => { + // Maps of same length. + let mut ordering = Ordering::Equal; + for ((k1, v1), (k2, v2)) in m1.iter().zip(m2.iter()) { + ordering = k1.cmp(k2).then_with(|| v1.cmp(v2)); + if !matches!(ordering, Ordering::Equal) { + break; + } + } + ordering + } (Tag(t1, v1), Tag(t2, v2)) => t1.cmp(t2).then(v1.cmp(v2)), (Simple(s1), Simple(s2)) => s1.cmp(s2), - (v1, v2) => { - // This case could handle all of the above as well. Checking individually is faster. - let mut encoding1 = Vec::new(); - let _ = write(v1.clone(), &mut encoding1); - let mut encoding2 = Vec::new(); - let _ = write(v2.clone(), &mut encoding2); - encoding1.cmp(&encoding2) + (_, _) => { + // The case of different major types is caught above. + unreachable!(); } } }