Merge main into #628

This commit is contained in:
bflatastic
2026-10-17 13:27:46 +07:00
20 changed files with 256 additions and 735 deletions
+2 -7
View File
@@ -64,14 +64,9 @@ impl Reader<'_> {
}
}
/// The network in blob `b`; `None` when it's truncated, out of range or not finite.
#[allow(dead_code, reason = "for readers that don't need the count of styled segments")]
pub(super) fn decode(b: &[u8]) -> Option<Network> {
decode_styled(b).map(|(net, _)| net)
}
/// The network in blob `b` and how many of its segments have a style id of their own (per-segment
/// stroke overrides, which the document model can't hold); `None` as for `decode`.
/// stroke overrides, which the document model can't hold); `None` when it's truncated, out of
/// range or not finite.
pub(super) fn decode_styled(b: &[u8]) -> Option<(Network, usize)> {
let mut r = Reader { b, pos: 0 };
let (nv, ns, nr) = (r.u32()? as usize, r.u32()? as usize, r.u32()? as usize);
+6 -6
View File
@@ -355,9 +355,9 @@ fn unreadable_conditions_skip_the_conditional() {
#[test]
fn damaged_network_blobs_never_panic() {
let good = square_blob();
assert!(network::decode(&good).is_some());
assert!(network::decode_styled(&good).is_some());
for cut in 0..good.len() {
assert!(network::decode(&good[..cut]).is_none(), "{cut}");
assert!(network::decode_styled(&good[..cut]).is_none(), "{cut}");
}
let mut r = Lcg(5);
for _ in 0..5000 {
@@ -366,7 +366,7 @@ fn damaged_network_blobs_never_panic() {
let i = (r.next() as usize) % m.len();
m[i] ^= 1 << (r.next() % 8);
}
if let Some(net) = network::decode(&m) {
if let Some((net, _)) = network::decode_styled(&m) {
assert!(net.segments.iter().all(|s| s.a < net.vertices.len() && s.b < net.vertices.len()));
assert!(net.regions.iter().flat_map(|r| &r.loops).flatten().all(|i| *i < net.segments.len()));
assert!(net.vertices.iter().all(|v| v.x.is_finite() && v.y.is_finite()));
@@ -375,13 +375,13 @@ fn damaged_network_blobs_never_panic() {
// Counts larger than the blob, and indices out of range.
let mut huge = vec![0xff; 12];
huge.extend_from_slice(&[0; 64]);
assert!(network::decode(&huge).is_none());
assert!(network::decode_styled(&huge).is_none());
let mut bad = arrow_blob();
bad[12 + 24 + 4..12 + 24 + 8].copy_from_slice(&7u32.to_le_bytes());
assert!(network::decode(&bad).is_none());
assert!(network::decode_styled(&bad).is_none());
for _ in 0..2000 {
let junk: Vec<u8> = (0..(r.next() % 120)).map(|_| r.next() as u8).collect();
let _ = network::decode(&junk);
let _ = network::decode_styled(&junk);
}
}