Files
panda-rpki-oss/src/repository/sync/rrdp/parse_helpers.rs
Panda RPKI OSS Local 277cbca878
Some checks failed
ci / rust (push) Has been cancelled
ci / docker (push) Has been cancelled
初始化 Panda RPKI v0.1.0 开源候选版本
2026-09-09 18:01:15 +08:00

88 lines
2.8 KiB
Rust

// Shared XML, URI, and hash parsing helpers.
#[cfg(test)]
use snapshot_apply::apply_snapshot;
use snapshot_apply::{apply_snapshot_from_bufread, fetch_snapshot_into_tempfile};
fn parse_rrdp_xml(xml: &[u8]) -> Result<roxmltree::Document<'_>, RrdpError> {
if xml.iter().any(|&b| b > 0x7F) {
return Err(RrdpError::NotAscii);
}
let s = std::str::from_utf8(xml).map_err(|e| RrdpError::Xml(e.to_string()))?;
roxmltree::Document::parse(s).map_err(|e| RrdpError::Xml(e.to_string()))
}
fn validate_root_common(root: &roxmltree::Node<'_, '_>) -> Result<(), RrdpError> {
let ns = root.default_namespace().unwrap_or("").to_string();
if ns != RRDP_XMLNS {
return Err(RrdpError::InvalidNamespace(ns));
}
let version = root.attribute("version").unwrap_or("");
if version != "1" {
return Err(RrdpError::InvalidVersion(version.to_string()));
}
Ok(())
}
fn parse_uuid_attr(root: &roxmltree::Node<'_, '_>, name: &'static str) -> Result<Uuid, RrdpError> {
let s = root.attribute(name).unwrap_or("");
Uuid::parse_str(s).map_err(|_e| RrdpError::InvalidSessionId(s.to_string()))
}
fn parse_u64_attr(root: &roxmltree::Node<'_, '_>, name: &'static str) -> Result<u64, RrdpError> {
let s = root.attribute(name).unwrap_or("");
parse_u64_str(s)
}
fn parse_u64_str(s: &str) -> Result<u64, RrdpError> {
let v = s
.parse::<u64>()
.map_err(|_e| RrdpError::InvalidSerial(s.to_string()))?;
if v == 0 {
return Err(RrdpError::InvalidSerial(s.to_string()));
}
Ok(v)
}
fn parse_sha256_hex_impl(s: &str, invalid: fn(String) -> RrdpError) -> Result<[u8; 32], RrdpError> {
let bytes = hex::decode(s).map_err(|_e| invalid(s.to_string()))?;
if bytes.len() != 32 {
return Err(invalid(s.to_string()));
}
let mut out = [0u8; 32];
out.copy_from_slice(&bytes);
Ok(out)
}
fn parse_sha256_hex_snapshot(s: &str) -> Result<[u8; 32], RrdpError> {
parse_sha256_hex_impl(s, RrdpError::SnapshotHashInvalid)
}
fn parse_sha256_hex_delta_ref(s: &str) -> Result<[u8; 32], RrdpError> {
parse_sha256_hex_impl(s, RrdpError::DeltaRefHashInvalid)
}
fn parse_sha256_hex_delta_publish(s: &str) -> Result<[u8; 32], RrdpError> {
parse_sha256_hex_impl(s, RrdpError::DeltaPublishHashInvalid)
}
fn parse_sha256_hex_delta_withdraw(s: &str) -> Result<[u8; 32], RrdpError> {
parse_sha256_hex_impl(s, RrdpError::DeltaWithdrawHashInvalid)
}
fn collect_element_text(node: &roxmltree::Node<'_, '_>) -> Option<String> {
let mut out = String::new();
for child in node.children() {
if child.is_text() {
out.push_str(child.text().unwrap_or(""));
}
}
if out.is_empty() { None } else { Some(out) }
}
fn strip_all_ascii_whitespace(s: &str) -> String {
s.chars().filter(|c| !c.is_ascii_whitespace()).collect()
}