Patchwork D1024: hgweb: do not import uuid immediately to avoid its side effect

login
register
mail settings
Submitter phabricator
Date Oct. 12, 2017, 5:02 a.m.
Message ID <differential-rev-PHID-DREV-guw4nb4moo2ukl6wiz7d-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/24767/
State Superseded
Headers show

Comments

phabricator - Oct. 12, 2017, 5:02 a.m.
quark created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  With hgdemandimport disabled (chg's case), `import uuid` has an immediate
  side effect calling `ctypes.util.find_library` trying to locate the
  `libuuid` library.  This happens at `import` time before `dispatch.run()`.
  The call trace is like:
  
    File "hg/hg", line 54, in <module>
      from mercurial import (
    File "hg/mercurial/dispatch.py", line 24, in <module>
      from . import (
    File "hg/mercurial/commands.py", line 23, in <module>
      from . import (
    File "hg/mercurial/help.py", line 33, in <module>
      from .hgweb import (
    File "hg/mercurial/hgweb/__init__.py", line 20, in <module>
      from . import (
    File "hg/mercurial/hgweb/hgweb_mod.py", line 14, in <module>
      from .common import (
    File "hg/mercurial/hgweb/common.py", line 15, in <module>
      import uuid
    File "/usr/lib64/python2.7/uuid.py", line 404, in <module>
      lib = ctypes.CDLL(ctypes.util.find_library(libname))
  
  The problem is, `ctypes.util.find_library` will execute
  `sh -c '/sbin/ldconfig -p 2>/dev/null'` on Python <= 2.7.12. The output of
  `sh` may pollute the terminal:
  
    shell-init: error retrieving current directory: getcwd: cannot access
    parent directories: No such file or directory
  
  This patch moves `import uuid` so its side-effect can only happen after the
  cwd check in `dispatch._getlocal`. Therefore the terminal won't be
  polluted by importing `uuid`.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/hgweb/common.py
  tests/test-dispatch.t

CHANGE DETAILS




To: quark, #hg-reviewers
Cc: mercurial-devel
phabricator - Oct. 13, 2017, 1:39 p.m.
yuja added inline comments.

INLINE COMMENTS

> test-dispatch.t:64
> +
> +#if no-windows
> +

Replaced with `#if rmcwd`

REPOSITORY
  rHG Mercurial

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

To: quark, #hg-reviewers, av6
Cc: yuja, mercurial-devel

Patch

diff --git a/tests/test-dispatch.t b/tests/test-dispatch.t
--- a/tests/test-dispatch.t
+++ b/tests/test-dispatch.t
@@ -60,3 +60,16 @@ 
   [255]
 
 #endif
+
+#if no-windows
+
+Current directory removed:
+
+  $ hg init $TESTTMP/repo1
+  $ cd $TESTTMP/repo1
+  $ rm -rf $TESTTMP/repo1
+  $ HGDEMANDIMPORT=disable hg version -q
+  abort: error getting current working directory: No such file or directory
+  [255]
+
+#endif
diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py
--- a/mercurial/hgweb/common.py
+++ b/mercurial/hgweb/common.py
@@ -12,7 +12,6 @@ 
 import errno
 import mimetypes
 import os
-import uuid
 
 from .. import (
     encoding,
@@ -221,6 +220,23 @@ 
     First value is ``None`` if CSP isn't enabled. Second value is ``None``
     if CSP isn't enabled or if the CSP header doesn't need a nonce.
     """
+    # Without demandimport, "import uuid" could have an immediate side-effect
+    # running "ldconfig" on Linux trying to find libuuid.
+    # With Python <= 2.7.12, that "ldconfig" is run via a shell and the shell
+    # may pollute the terminal with:
+    #
+    #   shell-init: error retrieving current directory: getcwd: cannot access
+    #   parent directories: No such file or directory
+    #
+    # Python >= 2.7.13 has fixed it by running "ldconfig" directly without a
+    # shell (hg changeset a09ae70f3489).
+    #
+    # Moved "import uuid" from here so it's executed after we know we have
+    # a sane cwd (i.e. after dispatch.py cwd check).
+    #
+    # We can move it back once we no longer need Python <= 2.7.12 support.
+    import uuid
+
     # Don't allow untrusted CSP setting since it be disable protections
     # from a trusted/global source.
     csp = ui.config('web', 'csp', untrusted=False)