~aw/patches

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
2 2

[PATCH mygit v1 1/2] implement subtrees

Johann Galle
Details
Message ID
<20210322223344.6568-1-johann@qwertqwefsday.eu>
DKIM signature
pass
Download raw message
Patch: +42 -30
From: Johann150 <johann@qwertqwefsday.eu>

This shouldn't introduce path traversal bugs because we are only putting the
path into git and never into the file system. In bare repositories the files
would not even exist on disk (at least not under those names), so putting
the paths into the file system wouldn't work anyway.
---
 src/main.rs         | 70 ++++++++++++++++++++++++++-------------------
 templates/tree.html |  2 +-
 2 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 146e764..4490fb7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -290,8 +290,10 @@ async fn repo_refs(req: Request<()>) -> tide::Result {
struct RepoTreeTemplate<'a> {
    repo: &'a Repository,
    tree: Tree<'a>,
    path: &'a Path,
    spec: &'a str,
}

async fn repo_tree(req: Request<()>) -> tide::Result {
    // TODO handle subtrees
    let repo = repo_from_request(&req.param("repo_name")?)?;
@@ -310,6 +312,7 @@ async fn repo_tree(req: Request<()>) -> tide::Result {
    let tmpl = RepoTreeTemplate {
        repo: &repo,
        tree,
        path: Path::new(""),
        spec,
    };
    Ok(tmpl.into())
@@ -367,12 +370,13 @@ async fn repo_file(req: Request<()>) -> tide::Result {
    let spec = req.param("ref").ok().or_else(|| head.shorthand()).unwrap();
    let commit = repo.revparse_single(spec)?.peel_to_commit()?;
    let tree = commit.tree()?;
    let tree_entry = tree.get_name(req.param("object_name")?).unwrap();
    let path = Path::new(req.param("object_name")?);
    let tree_entry = tree.get_path(path).unwrap();
    // TODO make sure I am escaping html properly here
    // TODO allow disabling of syntax highlighting
    // TODO -- dont pull in memory, use iterators if possible
    let syntax_set = SyntaxSet::load_defaults_nonewlines();
    let extension = std::path::Path::new(tree_entry.name().unwrap())
    let extension = path
        .extension()
        .and_then(std::ffi::OsStr::to_str)
        .unwrap_or_default();
@@ -381,34 +385,42 @@ async fn repo_file(req: Request<()>) -> tide::Result {
        .unwrap_or_else(|| syntax_set.find_syntax_plain_text());
    let ts = ThemeSet::load_defaults();
    let theme = &ts.themes["InspiredGitHub"]; // TODO make customizable
    let tree_obj = tree_entry.to_object(&repo)?;
    if tree_obj.as_tree().is_some() {
        // TODO render tree
    }
    let file_string = str::from_utf8(tree_obj.as_blob().unwrap().content())?;
    let mut highlighter = syntect::easy::HighlightLines::new(&syntax_reference, &theme);
    let (mut output, bg) = syntect::html::start_highlighted_html_snippet(&theme);
    for (n, line) in syntect::util::LinesWithEndings::from(file_string).enumerate() {
        let regions = highlighter.highlight(line, &syntax_set);
        output.push_str(&format!(
            "<a href='#L{0}' id='L{0}' class='line'>{0}</a>",
            n + 1
        ));
        syntect::html::append_highlighted_html_for_styled_line(
            &regions[..],
            syntect::html::IncludeBackground::IfDifferent(bg),
            &mut output,
        );
    }
    output.push_str("</pre>\n");
    let tmpl = match tree_entry.to_object(&repo)?.into_tree() {
        Ok(tree) => RepoTreeTemplate {
            repo: &repo,
            tree,
            path,
            spec: &spec,
        }
        .into(),
        Err(tree_obj) => {
            let file_string = str::from_utf8(tree_obj.as_blob().unwrap().content())?;
            let mut highlighter = syntect::easy::HighlightLines::new(&syntax_reference, &theme);
            let (mut output, bg) = syntect::html::start_highlighted_html_snippet(&theme);
            for (n, line) in syntect::util::LinesWithEndings::from(file_string).enumerate() {
                let regions = highlighter.highlight(line, &syntax_set);
                output.push_str(&format!(
                    "<a href='#L{0}' id='L{0}' class='line'>{0}</a>",
                    n + 1
                ));
                syntect::html::append_highlighted_html_for_styled_line(
                    &regions[..],
                    syntect::html::IncludeBackground::IfDifferent(bg),
                    &mut output,
                );
            }
            output.push_str("</pre>\n");

    let tmpl = RepoFileTemplate {
        repo: &repo,
        tree_entry: &tree_entry,
        file_text: &output,
        spec: &spec,
            RepoFileTemplate {
                repo: &repo,
                tree_entry: &tree_entry,
                file_text: &output,
                spec: &spec,
            }
            .into()
        }
    };
    Ok(tmpl.into())
    Ok(tmpl)
}

mod filters {
@@ -490,7 +502,7 @@ async fn main() -> Result<(), std::io::Error> {
    app.at("/:repo_name/log/:ref").get(repo_log); // ref optional
    app.at("/:repo_name/tree").get(repo_tree);
    app.at("/:repo_name/tree/:ref").get(repo_tree);
    app.at("/:repo_name/tree/:ref/item/:object_name")
    app.at("/:repo_name/tree/:ref/item/*object_name")
        .get(repo_file);
    // Raw files, patch files
    app.listen(format!("[::]:{}", CONFIG.port)).await?;
diff --git a/templates/tree.html b/templates/tree.html
index 8e187f9..836e847 100644
--- a/templates/tree.html
+++ b/templates/tree.html
@@ -11,7 +11,7 @@
        {{ entry.filemode()|unix_perms }}
      </td>
      <td class="filename">
        <a href="/{{repo|repo_name|urlencode_strict}}/tree/{{ spec }}/item/{{entry.name().unwrap()}}">
        <a href="/{{repo|repo_name|urlencode_strict}}/tree/{{ spec }}/item/{{path.join(entry.name().unwrap()).to_string_lossy()}}">
        {{ entry.name().unwrap() }}{% if entry.to_object(repo).unwrap().as_tree().is_some() %}/{% endif %}</a>
      </td>
      <td class="filesize">
-- 
2.20.1

[PATCH mygit v1 2/2] run cargo fmt

Johann Galle
Details
Message ID
<20210322223344.6568-2-johann@qwertqwefsday.eu>
In-Reply-To
<20210322223344.6568-1-johann@qwertqwefsday.eu> (view parent)
DKIM signature
pass
Download raw message
Patch: +5 -4
From: Johann150 <johann@qwertqwefsday.eu>

---
 src/errorpage.rs | 7 ++++---
 src/main.rs      | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/errorpage.rs b/src/errorpage.rs
index dbfcba7..3df280f 100644
--- a/src/errorpage.rs
+++ b/src/errorpage.rs
@@ -12,17 +12,18 @@ struct ErrorTemplate {
pub struct ErrorToErrorpage;

#[async_trait::async_trait]
impl<State: Clone + Send + Sync + 'static> Middleware<State> for ErrorToErrorpage{
impl<State: Clone + Send + Sync + 'static> Middleware<State> for ErrorToErrorpage {
    async fn handle(&self, req: Request<State>, next: Next<'_, State>) -> tide::Result {
        let resource = req.url().path().to_string();
        let mut response = next.run(req).await;
        if let Some(err) = response.take_error() {
            let status = err.status();
            response = ErrorTemplate{
            response = ErrorTemplate {
                resource,
                status,
                message: err.into_inner().to_string(),
            }.into();
            }
            .into();
            response.set_status(status);
        }

diff --git a/src/main.rs b/src/main.rs
index 4490fb7..c78f8f1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -135,7 +135,7 @@ fn repo_from_request(repo_name: &str) -> Result<Repository, tide::Error> {
        .into_owned();
    if repo_name.contains("..") {
        // Prevent path traversal
        return Err(tide::Error::from_str(400, "Invalid name"))
        return Err(tide::Error::from_str(400, "Invalid name"));
    }
    let repo_path = Path::new(&CONFIG.projectroot).join(repo_name);
    Repository::open(repo_path).or_else(|_| {
-- 
2.20.1
Details
Message ID
<CA4BJABOSCZY.3MFZ3PUK0YIV@debian-alex>
In-Reply-To
<20210322223344.6568-1-johann@qwertqwefsday.eu> (view parent)
DKIM signature
fail
Download raw message
DKIM signature: fail
Thank you!
Reply to thread Export thread (mbox)