[FIX] Replaced broken URL decoding implementation from urldecode crate with custom implementation
@@ -10,7 +10,6 @@ use md5;
use std::cmp::Ordering;
use std::net::IpAddr;
use std::str::FromStr;
-use urldecode::decode;
use urlencoding::encode;
pub mod avltree;
@@ -358,8 +357,48 @@ fn iptonum(_: &Lua, ip: String) -> LuaResult<Option<String>> {
//////////////// DECODE URL ////////////////
+fn from_hex_digit(digit: u8) -> Option<u8> {
+ match digit {
+ b'0'..=b'9' => Some(digit - b'0'),
+ b'A'..=b'F' => Some(digit - b'A' + 10),
+ b'a'..=b'f' => Some(digit - b'a' + 10),
+ _ => None,
+ }
+}
+
+fn urldecode(input: String) -> Vec<u8> {
+ let mut out = Vec::new();
+ let mut bytes = input.as_bytes().iter().copied();
+ while let Some(b) = bytes.next() {
+ if b == b'%' {
+ if let Some(h) = bytes.next() {
+ if let Some(l) = bytes.next() {
+ match from_hex_digit(h).and_then(|hv| from_hex_digit(l).map(|lv| (hv, lv))) {
+ None => {
+ out.push(b);
+ out.push(h);
+ out.push(l);
+ }
+ Some((hv, lv)) => {
+ out.push(hv * 16 + lv);
+ }
+ }
+ } else {
+ out.push(b);
+ out.push(h);
+ }
+ } else {
+ out.push(b);
+ }
+ } else {
+ out.push(b);
+ }
+ }
+ out
+}
+
fn decodeurl(_: &Lua, url: String) -> LuaResult<Option<String>> {
- Ok(Some(decode(url)))
+ Ok(Some(String::from_utf8_lossy(&urldecode(url)).into_owned()))
}
fn encodeurl(_: &Lua, url: String) -> LuaResult<Option<String>> {
