xavier_internal/deserialize/
primitives.rs1use std::str::FromStr;
2use quick_xml::events::{BytesStart, Event};
3use quick_xml::Reader;
4use crate::deserialize::error::PError;
5use crate::deserialize::macro_trait::XmlDeserializable;
6use crate::deserialize::decode::{decode_xml, strip_cdata};
7
8trait Number {}
9impl Number for i8 {}
10impl Number for i16 {}
11impl Number for i32 {}
12impl Number for i64 {}
13impl Number for i128 {}
14impl Number for u8 {}
15impl Number for u16 {}
16impl Number for u32 {}
17impl Number for u64 {}
18impl Number for u128 {}
19impl Number for isize {}
20impl Number for usize {}
21impl Number for f32 {}
22impl Number for f64 {}
23
24fn contains_malicious_characters(input: &str) -> bool {
25 for c in input.chars() {
26 match c as u32 {
27 0x00..=0x08 | 0x0B | 0x0C | 0x0E..=0x1F | 0x7F => {
28 return true;
29 }
30 _ => {}
31 }
32 }
33 false
34}
35
36fn contains_malicious_entities(input: &str) -> bool {
37 let malicious_patterns = [
38 "�", "", "", "", "", "", "", "", "",
39 "", "", "", "", "", "", "", "", "",
40 "", "", "", "", "", "", "", "", "",
41 "", "", ""
42 ];
43
44 for pattern in &malicious_patterns {
45 if input.contains(pattern) {
46 return true;
47 }
48 }
49
50 false
51}
52
53impl XmlDeserializable for String {
54 fn from_xml(reader: &mut Reader<&[u8]>, _: Option<&BytesStart>, _tag_name: Option<&str>) -> Result<Option<Self>, PError> {
55 let mut current_value = String::new();
56 loop {
57 match reader.read_event() {
58 Err(error) => { return Err(PError::new(&format!("Error at position {}: {:?}", reader.buffer_position(), error))) },
59 Ok(Event::Eof) => { },
60 Ok(Event::Start(_)) => {},
61 Ok(Event::End(_)) => { return Ok(Some(current_value)); },
62 Ok(Event::Empty(_)) => { return Ok(None); },
63 Ok(Event::Comment(_)) => {},
64 Ok(Event::Text(event)) => {
65 let raw_string = String::from_utf8(event.to_vec())?;
66 if contains_malicious_entities(&raw_string) {
67 return Err(PError::new("Malicious XML entities detected"));
68 }
69 let cdata_stripped = strip_cdata(&raw_string);
70 let decoded = decode_xml(&cdata_stripped);
71
72 if contains_malicious_characters(&decoded) {
73 return Err(PError::new("Malicious characters detected in XML content"));
74 }
75
76 current_value.push_str(decoded.as_str());
77 },
78 Ok(Event::CData(event)) => {
79 let raw_string = String::from_utf8(event.to_vec())?;
80
81 if contains_malicious_entities(&raw_string) {
82 return Err(PError::new("Malicious XML entities detected"));
83 }
84
85 let decoded = decode_xml(&raw_string);
86
87 if contains_malicious_characters(&decoded) {
88 return Err(PError::new("Malicious characters detected in XML content"));
89 }
90
91 current_value.push_str(decoded.as_str());
92 },
93 Ok(Event::Decl(_)) => {},
94 Ok(Event::PI(_)) => {},
95 Ok(Event::DocType(_)) => {},
96 }
97 }
98 }
99}
100
101impl XmlDeserializable for char {
102 fn from_xml(reader: &mut Reader<&[u8]>, _: Option<&BytesStart>, _tag_name: Option<&str>) -> Result<Option<Self>, PError> {
103 loop {
104 match reader.read_event() {
105 Err(error) => { return Err(PError::new(&format!("Error at position {}: {:?}", reader.buffer_position(), error))) },
106 Ok(Event::Eof) => { },
107 Ok(Event::Start(_)) => {},
108 Ok(Event::End(_)) => { return Ok(None); },
109 Ok(Event::Empty(_)) => { return Ok(None); },
110 Ok(Event::Comment(_)) => {},
111 Ok(Event::Text(event)) => {
112 let raw_string = String::from_utf8(event.to_vec())?;
113 let trimmed = raw_string.trim();
114 if trimmed.is_empty() {
115 return Ok(Some(' '));
116 }
117 if raw_string.chars().count() > 1 {
118 return Err(PError::new("It's supposed to be a char and string was found!"));
119 }
120 return Ok(Some(trimmed.chars().next().ok_or_else(|| PError::new("Empty string cannot be parsed as char"))?));
121 },
122 Ok(Event::CData(event)) => {
123 let raw_string = String::from_utf8(event.to_vec())?;
124 let trimmed = raw_string.trim();
125 if trimmed.is_empty() {
126 return Ok(Some(' '));
127 }
128 return Ok(Some(trimmed.chars().next().ok_or_else(|| PError::new("Empty string cannot be parsed as char"))?));
129 },
130 Ok(Event::Decl(_)) => {},
131 Ok(Event::PI(_)) => {},
132 Ok(Event::DocType(_)) => {},
133 }
134 }
135 }
136}
137
138impl <T: FromStr + Number> XmlDeserializable for T
139 where PError: From<<T as FromStr>::Err> {
140 fn from_xml(reader: &mut Reader<&[u8]>, _: Option<&BytesStart>, _tag_name: Option<&str>) -> Result<Option<Self>, PError> {
141
142 loop {
143 match reader.read_event() {
144 Err(error) => { return Err(PError::new(&format!("Error at position {}: {:?}", reader.buffer_position(), error))) },
145 Ok(Event::Eof) => {},
146 Ok(Event::Start(_)) => {},
147 Ok(Event::End(_)) => { return Ok(Some("0".parse()?)); },
148 Ok(Event::Empty(_)) => { return Ok(Some("0".parse()?)); },
149 Ok(Event::Comment(_)) => {},
150 Ok(Event::Text(event)) => {
151 let raw_string = String::from_utf8(event.to_vec())?;
152 return if raw_string.is_empty() { Ok(Some("0".parse()?)) } else { Ok(Some(raw_string.parse()?)) };
153 },
154 Ok(Event::CData(event)) => {
155 let raw_string = String::from_utf8(event.to_vec())?;
156 return if raw_string.is_empty() { Ok(Some("0".parse()?)) } else { Ok(Some(raw_string.parse()?)) };
157 },
158 Ok(Event::Decl(_)) => {},
159 Ok(Event::PI(_)) => {},
160 Ok(Event::DocType(_)) => {},
161 }
162 }
163 }
164}
165
166
167impl XmlDeserializable for bool {
168 fn from_xml(reader: &mut Reader<&[u8]>, _: Option<&BytesStart>, _tag_name: Option<&str>) -> Result<Option<Self>, PError> {
169 loop {
170 match reader.read_event() {
171 Err(error) => { return Err(PError::new(&format!("Error at position {}: {:?}", reader.buffer_position(), error))) },
172 Ok(Event::Eof) => {},
173 Ok(Event::Start(_)) => {},
174 Ok(Event::End(_)) => { return Ok(None); },
175 Ok(Event::Empty(_)) => { return Ok(None); },
176 Ok(Event::Comment(_)) => {},
177 Ok(Event::Text(event)) => {
178 return Ok(Some(String::from_utf8(event.to_vec())?.parse()?))
179 },
180 Ok(Event::CData(event)) => {
181 return Ok(Some(String::from_utf8(event.to_vec())?.parse()?))
182 },
183 Ok(Event::Decl(_)) => {},
184 Ok(Event::PI(_)) => {},
185 Ok(Event::DocType(_)) => {},
186 }
187 }
188 }
189}