[PATCH 2 of 3 V6] hgweb: teach archive how to download a specific directory or file
Angel Ezquerra
angel.ezquerra at gmail.com
Tue Mar 12 16:47:52 CDT 2013
On Tue, Mar 12, 2013 at 6:29 PM, Pierre-Yves David
<pierre-yves.david at logilab.fr> wrote:
> On Wed, Feb 27, 2013 at 06:06:33PM +0100, Angel Ezquerra wrote:
>> # HG changeset patch
>> # User Angel Ezquerra <angel.ezquerra at gmail.com>
>> # Date 1360493525 -3600
>> # Node ID b9fda7cbf2c239cecd667159391befb440edba80
>> # Parent a1aab0b30144b6d9b383e8021d24eecd5861c84e
>> hgweb: teach archive how to download a specific directory or file
>>
>> The archive web command now takes into account the "file" request entry, if one
>> is provided.
>>
>> The provided "file" is processed as a "path" corresponding to a directory or
>> file that will be downloaded.
>>
>> With this change hgweb can to process requests such as:
>>
>> http://mercurial.selenic.com/hg/archive/tip.zip/mercurial/templates
>>
>> This will download all files on the mercurial/templates directory as a zip file.
>> It is not possible to specify file patterns. Those will be rejected with a 403
>> reply fromthe server.
>>
>> Note that this is a first step to add support for downloading directories from
>> the web interface. Currently the only way to use this feature is by manually
>> constructing the URL that you want to download. We will have to modify the
>> archiveentry map entry on the different templates so that it adds the current
>> folder path to the archive links.
>>
>> diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
>> --- a/mercurial/hgweb/webcommands.py
>> +++ b/mercurial/hgweb/webcommands.py
>> @@ -816,6 +816,17 @@
>> if cnode == key or key == 'tip':
>> arch_version = short(cnode)
>> name = "%s-%s" % (reponame, arch_version)
>> +
>> + ctx = webutil.changectx(web.repo, req)
>> + pats = []
>> + file = req.form.get('file', None)
>> + if file:
>> + file = file[0]
>> + if ':' in file:
>> + msg = 'Archive pattern not allowed: %s' % file
>> + raise ErrorResponse(HTTP_FORBIDDEN, msg)
>> + pats = ['path:' + file]
>
> What about file with ":" is there name ?
I'd say that a user that created such a file deserves to not be able
to download it ;-)
Jokes aside, the alternative is to explicitly test for the different
patterns (e.g. relpath:, relre:, etc). The problem with that is that
if we ever introduce a new pattern we may forget to update this filter
and then let a malicious user use such a pattern.
So I don't know what is the best solution to this... Suggestions?
>> diff --git a/tests/test-archive.t b/tests/test-archive.t
>> --- a/tests/test-archive.t
>> +++ b/tests/test-archive.t
>> @@ -100,6 +100,13 @@
>> testing: test-archive-2c0277f05ed4/baz/bletch OK
>> testing: test-archive-2c0277f05ed4/foo OK
>> No errors detected in compressed data of archive.zip.
>> + $ python getarchive.py "$TIP" gz baz | gunzip | tar tf - 2>/dev/null
>> + test-archive-2c0277f05ed4/baz/bletch
>
> Is that the test for a directory of a file?
>
> You should test the other too.
You are right. That was testing archiving a single file. I'll add
another test that archives a directory.
Good catch!
>
>> +test that we reject unsafe patterns
>> +
>> + $ python getarchive.py "$TIP" gz relre:baz
>> + HTTP Error 403: Archive pattern not allowed: relre:baz
>>
>> $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
>
> Patches looks great otherwise!
Thanks for the review. Once we decide the best way to reject patterns
(if the current approach is not acceptable) I will resend the series
with the additional test.
Cheers,
Angel
More information about the Mercurial-devel
mailing list