💾 Archived View for lists.flounder.online › patches › threads › 20210322223344.6568-1-johann@qwertqw… captured on 2022-04-28 at 19:24:32. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

[PATCH mygit v1 1/2] implement subtrees

[PATCH mygit v1 1/2] implement subtrees

From: johann@qwertqwefsday.eu

Date: Mon, 22 Mar 2021 23:33:43 +0100

Message-Id: 20210322223344.6568-1-johann@qwertqwefsday.eu

To: <~aw/patches@lists.sr.ht>

Cc: "Johann150" <johann@qwertqwefsday.eu>

Reply

Export

--------------------------------------

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

Re: [PATCH mygit v1 1/2] implement subtrees

From: alex@alexwennerberg.com

Date: Mon, 22 Mar 2021 17:53:33 -0700

Message-Id: CA4BJABOSCZY.3MFZ3PUK0YIV@debian-alex

To: "Johann Galle" <johann@qwertqwefsday.eu>, <~aw/patches@lists.sr.ht>

In-Reply-To: 20210322223344.6568-1-johann@qwertqwefsday.eu

Reply

Export

--------------------------------------

Thank you!