Patchwork url: fix crash by empty path with #fragments

login
register
mail settings
Submitter Yuya Nishihara
Date Sept. 30, 2016, 1:55 p.m.
Message ID <01b625c68599f2b56509.1475243710@mimosa>
Download mbox | patch
Permalink /patch/16809/
State Accepted
Headers show

Comments

Yuya Nishihara - Sept. 30, 2016, 1:55 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1475239127 -32400
#      Fri Sep 30 21:38:47 2016 +0900
# Node ID 01b625c68599f2b56509a3239cb13b9e5d4638c6
# Parent  ff17dff99295e0781b3f147da2c5e5b14d3436e4
url: fix crash by empty path with #fragments

Before, "#foo" paths made hg crash. We've moved the #fragment parsing at
64fbd0de9773, but we shouldn't set path to None too early. This patch just
removes the "if not path:" block since that's checked a few lines later.
Augie Fackler - Sept. 30, 2016, 7:57 p.m.
On Fri, Sep 30, 2016 at 10:55:10PM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1475239127 -32400
> #      Fri Sep 30 21:38:47 2016 +0900
> # Node ID 01b625c68599f2b56509a3239cb13b9e5d4638c6
> # Parent  ff17dff99295e0781b3f147da2c5e5b14d3436e4
> url: fix crash by empty path with #fragments

Queued, thanks

>
> Before, "#foo" paths made hg crash. We've moved the #fragment parsing at
> 64fbd0de9773, but we shouldn't set path to None too early. This patch just
> removes the "if not path:" block since that's checked a few lines later.
>
> diff --git a/mercurial/util.py b/mercurial/util.py
> --- a/mercurial/util.py
> +++ b/mercurial/util.py
> @@ -2377,6 +2377,22 @@ class url(object):
>      <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
>      >>> url('http://host/a?b#c', parsequery=False, parsefragment=False)
>      <url scheme: 'http', host: 'host', path: 'a?b#c'>
> +
> +    Empty path:
> +
> +    >>> url('')
> +    <url path: ''>
> +    >>> url('#a')
> +    <url path: '', fragment: 'a'>
> +    >>> url('http://host/')
> +    <url scheme: 'http', host: 'host', path: ''>
> +    >>> url('http://host/#a')
> +    <url scheme: 'http', host: 'host', path: '', fragment: 'a'>
> +
> +    Only scheme:
> +
> +    >>> url('http:')
> +    <url scheme: 'http'>
>      """
>
>      _safechars = "!~*'()+"
> @@ -2393,8 +2409,6 @@ class url(object):
>
>          if parsefragment and '#' in path:
>              path, self.fragment = path.split('#', 1)
> -            if not path:
> -                path = None
>
>          # special case for Windows drive letters and UNC paths
>          if hasdriveletter(path) or path.startswith(r'\\'):
> diff --git a/tests/test-url-rev.t b/tests/test-url-rev.t
> --- a/tests/test-url-rev.t
> +++ b/tests/test-url-rev.t
> @@ -320,3 +320,12 @@ Test handling common incoming revisions
>    remote: 1 outgoing
>
>    $ cd ..
> +
> +Test url#rev syntax of local destination path, which should be taken as
> +a 'url#rev' path
> +
> +  $ hg clone repo '#foo'
> +  updating to branch default
> +  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ hg root -R '#foo'
> +  $TESTTMP/#foo (glob)
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -2377,6 +2377,22 @@  class url(object):
     <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
     >>> url('http://host/a?b#c', parsequery=False, parsefragment=False)
     <url scheme: 'http', host: 'host', path: 'a?b#c'>
+
+    Empty path:
+
+    >>> url('')
+    <url path: ''>
+    >>> url('#a')
+    <url path: '', fragment: 'a'>
+    >>> url('http://host/')
+    <url scheme: 'http', host: 'host', path: ''>
+    >>> url('http://host/#a')
+    <url scheme: 'http', host: 'host', path: '', fragment: 'a'>
+
+    Only scheme:
+
+    >>> url('http:')
+    <url scheme: 'http'>
     """
 
     _safechars = "!~*'()+"
@@ -2393,8 +2409,6 @@  class url(object):
 
         if parsefragment and '#' in path:
             path, self.fragment = path.split('#', 1)
-            if not path:
-                path = None
 
         # special case for Windows drive letters and UNC paths
         if hasdriveletter(path) or path.startswith(r'\\'):
diff --git a/tests/test-url-rev.t b/tests/test-url-rev.t
--- a/tests/test-url-rev.t
+++ b/tests/test-url-rev.t
@@ -320,3 +320,12 @@  Test handling common incoming revisions 
   remote: 1 outgoing
 
   $ cd ..
+
+Test url#rev syntax of local destination path, which should be taken as
+a 'url#rev' path
+
+  $ hg clone repo '#foo'
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg root -R '#foo'
+  $TESTTMP/#foo (glob)