{"thread":{"id":"20918","subject":"[RFC/PATCH v4 1/2] gitweb: check given hash before trying to create snapshot","startedAt":"2009-09-12T23:03:52Z","lastAt":"2009-09-12T23:03:52Z","messageCount":1,"participants":["Mark Rada"],"isPatch":true,"patchVersion":4,"patchTotal":2},"messages":[{"id":"123006","messageId":"4AAC28D8.8050907@mailservices.uwaterloo.ca","threadId":"20918","inReplyTo":null,"subject":"[RFC/PATCH v4 1/2] gitweb: check given hash before trying to create snapshot","fromName":"Mark Rada","fromEmail":"marada@uwaterloo.ca","sentAt":"2009-09-12T23:03:52Z","receivedAt":"2009-09-12T23:03:52Z","isPatch":true,"sender":{"key":"marada@uwaterloo.ca","avatar":"https://avatars.githubusercontent.com/u/38430?v=4"},"body":"I changed some variable names to be nicer looking.\n\n--\nMark Rada (ferrous26)\nmarada@uwaterloo.ca\n\n\n--->8---\nMakes things nicer in cases when you hand craft the snapshot URL but\nmake a typo in defining the hash variable (e.g. netx instead of next);\nyou will now get an error message instead of a broken tarball.\n\nTo maintain backwards compatibility, git_get_head_hash is now a wrapper\nfor git_get_full_hash, as suggested by Jakub Narebski.\n\nTests for t9501 are included to demonstrate added functionality.\n\nSigned-off-by: Mark Rada <marada@uwaterloo.ca>\n---\n gitweb/gitweb.perl                       |   19 +++++++++++++------\n t/t9501-gitweb-standalone-http-status.sh |   29 +++++++++++++++++++++++++++++\n 2 files changed, 42 insertions(+), 6 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 24b2193..e1beca5 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1983,14 +1983,20 @@ sub quote_command {\n \n # get HEAD ref of given project as hash\n sub git_get_head_hash {\n+\treturn git_get_full_hash(shift, 'HEAD');\n+}\n+\n+# given a project and tree-ish, returns full hash\n+sub git_get_full_hash {\n \tmy $project = shift;\n+\tmy $hash = shift;\n \tmy $o_git_dir = $git_dir;\n \tmy $retval = undef;\n \t$git_dir = \"$projectroot/$project\";\n-\tif (open my $fd, \"-|\", git_cmd(), \"rev-parse\", \"--verify\", \"HEAD\") {\n-\t\tmy $head = <$fd>;\n+\tif (open my $fd, '-|', git_cmd(), 'rev-parse', '--verify', $hash) {\n+\t\t$hash = <$fd>;\n \t\tclose $fd;\n-\t\tif (defined $head && $head =~ /^([0-9a-fA-F]{40})$/) {\n+\t\tif (defined $hash && $hash =~ /^([0-9a-fA-F]{40})$/) {\n \t\t\t$retval = $1;\n \t\t}\n \t}\n@@ -5196,8 +5202,9 @@ sub git_snapshot {\n \t\tdie_error(403, \"Unsupported snapshot format\");\n \t}\n \n-\tif (!defined $hash) {\n-\t\t$hash = git_get_head_hash($project);\n+\tmy $full_hash = git_get_full_hash($project, $hash);\n+\tif (!$full_hash) {\n+\t\tdie_error(404, 'Hash id was not valid');\n \t}\n \n \tmy $name = $project;\n@@ -5210,7 +5217,7 @@ sub git_snapshot {\n \t$cmd = quote_command(\n \t\tgit_cmd(), 'archive',\n \t\t\"--format=$known_snapshot_formats{$format}{'format'}\",\n-\t\t\"--prefix=$name/\", $hash);\n+\t\t\"--prefix=$name/\", $full_hash);\n \tif (exists $known_snapshot_formats{$format}{'compressor'}) {\n \t\t$cmd .= ' | ' . quote_command(@{$known_snapshot_formats{$format}{'compressor'}});\n \t}\ndiff --git a/t/t9501-gitweb-standalone-http-status.sh b/t/t9501-gitweb-standalone-http-status.sh\nindex d0ff21d..632007e 100644\n--- a/t/t9501-gitweb-standalone-http-status.sh\n+++ b/t/t9501-gitweb-standalone-http-status.sh\n@@ -75,4 +75,33 @@ test_expect_success \\\n test_debug 'cat gitweb.output'\n \n \n+# ----------------------------------------------------------------------\n+# snapshot hash ids\n+\n+test_expect_success \\\n+\t'snapshots: good treeish id' \\\n+\t'gitweb_run \"p=.git;a=snapshot;h=master;sf=tgz\" &&\n+\tgrep \"Status: 200 OK\" gitweb.output'\n+test_debug 'cat gitweb.output'\n+\n+test_expect_success \\\n+\t'snapshots: bad treeish id' \\\n+\t'gitweb_run \"p=.git;a=snapshot;h=frizzumFrazzum;sf=tgz\" &&\n+\tgrep \"404 - Hash id was not valid\" gitweb.output'\n+test_debug 'cat gitweb.output'\n+\n+test_expect_success \\\n+\t'snapshots: good object id' \\\n+\t'ID=`git rev-parse --verify HEAD` &&\n+\tgitweb_run \"p=.git;a=snapshot;h=$ID;sf=tgz\" &&\n+\tgrep \"Status: 200 OK\" gitweb.output'\n+test_debug 'cat gitweb.output'\n+\n+test_expect_success \\\n+\t'snapshots: bad object id' \\\n+\t'gitweb_run \"p=.git;a=snapshot;h=abcdef01234;sf=tgz\" &&\n+\tgrep \"404 - Hash id was not valid\" gitweb.output'\n+test_debug 'cat gitweb.output'\n+\n+\n test_done\n-- \n1.6.4.2\n"}]}