@@ -1240,7 +1240,26 @@ fn singbox_xml_identity_matches(xml: &str) -> bool {
|
|||||||
}
|
}
|
||||||
declaration_seen = true;
|
declaration_seen = true;
|
||||||
}
|
}
|
||||||
Event::PI(_) | Event::DocType(_) | Event::GeneralRef(_) => return false,
|
Event::GeneralRef(reference) => {
|
||||||
|
// quick-xml emits escaped quotes (including our own WinSW XML)
|
||||||
|
// separately from text. Resolve only built-in/numeric XML entities;
|
||||||
|
// custom entities and DTDs remain forbidden.
|
||||||
|
let name = match std::str::from_utf8(reference.as_ref()) {
|
||||||
|
Ok(name) => name,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
let encoded = format!("&{name};");
|
||||||
|
let decoded = match unescape(&encoded) {
|
||||||
|
Ok(decoded) => decoded,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
if active_field.is_some() {
|
||||||
|
active_value.push_str(&decoded);
|
||||||
|
} else if depth == 0 || root_closed {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::PI(_) | Event::DocType(_) => return false,
|
||||||
Event::Eof => break,
|
Event::Eof => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -712,6 +712,42 @@ fn winsw_xml() -> &'static str {
|
|||||||
</service>"#
|
</service>"#
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn current_singbox_recognizes_the_native_installer_xml() {
|
||||||
|
let xml = proxywarden_lib::singbox_service::singbox_service_xml();
|
||||||
|
for xml in [
|
||||||
|
xml.to_owned(),
|
||||||
|
xml.replace(""", """),
|
||||||
|
xml.replace(""", """),
|
||||||
|
] {
|
||||||
|
let inventory = inventory_singbox_with_host(¤t_singbox_host_with_xml(&xml));
|
||||||
|
assert_eq!(
|
||||||
|
inventory.classification(),
|
||||||
|
ComponentClassification::ManagedCurrent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for entity in ["&unknown;", "&quot;", "�", "�"] {
|
||||||
|
let xml = xml.replace(""", entity);
|
||||||
|
let inventory = inventory_singbox_with_host(¤t_singbox_host_with_xml(&xml));
|
||||||
|
assert_ne!(
|
||||||
|
inventory.classification(),
|
||||||
|
ComponentClassification::ManagedCurrent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
#[test]
|
||||||
|
#[ignore = "read-only smoke test requiring an installed managed sing-box"]
|
||||||
|
fn installed_singbox_inventory_is_current() {
|
||||||
|
let inventory = proxywarden_lib::component_detection::inventory_singbox();
|
||||||
|
assert_eq!(
|
||||||
|
inventory.classification(),
|
||||||
|
ComponentClassification::ManagedCurrent,
|
||||||
|
"{inventory:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn current_singbox_host_with_xml(xml: &str) -> MockHost {
|
fn current_singbox_host_with_xml(xml: &str) -> MockHost {
|
||||||
MockHost::new()
|
MockHost::new()
|
||||||
.with_path(r"C:\Program Files\ProxyWarden\components\sing-box\sing-box.exe")
|
.with_path(r"C:\Program Files\ProxyWarden\components\sing-box\sing-box.exe")
|
||||||
|
|||||||
Reference in New Issue
Block a user