1use crate::warnln;
2
3use std::io::Write;
4#[derive(Clone, Default, Debug)]
9pub struct Config {
10 pub external_parse_config: ExternalEntityParseConfig,
11
12 #[cfg(feature = "experimental")]
13 pub targeted_parsing: Option<TargetedParsingConfig>,
14}
15
16#[derive(Clone, Default, Debug)]
17pub struct ExternalEntityParseConfig {
18 pub allow_ext_parse: bool,
19 pub ignore_ext_parse_warning: bool,
20 pub base_directory: Option<String>,
21}
22
23#[cfg(feature = "experimental")]
24#[derive(Clone, Debug)]
25pub struct TargetedParsingConfig {
26 pub tag_name: String,
27 pub parse_multiple: bool, }
29
30pub(crate) fn check_config(config: &Config) -> Result<(), Box<dyn std::error::Error>> {
31 match config {
32 Config {
33 external_parse_config:
34 ExternalEntityParseConfig {
35 allow_ext_parse: true,
36 ignore_ext_parse_warning: false,
37 ..
38 },
39 } => {
40 warnln!("The configuration `{:?}` allows external entity parsing which might expose the system to an XML External Entity (XXE) attack.\nThis crate makes no guarantees for security in this regard so make sure you trust your sources.\nVerification of all `.ent` files is strongly recommended.", config);
41
42 loop {
43 print!("Do you wish to proceed? [y/n]: ");
44 std::io::stdout().flush().unwrap();
45
46 let mut decision = String::new();
47 std::io::stdin().read_line(&mut decision).unwrap();
48
49 match decision.trim().to_lowercase().as_str() {
50 "y" | "Y" | "yes" => break,
51 "n" | "N" | "no" => {
52 return Err(nom::Err::Error(
53 "User decided to stop due to potential XXE attack",
54 )
55 .into());
56 }
57 _ => eprintln!("Invalid input. Please type 'y' or 'n'"),
58 }
59 }
60 }
61 Config {
62 external_parse_config:
63 ExternalEntityParseConfig {
64 allow_ext_parse: false,
65 ignore_ext_parse_warning: true,
66 ..
67 },
68 } => {
69 warnln!("The configuration `{:?}` may allow for unexpected parsing if `allow_ext_parse` is changed to true in the future", config);
70 }
71 _ => (),
72 }
73 Ok(())
74}