///|
/// A generic decoded BER value (X.690). Constructed values expose their
/// children; primitive values expose their raw content octets.
pub struct BerValue {
tag : BerTag
content : Bytes
children : Array[BerValue]?
} derive(Eq, @debug.Debug)
///|
pub fn BerValue::primitive(tag : BerTag, content : Bytes) -> BerValue {
{ tag, content, children: None }
}
///|
pub fn BerValue::constructed(
tag : BerTag,
children : Array[BerValue],
) -> BerValue {
{ tag, content: Bytes::new(0), children: Some(children) }
}
///|
pub fn BerValue::is_constructed(self : BerValue) -> Bool {
self.children is Some(_)
}
///|
pub fn BerValue::children_or_empty(self : BerValue) -> Array[BerValue] {
match self.children {
Some(children) => children
None => []
}
}
///|
/// A human-readable dump of the value tree; used by the `ber_dump` example
/// and debugging tooling.
pub fn BerValue::to_string(self : BerValue) -> String {
let sb = StringBuilder()
self.render(0, sb)
sb.to_string()
}
///|
fn BerValue::render(self : BerValue, depth : Int, sb : StringBuilder) -> Unit {
for _ in 0..
for child in children {
sb.write_string("\n")
child.render(depth + 1, sb)
}
None => {
let n = self.content.length()
if n > 0 {
let view : BytesView = self.content[:]
let shown = if n > 16 { view[:16] } else { view }
sb.write_string(": ")
sb.write_string(to_hex_lower(shown))
if n > 16 {
sb.write_string(" ... (\{n} bytes)")
}
}
}
}
}
///|
/// Limits enforced during BER decoding to protect against malformed or
/// malicious input (anti-DoS).
pub struct BerLimits {
max_length : Int
max_depth : Int
max_elements : Int
max_integer_bytes : Int
} derive(Eq, @debug.Debug)
///|
pub impl Default for BerLimits with fn default() {
{
max_length: 64 * 1024 * 1024,
max_depth: 64,
max_elements: 4096,
max_integer_bytes: 8,
}
}
///|
/// A tight limit set used by tests and defensive callers.
pub fn strict_limits() -> BerLimits {
{
max_length: 1024 * 1024,
max_depth: 16,
max_elements: 256,
max_integer_bytes: 4,
}
}
///|
/// Errors produced by the BER encoder/decoder.
pub(all) suberror BerError {
Truncated
InvalidLength
InvalidTag
IndefinitePrimitive
MissingEoc
UnexpectedEoc
TooDeep
TooManyElements
IntegerTooLarge
LengthExceedsLimit(Int)
NotSingleValue
InvalidOid
} derive(Eq, @debug.Debug)