From 54709d9efd4624745ed0f67029ca30ee2ca87bc9 Mon Sep 17 00:00:00 2001
From: Dylan Katz <git@dylankatz.com>
Date: Mon, 21 Aug 2017 11:14:37 -0600
Subject: [PATCH 1/2] Fix leaking environment variables

---
 git/repo/base.py | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/git/repo/base.py b/git/repo/base.py
index 28bb2a5d7..1dfe91840 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -9,6 +9,7 @@
 import os
 import re
 import sys
+import warnings
 
 from git.cmd import (
     Git,
@@ -50,8 +51,11 @@
 __all__ = ('Repo',)
 
 
-def _expand_path(p):
-    return osp.normpath(osp.abspath(osp.expandvars(osp.expanduser(p))))
+def _expand_path(p, unsafe=True):
+    if unsafe:
+        return osp.normpath(osp.abspath(osp.expandvars(osp.expanduser(p))))
+    else:
+        return osp.normpath(osp.abspath(osp.expanduser(p)))
 
 
 class Repo(object):
@@ -90,7 +94,7 @@ class Repo(object):
     # Subclasses may easily bring in their own custom types by placing a constructor or type here
     GitCommandWrapperType = Git
 
-    def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False):
+    def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False, unsafe=True):
         """Create a new Repo instance
 
         :param path:
@@ -121,7 +125,10 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals
             epath = os.getcwd()
         if Git.is_cygwin():
             epath = decygpath(epath)
-        epath = _expand_path(epath or path or os.getcwd())
+        if unsafe and ("%" in epath or "$" in epath):
+            warnings.warn("The use of environment variables in paths is deprecated"
+                        + "\nfor security reasons and may be removed in the future!!")
+        epath = _expand_path(epath or path or os.getcwd(), unsafe)
         if not os.path.exists(epath):
             raise NoSuchPathError(epath)
 
@@ -148,7 +155,7 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals
                 sm_gitpath = find_worktree_git_dir(dotgit)
 
             if sm_gitpath is not None:
-                self.git_dir = _expand_path(sm_gitpath)
+                self.git_dir = _expand_path(sm_gitpath, unsafe)
                 self._working_tree_dir = curpath
                 break
 
@@ -862,12 +869,17 @@ def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs):
             the directory containing the database objects, i.e. .git/objects.
             It will be used to access all object data
 
+        :param unsafe:
+            if specified, environment variables will not be escaped. This
+            can lead to information disclosure, allowing attackers to
+            access the contents of environment variables
+
         :parm kwargs:
             keyword arguments serving as additional options to the git-init command
 
         :return: ``git.Repo`` (the newly created repo)"""
         if path:
-            path = _expand_path(path)
+            path = _expand_path(path, unsafe)
         if mkdir and path and not osp.exists(path):
             os.makedirs(path, 0o755)
 

From 67291f0ab9b8aa24f7eb6032091c29106de818ab Mon Sep 17 00:00:00 2001
From: Dylan Katz <git@dylankatz.com>
Date: Mon, 21 Aug 2017 12:09:37 -0600
Subject: [PATCH 2/2] Fixed missing parameter and changed name

---
 git/repo/base.py | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/git/repo/base.py b/git/repo/base.py
index 1dfe91840..d575466db 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -51,11 +51,11 @@
 __all__ = ('Repo',)
 
 
-def _expand_path(p, unsafe=True):
-    if unsafe:
-        return osp.normpath(osp.abspath(osp.expandvars(osp.expanduser(p))))
-    else:
-        return osp.normpath(osp.abspath(osp.expanduser(p)))
+def _expand_path(p, expand_vars=True):
+    p = osp.expanduser(p)
+    if expand_vars:
+        p = osp.expandvars(p)
+    return osp.normpath(osp.abspath(p))
 
 
 class Repo(object):
@@ -94,7 +94,7 @@ class Repo(object):
     # Subclasses may easily bring in their own custom types by placing a constructor or type here
     GitCommandWrapperType = Git
 
-    def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False, unsafe=True):
+    def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False, expand_vars=True):
         """Create a new Repo instance
 
         :param path:
@@ -120,15 +120,17 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals
         :raise InvalidGitRepositoryError:
         :raise NoSuchPathError:
         :return: git.Repo """
+
         epath = path or os.getenv('GIT_DIR')
         if not epath:
             epath = os.getcwd()
         if Git.is_cygwin():
             epath = decygpath(epath)
-        if unsafe and ("%" in epath or "$" in epath):
-            warnings.warn("The use of environment variables in paths is deprecated"
-                        + "\nfor security reasons and may be removed in the future!!")
-        epath = _expand_path(epath or path or os.getcwd(), unsafe)
+        epath = epath or path or os.getcwd()
+        if expand_vars and ("%" in epath or "$" in epath):
+            warnings.warn("The use of environment variables in paths is deprecated" +
+                          "\nfor security reasons and may be removed in the future!!")
+        epath = _expand_path(epath, expand_vars)
         if not os.path.exists(epath):
             raise NoSuchPathError(epath)
 
@@ -155,7 +157,7 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals
                 sm_gitpath = find_worktree_git_dir(dotgit)
 
             if sm_gitpath is not None:
-                self.git_dir = _expand_path(sm_gitpath, unsafe)
+                self.git_dir = _expand_path(sm_gitpath, expand_vars)
                 self._working_tree_dir = curpath
                 break
 
@@ -851,7 +853,7 @@ def blame(self, rev, file, incremental=False, **kwargs):
         return blames
 
     @classmethod
-    def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs):
+    def init(cls, path=None, mkdir=True, odbt=DefaultDBType, expand_vars=True, **kwargs):
         """Initialize a git repository at the given path if specified
 
         :param path:
@@ -869,7 +871,7 @@ def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs):
             the directory containing the database objects, i.e. .git/objects.
             It will be used to access all object data
 
-        :param unsafe:
+        :param expand_vars:
             if specified, environment variables will not be escaped. This
             can lead to information disclosure, allowing attackers to
             access the contents of environment variables
@@ -879,7 +881,7 @@ def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs):
 
         :return: ``git.Repo`` (the newly created repo)"""
         if path:
-            path = _expand_path(path, unsafe)
+            path = _expand_path(path, expand_vars)
         if mkdir and path and not osp.exists(path):
             os.makedirs(path, 0o755)