D5772: hg: raise Abort on invalid path

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Thu Jan 31 01:23:52 UTC 2019


indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Currently, some os.path functions when opening repositories may
  raise an uncaught TypeError or ValueError if the path is invalid.
  
  Let's catch these exceptions and turn them into an Abort for
  convenience.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5772

AFFECTED FILES
  mercurial/hg.py
  mercurial/ui.py
  tests/test-remotefilelog-gc.t

CHANGE DETAILS

diff --git a/tests/test-remotefilelog-gc.t b/tests/test-remotefilelog-gc.t
--- a/tests/test-remotefilelog-gc.t
+++ b/tests/test-remotefilelog-gc.t
@@ -107,6 +107,6 @@
 # Test that warning is displayed when the repo path is malformed
 
   $ printf "asdas\0das" >> $CACHEDIR/repos
-  $ hg gc 2>&1 | head -n2
-  warning: malformed path: * (glob)
-  Traceback (most recent call last):
+  $ hg gc
+  abort: invalid path asdas\x00da: stat() argument 1 must be encoded string without null bytes, not str (esc)
+  [255]
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -2051,7 +2051,11 @@
         This is its own function so that extensions can change the definition of
         'valid' in this case (like when pulling from a git repo into a hg
         one)."""
-        return os.path.isdir(os.path.join(path, '.hg'))
+        try:
+            return os.path.isdir(os.path.join(path, '.hg'))
+        # Python 2 may return TypeError. Python 3, ValueError.
+        except (TypeError, ValueError):
+            return False
 
     @property
     def suboptions(self):
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -38,6 +38,7 @@
     narrowspec,
     node,
     phases,
+    pycompat,
     repository as repositorymod,
     scmutil,
     sshpeer,
@@ -57,7 +58,15 @@
 
 def _local(path):
     path = util.expandpath(util.urllocalpath(path))
-    return (os.path.isfile(path) and bundlerepo or localrepo)
+
+    try:
+        isfile = os.path.isfile(path)
+    # Python 2 raises TypeError, Python 3 ValueError.
+    except (TypeError, ValueError) as e:
+        raise error.Abort(_('invalid path %s: %s') % (
+            path, pycompat.bytestr(e)))
+
+    return isfile and bundlerepo or localrepo
 
 def addbranchrevs(lrepo, other, branches, revs):
     peer = other.peer() # a courtesy to callers using a localrepo for other



To: indygreg, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list