1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
/// Message does not start with the "VRT" magic family at all — not a
/// Veritate message.
BadMagic,
/// A Veritate message ("VRT" prefix) whose version byte this decoder does
/// not implement. `found` is the version digit in the magic; `supported`
/// is what this build understands. Guarantees a vN message can never be
/// silently misread as vM.
UnsupportedVersion { found: u8, supported: u8 },
/// The fixed header is structurally invalid for this version: an unknown
/// flag bit, or a reserved field that is not zero.
MalformedHeader(&'static str),
/// Buffer too short for the fixed header or a declared region.
Truncated,
/// An offset or length points outside the message buffer.
OutOfBounds,
/// List element index past the end of the list.
IndexOutOfBounds,
/// A string field holds invalid UTF-8.
BadUtf8,
/// The (inline) schema bytes are malformed or non-canonical.
BadSchema(String),
/// A value's type does not match the schema field type (write path),
/// or a typed getter was used on a differently-typed field (read path).
TypeMismatch { expected: String, got: String },
/// Writer and reader schema cannot be resolved (e.g. int narrowing).
Incompatible(String),
/// A value referenced a field ID that is not in the schema.
UnknownFieldId(u16),
/// The same field ID appeared twice in one struct value.
DuplicateField(u16),
/// The same key appeared twice in one map value.
DuplicateMapKey,
/// A `union` value or wire tag selected a variant index that does not exist.
BadUnionTag(u32),
/// A dense struct was encoded without one of its (mandatory) fields.
MissingField(u16),
/// The message's schema id does not match the resolver's writer schema
/// (or the inline schema bytes hash to something else).
SchemaIdMismatch { message: u128, expected: u128 },
/// dump_json needs an inline schema but the message was hash-only.
NoInlineSchema,
/// Recursion (nested structs/lists) exceeded the safety depth limit — the
/// message may contain an offset cycle or hostile nesting.
DepthLimitExceeded,
/// A bounded read exhausted its traversal budget: the message followed
/// offsets that would touch more bytes than the budget allows (an
/// amplification guard for untrusted input — see `Budget` / the wire spec §5.2).
TraversalBudgetExceeded,
/// Message would exceed the 4 GiB u32-offset limit.
MessageTooLarge,
/// A `.vertc` container file is malformed: bad magic/version, an index
/// pointing out of bounds, a misaligned or overlapping record, etc.
BadContainer(&'static str),
/// Internal invariant violation (a bug in this library).
Internal(&'static str),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::BadMagic => write!(f, "not a Veritate message (bad magic)"),
Error::UnsupportedVersion { found, supported } => write!(
f,
"unsupported Veritate wire version: message is v{}, this build implements v{}",
*found as char, *supported as char
),
Error::MalformedHeader(s) => write!(f, "malformed message header: {s}"),
Error::Truncated => write!(f, "message truncated"),
Error::OutOfBounds => write!(f, "offset out of bounds"),
Error::IndexOutOfBounds => write!(f, "list index out of bounds"),
Error::BadUtf8 => write!(f, "string field is not valid UTF-8"),
Error::BadSchema(s) => write!(f, "bad schema: {s}"),
Error::TypeMismatch { expected, got } => {
write!(f, "type mismatch: expected {expected}, got {got}")
}
Error::Incompatible(s) => write!(f, "schemas incompatible: {s}"),
Error::UnknownFieldId(id) => write!(f, "field id {id} not in schema"),
Error::DuplicateField(id) => write!(f, "field id {id} set twice"),
Error::DuplicateMapKey => write!(f, "the same map key was set twice"),
Error::BadUnionTag(t) => write!(f, "union tag {t} is not a valid variant index"),
Error::MissingField(id) => {
write!(f, "dense struct requires field id {id}, which was not set")
}
Error::SchemaIdMismatch { message, expected } => write!(
f,
"schema id mismatch: message has {message:#034x}, expected {expected:#034x}"
),
Error::NoInlineSchema => write!(f, "message carries no inline schema"),
Error::DepthLimitExceeded => {
write!(f, "nesting depth limit exceeded (possible offset cycle)")
}
Error::TraversalBudgetExceeded => {
write!(
f,
"traversal budget exceeded (possible amplification attack)"
)
}
Error::MessageTooLarge => write!(f, "message exceeds 4 GiB limit"),
Error::BadContainer(s) => write!(f, "bad container: {s}"),
Error::Internal(s) => write!(f, "internal error: {s}"),
}
}
}
impl std::error::Error for Error {}
pub type Result<T> = std::result::Result<T, Error>;