use crate::error::EncodeError;
use std::fmt::Write as _;
pub fn between_obfuscate(payload: &str) -> String {
let mut result = String::with_capacity(payload.len() * 3);
for ch in payload.chars() {
if ch == '=' {
result.push_str(" BETWEEN 0 AND ");
} else if ch == '>' {
result.push_str(" NOT BETWEEN 0 AND ");
} else {
result.push(ch);
}
}
result
}
pub fn unmagic_quotes(payload: impl AsRef<[u8]>) -> Result<String, EncodeError> {
let payload = payload.as_ref();
let payload_str = std::str::from_utf8(payload).map_err(|_| EncodeError::InvalidUtf8)?;
Ok(payload_str.replace('\'', "%bf%27"))
}
pub fn percentage_prefix(payload: &str) -> String {
let mut out = String::with_capacity(payload.len() * 2);
for ch in payload.chars() {
let _ = write!(&mut out, "%{ch}");
}
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn between_obfuscate_basic() {
assert_eq!(between_obfuscate("id=1"), "id BETWEEN 0 AND 1");
assert_eq!(between_obfuscate("id>0"), "id NOT BETWEEN 0 AND 0");
}
#[test]
fn unmagic_quotes_basic() {
assert_eq!(unmagic_quotes("' OR 1=1--").unwrap(), "%bf%27 OR 1=1--");
}
#[test]
fn percentage_prefix_basic() {
assert_eq!(percentage_prefix("SELECT"), "%S%E%L%E%C%T");
}
}