Skip to content

Commit

Permalink
Redirect on invalid UTF-8 in /p/
Browse files Browse the repository at this point in the history
Previously, uploading a paste with invalid UTF-8 and then viewing it
with the pretty URL would cause a panic.
With this change, it simply redirects to the raw URL.
  • Loading branch information
NoraCodes committed Feb 2, 2022
1 parent ea144a1 commit 5aafe25
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 9 deletions.
31 changes: 31 additions & 0 deletions src/models/maybe_redirect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use rocket::{
request::Request,
response::{Redirect, Responder, Result},
};
use rocket_dyn_templates::Template;

pub enum MaybeRedirect {
Redirect(Box<Redirect>),
Template(Box<Template>),
}

impl From<Redirect> for MaybeRedirect {
fn from(other: Redirect) -> Self {
Self::Redirect(Box::new(other))
}
}

impl From<Template> for MaybeRedirect {
fn from(other: Template) -> Self {
Self::Template(Box::new(other))
}
}

impl<'r, 'o: 'r> Responder<'r, 'o> for MaybeRedirect {
fn respond_to(self, req: &'r Request<'_>) -> Result<'o> {
match self {
Self::Template(t) => t.respond_to(req),
Self::Redirect(r) => r.respond_to(req),
}
}
}
1 change: 1 addition & 0 deletions src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod maybe_redirect;
pub mod paste_id;
pub mod pretty;
pub mod pretty_syntax;
6 changes: 3 additions & 3 deletions src/models/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ static SYNTAXES: &[u8] =
static THEMES: &[u8] =
include_bytes!("../../resources/themes/ayu_dark.tmTheme");

pub fn get_pretty_body(path: &Path, ext: &str) -> String {
pub fn get_pretty_body(path: &Path, ext: &str) -> std::io::Result<String> {
let ss: SyntaxSet = syntect::dumps::from_binary(SYNTAXES);

let mut theme_cursor = std::io::Cursor::new(THEMES);
let theme = ThemeSet::load_from_reader(&mut theme_cursor).unwrap();

let content = fs::read_to_string(path).unwrap();
let content = fs::read_to_string(path)?;
let syntax = ss
.find_syntax_by_token(ext)
.unwrap_or_else(|| ss.find_syntax_plain_text());

highlighted_html_for_string(&content, &ss, syntax, &theme)
Ok(highlighted_html_for_string(&content, &ss, syntax, &theme))
}
17 changes: 14 additions & 3 deletions src/routes/pretty_retrieve.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
use rocket::response::Redirect;
use rocket_dyn_templates::Template;

use std::collections::HashMap;
use std::io::ErrorKind::InvalidData;
use std::path::Path;

use crate::get_upload_dir;
use crate::models::maybe_redirect::MaybeRedirect;
use crate::models::paste_id::PasteId;
use crate::models::pretty::get_pretty_body;

#[get("/p/<id>", rank = 2)]
pub async fn pretty_retrieve(id: PasteId<'_>) -> Option<Template> {
pub async fn pretty_retrieve(id: PasteId<'_>) -> Option<MaybeRedirect> {
let filepath = Path::new(&get_upload_dir()).join(format!("{id}", id = id));

let contents = get_pretty_body(&filepath, &String::from("txt"));
let contents = match get_pretty_body(&filepath, &String::from("txt")) {
Ok(v) => v,
Err(e) if e.kind() == InvalidData => {
return Some(Redirect::to(format!("/{}", id)).into());
}
_ => {
return None;
}
};

let mut map = HashMap::new();
map.insert("title", id.to_string());
map.insert("body", contents);
let rendered = Template::render("pretty.html", &map);

match tree_magic::match_filepath("text/plain", &filepath) {
true => Some(rendered),
true => Some(rendered.into()),
false => None,
}
}
17 changes: 14 additions & 3 deletions src/routes/pretty_retrieve_ext.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
use rocket::response::Redirect;
use rocket_dyn_templates::Template;

use std::collections::HashMap;
use std::io::ErrorKind::InvalidData;
use std::path::Path;

use crate::get_upload_dir;
use crate::models::maybe_redirect::MaybeRedirect;
use crate::models::pretty::get_pretty_body;
use crate::models::pretty_syntax::PasteIdSyntax;

#[get("/p/<id_ext>", rank = 1)]
pub async fn pretty_retrieve_ext(
id_ext: PasteIdSyntax<'_>,
) -> Option<Template> {
) -> Option<MaybeRedirect> {
let id = id_ext.get_fname();
let ext = id_ext.get_ext();

let filepath = Path::new(&get_upload_dir()).join(id.to_string());

let contents = get_pretty_body(&filepath, &ext.to_string());
let contents = match get_pretty_body(&filepath, &ext.to_string()) {
Ok(v) => v,
Err(e) if e.kind() == InvalidData => {
return Some(Redirect::to(format!("/{}", id)).into());
}
_ => {
return None;
}
};

let mut map = HashMap::new();
map.insert("title", id.to_string());
map.insert("body", contents);
let rendered = Template::render("pretty.html", &map);

match tree_magic::match_filepath("text/plain", &filepath) {
true => Some(rendered),
true => Some(rendered.into()),
false => None,
}
}

0 comments on commit 5aafe25

Please sign in to comment.