pub fn html_special_chars(input: &str) -> String {
let mut escaped = String::new();
for c in input.chars() {
match c {
'\'' => escaped.push_str("'"),
'"' => escaped.push_str("""),
'&' => escaped.push_str("&"),
'<' => escaped.push_str("<"),
'>' => escaped.push_str(">"),
c => escaped.push(c),
}
}
escaped
}
#[macro_export]
macro_rules! sanitize_like {
($pattern:tt) => { $crate::_sanitize_like($pattern, '\\') };
($pattern:tt, $escape:tt) => { $crate::_sanitize_like($pattern, $escape) };
}
#[doc(hidden)]
pub fn _sanitize_like<T: std::string::ToString>(pattern: T, escape_character: char) -> String {
let mut escaped_str = String::new();
for ch in pattern.to_string().chars() {
if ch == '%' || ch == '_' {
escaped_str.push(escape_character);
}
escaped_str.push(ch);
}
escaped_str
}
pub(crate) fn escape_string(s: &str) -> String {
let mut escaped = String::new();
escaped.push('\'');
for c in s.chars() {
if c == '\'' { escaped.push('\''); }
#[cfg(any(feature = "mysql", feature = "postgres"))]
if c == '\\' { escaped.push('\\'); }
escaped.push(c);
}
escaped.push('\'');
escaped
}
pub(crate) fn to_hex(bytes: &[u8]) -> String {
use lazy_static::lazy_static;
lazy_static! {
static ref LUT: Vec<String> = (0u8..=255).map(|n| format!("{:02X}", n)).collect();
}
bytes.iter().map(|&n| LUT.get(n as usize).unwrap().to_owned()).collect::<String>()
}
pub(crate) fn to_binary_literal(bytes: &[u8]) -> String {
let data = to_hex(bytes);
if cfg!(feature = "sqlite") || cfg!(feature = "mysql") {
format!("X'{}'", data)
} else {
format!("'\\x{}'", data)
}
}
#[doc(hidden)]
pub fn invalid_literal() -> &'static str {
#[cfg(debug_assertions)]
return "\x1b[31merror\x1b[0m: invalid literal\n";
#[cfg(not(debug_assertions))]
return "\x1b[33mwarning\x1b[0m: invalid literal\n";
}
#[cfg(test)]
mod tests {
#[test]
fn html_special_chars() {
assert_eq!(
super::html_special_chars(r#"<script type="text/javascript">alert('1')</script>"#),
r#"<script type="text/javascript">alert('1')</script>"#
);
}
#[test]
#[cfg(feature = "sqlite")]
#[cfg(not(all(feature = "sqlite", feature = "mysql", feature = "postgres")))]
fn escape_string() {
assert_eq!(super::escape_string("O'Reilly"), "'O''Reilly'");
assert_eq!(super::escape_string("O\\'Reilly"), "'O\\''Reilly'");
}
#[test]
#[cfg(feature = "mysql")]
#[cfg(not(all(feature = "sqlite", feature = "mysql", feature = "postgres")))]
fn escape_string() {
assert_eq!(super::escape_string("O'Reilly"), "'O''Reilly'");
assert_eq!(super::escape_string("O\\'Reilly"), "'O\\\\''Reilly'");
}
#[test]
#[cfg(feature = "postgres")]
#[cfg(not(all(feature = "sqlite", feature = "mysql", feature = "postgres")))]
fn escape_string() {
assert_eq!(super::escape_string("O'Reilly"), "'O''Reilly'");
assert_eq!(super::escape_string("O\\'Reilly"), "'O\\\\''Reilly'");
}
}