Skip to content

Commit

Permalink
Centralise URL escaping. Also escape ?
Browse files Browse the repository at this point in the history
  • Loading branch information
nabijaczleweli committed Dec 13, 2021
1 parent 8bb613a commit b3d685e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
16 changes: 7 additions & 9 deletions src/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use iron::mime::{Mime, SubLevel as MimeSubLevel, TopLevel as MimeTopLevel};
use std::io::{self, ErrorKind as IoErrorKind, SeekFrom, Write, Error as IoError, Read, Seek};
use iron::{headers, status, method, mime, IronResult, Listening, Response, TypeMap, Request, Handler, Iron};
use self::super::util::{WwwAuthenticate, DisplayThree, CommaList, Spaces, Dav, url_path, file_hash, is_symlink, encode_str, encode_file, file_length,
hash_string, html_response, file_binary, client_mobile, percent_decode, file_icon_suffix, is_actually_file, is_descendant_of,
hash_string, html_response, file_binary, client_mobile, percent_decode, escape_specials, file_icon_suffix, is_actually_file, is_descendant_of,
response_encoding, detect_file_as_dir, encoding_extension, file_time_modified, file_time_modified_p, get_raw_fs_metadata,
human_readable_size, encode_tail_if_trimmed, is_nonexistent_descendant_of, USER_AGENT, ERROR_HTML, INDEX_EXTENSIONS, MIN_ENCODING_GAIN,
MAX_ENCODING_SIZE, MIN_ENCODING_SIZE, DAV_LEVEL_1_METHODS, DIRECTORY_LISTING_HTML, MOBILE_DIRECTORY_LISTING_HTML,
Expand Down Expand Up @@ -775,8 +775,7 @@ impl HttpHandler {
file_time_modified_p(req_p.parent().expect("Failed to get requested directory's parent directory"))
.strftime("%F %T")
.unwrap(),
up_path =
slash_idx.map(|i| &rel_noslash[0..i]).unwrap_or("").replace('%', "%25").replace('#', "%23").replace('[', "%5B").replace(']', "%5D"),
up_path = escape_specials(slash_idx.map(|i| &rel_noslash[0..i]).unwrap_or("")),
up_path_slash = if slash_idx.is_some() { "/" } else { "" })
};
let list_s = req_p.read_dir()
Expand Down Expand Up @@ -828,8 +827,8 @@ impl HttpHandler {
} else {
DisplayThree("", String::new(), "")
},
path = format!("/{}", relpath).replace("//", "/").replace('%', "%25").replace('#', "%23").replace('[', "%5B").replace(']', "%5D"),
fname = encode_tail_if_trimmed(fname.replace('%', "%25").replace('#', "%23").replace('[', "%5B").replace(']', "%5D")))
path = escape_specials(format!("/{}", relpath).replace("//", "/")),
fname = encode_tail_if_trimmed(escape_specials(&fname)))
});

self.handle_generated_response_encoding(req,
Expand Down Expand Up @@ -879,8 +878,7 @@ impl HttpHandler {
<td><a href=\"/{up_path}{up_path_slash}\">&nbsp;</a></td> \
<td><a href=\"/{up_path}{up_path_slash}\">&nbsp;</a></td></tr>",
file_time_modified_p(req_p.parent().expect("Failed to get requested directory's parent directory")).strftime("%F %T").unwrap(),
up_path =
slash_idx.map(|i| &rel_noslash[0..i]).unwrap_or("").replace('%', "%25").replace('#', "%23").replace('[', "%5B").replace(']', "%5D"),
up_path = escape_specials(slash_idx.map(|i| &rel_noslash[0..i]).unwrap_or("")),
up_path_slash = if slash_idx.is_some() { "/" } else { "" })
};

Expand Down Expand Up @@ -944,8 +942,8 @@ impl HttpHandler {
} else {
DisplayThree("", "", "")
},
path = format!("/{}", relpath).replace("//", "/").replace('%', "%25").replace('#', "%23").replace('[', "%5B").replace(']', "%5D"),
fname = encode_tail_if_trimmed(fname.replace('%', "%25").replace('#', "%23").replace('[', "%5B").replace(']', "%5D")))
path = escape_specials(format!("/{}", relpath).replace("//", "/")),
fname = encode_tail_if_trimmed(escape_specials(&fname)))
});

self.handle_generated_response_encoding(req,
Expand Down
17 changes: 17 additions & 0 deletions src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,23 @@ pub fn encode_tail_if_trimmed(mut s: String) -> String {
}
}

/// %-escape special characters in an URL
pub fn escape_specials<S: AsRef<str>>(s: S) -> String {
let s = s.as_ref();
let mut ret = Vec::with_capacity(s.len());
for &b in s.as_bytes() {
match b {
b'%' => ret.extend(b"%25"),
b'#' => ret.extend(b"%23"),
b'?' => ret.extend(b"%3F"),
b'[' => ret.extend(b"%5B"),
b']' => ret.extend(b"%5D"),
_ => ret.push(b),
}
}
unsafe { String::from_utf8_unchecked(ret) }
}

/// Check if the specified file is to be considered "binary".
///
/// Basically checks is a file is UTF-8.
Expand Down

0 comments on commit b3d685e

Please sign in to comment.