xml_sec/xmldsig/
extension.rs1use crate::document::{DocumentView, NodeIdentity, XmlDocumentError};
7use structured_asn1::memory::{MemoryError, Work};
8
9mod scalar;
10pub use scalar::*;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum BooleanAttribute {
15 Absent,
17 Value(bool),
19 Malformed,
21}
22
23#[derive(Debug, thiserror::Error)]
25pub enum ScalarError {
26 #[error(transparent)]
28 Document(#[from] XmlDocumentError),
29 #[error("XML scalar owner is not an element")]
31 NotElement,
32 #[error("XML scalar resource failure: {0}")]
34 Resource(MemoryError),
35}
36
37pub(super) fn charge_bytes<W: Work>(work: &W, bytes: usize) -> Result<(), ScalarError> {
38 let bytes =
39 u64::try_from(bytes).map_err(|_| ScalarError::Resource(MemoryError::WorkExceeded))?;
40 work.charge_work(bytes).map_err(ScalarError::Resource)
41}
42
43pub fn boolean_attribute<W: Work>(
50 view: DocumentView<'_>,
51 owner: NodeIdentity,
52 namespace: Option<&str>,
53 local_name: &str,
54 work: &W,
55) -> Result<BooleanAttribute, ScalarError> {
56 work.charge_work(1).map_err(ScalarError::Resource)?;
57 let node = view.resolve_node(owner)?;
58 if !node.is_element() {
59 return Err(ScalarError::NotElement);
60 }
61 for attribute in node.attributes() {
62 work.charge_work(1).map_err(ScalarError::Resource)?;
63 charge_bytes(work, attribute.name().len())?;
64 if attribute.name() != local_name {
65 continue;
66 }
67 if let Some(uri) = attribute.namespace() {
68 charge_bytes(work, uri.len())?;
69 }
70 if attribute.namespace() != namespace {
71 continue;
72 }
73 let value = attribute.value();
74 charge_bytes(work, value.len())?;
75 work.charge_work(5).map_err(ScalarError::Resource)?;
76 return Ok(match value.trim_matches([' ', '\t', '\r', '\n']) {
82 "true" | "1" => BooleanAttribute::Value(true),
83 "false" | "0" => BooleanAttribute::Value(false),
84 _ => BooleanAttribute::Malformed,
85 });
86 }
87 Ok(BooleanAttribute::Absent)
88}