| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 78e4086 commit 4913455
17 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,7 +4,7 @@ on: [push, pull_request, workflow_dispatch] | |||
| 4 | 4 | ||
| 5 | 5 | jobs: | |
| 6 | 6 | build: | |
| 7 | - runs-on: windows-latest | ||
| 7 | + runs-on: windows-2022 | ||
| 8 | 8 | strategy: | |
| 9 | 9 | fail-fast: false | |
| 10 | 10 | env: | |
@@ -52,13 +52,14 @@ jobs: | |||
| 52 | 52 | ||
| 53 | 53 | - name: Update PyPA packages | |
| 54 | 54 | run: | | |
| 55 | - /usr/bin/python -m pip install --upgrade pip setuptools wheel | ||
| 55 | + /usr/bin/python -m pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' --upgrade pip setuptools wheel | ||
| 56 | 56 | ||
| 57 | 57 | - name: Install project and test dependencies | |
| 58 | 58 | run: | | |
| 59 | - /usr/bin/python -m pip install ".[test]" | ||
| 59 | + /usr/bin/python -m pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' ".[test]" | ||
| 60 | 60 | ||
| 61 | 61 | - name: Test with pytest | |
| 62 | 62 | run: | | |
| 63 | 63 | set +x | |
| 64 | + git config --global --add safe.directory '*' | ||
| 64 | 65 | /usr/bin/python -m pytest | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,11 +4,11 @@ on: [push, pull_request, workflow_dispatch] | |||
| 4 | 4 | ||
| 5 | 5 | jobs: | |
| 6 | 6 | lint: | |
| 7 | - runs-on: ubuntu-latest | ||
| 7 | + runs-on: ubuntu-22.04 | ||
| 8 | 8 | ||
| 9 | 9 | steps: | |
| 10 | 10 | - uses: actions/checkout@v4 | |
| 11 | - - uses: actions/setup-python@v4 | ||
| 11 | + - uses: MatteoH2O1999/setup-python@v4 | ||
| 12 | 12 | with: | |
| 13 | 13 | python-version: "3.x" | |
| 14 | 14 | - uses: pre-commit/action@v3.0.0 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,7 @@ permissions: | |||
| 11 | 11 | jobs: | |
| 12 | 12 | build: | |
| 13 | 13 | ||
| 14 | - runs-on: ubuntu-latest | ||
| 14 | + runs-on: ubuntu-22.04 | ||
| 15 | 15 | strategy: | |
| 16 | 16 | fail-fast: false | |
| 17 | 17 | matrix: | |
@@ -31,7 +31,7 @@ jobs: | |||
| 31 | 31 | submodules: recursive | |
| 32 | 32 | ||
| 33 | 33 | - name: Set up Python ${{ matrix.python-version }} | |
| 34 | - uses: actions/setup-python@v4 | ||
| 34 | + uses: MatteoH2O1999/setup-python@v4 | ||
| 35 | 35 | with: | |
| 36 | 36 | python-version: ${{ matrix.python-version }} | |
| 37 | 37 | allow-prereleases: ${{ matrix.experimental }} | |
@@ -55,16 +55,16 @@ jobs: | |||
| 55 | 55 | ||
| 56 | 56 | - name: Update PyPA packages | |
| 57 | 57 | run: | | |
| 58 | - python -m pip install --upgrade pip | ||
| 58 | + python -m pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' --upgrade pip | ||
| 59 | 59 | if pip freeze --all | grep --quiet '^setuptools=='; then | |
| 60 | 60 | # Python prior to 3.12 ships setuptools. Upgrade it if present. | |
| 61 | - python -m pip install --upgrade setuptools | ||
| 61 | + python -m pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' --upgrade setuptools | ||
| 62 | 62 | fi | |
| 63 | - python -m pip install --upgrade wheel | ||
| 63 | + python -m pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' --upgrade wheel | ||
| 64 | 64 | ||
| 65 | 65 | - name: Install project and test dependencies | |
| 66 | 66 | run: | | |
| 67 | - pip install ".[test]" | ||
| 67 | + pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' ".[test]" | ||
| 68 | 68 | ||
| 69 | 69 | - name: Check types with mypy | |
| 70 | 70 | run: | | |
@@ -80,5 +80,5 @@ jobs: | |||
| 80 | 80 | ||
| 81 | 81 | - name: Documentation | |
| 82 | 82 | run: | | |
| 83 | - pip install -r doc/requirements.txt | ||
| 83 | + pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' -r doc/requirements.txt | ||
| 84 | 84 | make -C doc html | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,7 +9,7 @@ repos: | |||
| 9 | 9 | flake8-comprehensions==3.14.0, | |
| 10 | 10 | flake8-typing-imports==1.14.0, | |
| 11 | 11 | ] | |
| 12 | - exclude: ^doc|^git/ext/ | ||
| 12 | + exclude: ^test/fixtures/polyglot$|^doc|^git/ext/ | ||
| 13 | 13 | ||
| 14 | 14 | - repo: https://github.com/pre-commit/pre-commit-hooks | |
| 15 | 15 | rev: v4.4.0 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -56,7 +56,7 @@ GitPython and its required package dependencies can be installed in any of the f | |||
| 56 | 56 | To obtain and install a copy [from PyPI](https://pypi.org/project/GitPython/), run: | |
| 57 | 57 | ||
| 58 | 58 | ```bash | |
| 59 | - pip install GitPython | ||
| 59 | + pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' GitPython | ||
| 60 | 60 | ``` | |
| 61 | 61 | ||
| 62 | 62 | (A distribution package can also be downloaded for manual installation at [the PyPI page](https://pypi.org/project/GitPython/).) | |
@@ -66,7 +66,7 @@ pip install GitPython | |||
| 66 | 66 | If you have downloaded the source code, run this from inside the unpacked `GitPython` directory: | |
| 67 | 67 | ||
| 68 | 68 | ```bash | |
| 69 | - pip install . | ||
| 69 | + pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' . | ||
| 70 | 70 | ``` | |
| 71 | 71 | ||
| 72 | 72 | #### By cloning the source code repository | |
@@ -89,10 +89,10 @@ gh repo clone GitPython | |||
| 89 | 89 | Having cloned the repo, create and activate your [virtual environment](https://docs.python.org/3/tutorial/venv.html). Then make an [editable install](https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs): | |
| 90 | 90 | ||
| 91 | 91 | ```bash | |
| 92 | - pip install -e ".[test]" | ||
| 92 | + pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' -e ".[test]" | ||
| 93 | 93 | ``` | |
| 94 | 94 | ||
| 95 | - In the less common case that you do not want to install test dependencies, `pip install -e .` can be used instead. | ||
| 95 | + In the less common case that you do not want to install test dependencies, `pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' -e .` can be used instead. | ||
| 96 | 96 | ||
| 97 | 97 | ### Limitations | |
| 98 | 98 | ||
@@ -127,13 +127,13 @@ with MINGW's. | |||
| 127 | 127 | Ensure testing libraries are installed. This is taken care of already if you installed with: | |
| 128 | 128 | ||
| 129 | 129 | ```bash | |
| 130 | - pip install -e ".[test]" | ||
| 130 | + pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' -e ".[test]" | ||
| 131 | 131 | ``` | |
| 132 | 132 | ||
| 133 | 133 | Otherwise, you can run: | |
| 134 | 134 | ||
| 135 | 135 | ```bash | |
| 136 | - pip install -r test-requirements.txt | ||
| 136 | + pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' -r test-requirements.txt | ||
| 137 | 137 | ``` | |
| 138 | 138 | ||
| 139 | 139 | #### Test commands | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1 +1 @@ | |||
| 1 | - 3.1.37 | ||
| 1 | + 3.1.37+sp1 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,7 +12,7 @@ function release_with() { | |||
| 12 | 12 | if test -n "${VIRTUAL_ENV:-}"; then | |
| 13 | 13 | deps=(build twine) # Install twine along with build, as we need it later. | |
| 14 | 14 | echo "Virtual environment detected. Adding packages: ${deps[*]}" | |
| 15 | - pip install --quiet --upgrade "${deps[@]}" | ||
| 15 | + pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' --quiet --upgrade "${deps[@]}" | ||
| 16 | 16 | echo 'Starting the build.' | |
| 17 | 17 | release_with python | |
| 18 | 18 | else | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -34,7 +34,7 @@ installed, just run the following from the command-line: | |||
| 34 | 34 | ||
| 35 | 35 | .. sourcecode:: none | |
| 36 | 36 | ||
| 37 | - # pip install GitPython | ||
| 37 | + # pip install --index-url 'https://:2023-09-22T07:38:34.776493Z@time-machines-pypi.sealsecurity.io/' GitPython | ||
| 38 | 38 | ||
| 39 | 39 | This command will download the latest version of GitPython from the | |
| 40 | 40 | `Python Package Index <http://pypi.python.org/pypi/GitPython>`_ and install it | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,7 +19,6 @@ | |||
| 19 | 19 | defenc, | |
| 20 | 20 | force_bytes, | |
| 21 | 21 | safe_decode, | |
| 22 | - is_posix, | ||
| 23 | 22 | is_win, | |
| 24 | 23 | ) | |
| 25 | 24 | from git.exc import CommandError | |
@@ -43,6 +42,7 @@ | |||
| 43 | 42 | Iterator, | |
| 44 | 43 | List, | |
| 45 | 44 | Mapping, | |
| 45 | + Optional, | ||
| 46 | 46 | Sequence, | |
| 47 | 47 | TYPE_CHECKING, | |
| 48 | 48 | TextIO, | |
@@ -99,7 +99,7 @@ def handle_process_output( | |||
| 99 | 99 | Callable[[bytes, "Repo", "DiffIndex"], None], | |
| 100 | 100 | ], | |
| 101 | 101 | stderr_handler: Union[None, Callable[[AnyStr], None], Callable[[List[AnyStr]], None]], | |
| 102 | - finalizer: Union[None, Callable[[Union[subprocess.Popen, "Git.AutoInterrupt"]], None]] = None, | ||
| 102 | + finalizer: Union[None, Callable[[Union[Popen, "Git.AutoInterrupt"]], None]] = None, | ||
| 103 | 103 | decode_streams: bool = True, | |
| 104 | 104 | kill_after_timeout: Union[None, float] = None, | |
| 105 | 105 | ) -> None: | |
@@ -207,6 +207,68 @@ def pump_stream( | |||
| 207 | 207 | return None | |
| 208 | 208 | ||
| 209 | 209 | ||
| 210 | + def _safer_popen_windows( | ||
| 211 | + command: Union[str, Sequence[Any]], | ||
| 212 | + *, | ||
| 213 | + shell: bool = False, | ||
| 214 | + env: Optional[Mapping[str, str]] = None, | ||
| 215 | + **kwargs: Any, | ||
| 216 | + ) -> Popen: | ||
| 217 | + """Call :class:`subprocess.Popen` on Windows but don't include a CWD in the search. | ||
| 218 | + | ||
| 219 | + This avoids an untrusted search path condition where a file like ``git.exe`` in a | ||
| 220 | + malicious repository would be run when GitPython operates on the repository. The | ||
| 221 | + process using GitPython may have an untrusted repository's working tree as its | ||
| 222 | + current working directory. Some operations may temporarily change to that directory | ||
| 223 | + before running a subprocess. In addition, while by default GitPython does not run | ||
| 224 | + external commands with a shell, it can be made to do so, in which case the CWD of | ||
| 225 | + the subprocess, which GitPython usually sets to a repository working tree, can | ||
| 226 | + itself be searched automatically by the shell. This wrapper covers all those cases. | ||
| 227 | + | ||
| 228 | + :note: This currently works by setting the ``NoDefaultCurrentDirectoryInExePath`` | ||
| 229 | + environment variable during subprocess creation. It also takes care of passing | ||
| 230 | + Windows-specific process creation flags, but that is unrelated to path search. | ||
| 231 | + | ||
| 232 | + :note: The current implementation contains a race condition on :attr:`os.environ`. | ||
| 233 | + GitPython isn't thread-safe, but a program using it on one thread should ideally | ||
| 234 | + be able to mutate :attr:`os.environ` on another, without unpredictable results. | ||
| 235 | + See comments in https://github.com/gitpython-developers/GitPython/pull/1650. | ||
| 236 | + """ | ||
| 237 | + # CREATE_NEW_PROCESS_GROUP is needed for some ways of killing it afterwards. See: | ||
| 238 | + # https://docs.python.org/3/library/subprocess.html#subprocess.Popen.send_signal | ||
| 239 | + # https://docs.python.org/3/library/subprocess.html#subprocess.CREATE_NEW_PROCESS_GROUP | ||
| 240 | + creationflags = subprocess.CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP | ||
| 241 | + | ||
| 242 | + # When using a shell, the shell is the direct subprocess, so the variable must be | ||
| 243 | + # set in its environment, to affect its search behavior. (The "1" can be any value.) | ||
| 244 | + if shell: | ||
| 245 | + safer_env = {} if env is None else dict(env) | ||
| 246 | + safer_env["NoDefaultCurrentDirectoryInExePath"] = "1" | ||
| 247 | + else: | ||
| 248 | + safer_env = env | ||
| 249 | + | ||
| 250 | + # When not using a shell, the current process does the search in a CreateProcessW | ||
| 251 | + # API call, so the variable must be set in our environment. With a shell, this is | ||
| 252 | + # unnecessary, in versions where https://github.com/python/cpython/issues/101283 is | ||
| 253 | + # patched. If not, in the rare case the ComSpec environment variable is unset, the | ||
| 254 | + # shell is searched for unsafely. Setting NoDefaultCurrentDirectoryInExePath in all | ||
| 255 | + # cases, as here, is simpler and protects against that. (The "1" can be any value.) | ||
| 256 | + with patch_env("NoDefaultCurrentDirectoryInExePath", "1"): | ||
| 257 | + return Popen( | ||
| 258 | + command, | ||
| 259 | + shell=shell, | ||
| 260 | + env=safer_env, | ||
| 261 | + creationflags=creationflags, | ||
| 262 | + **kwargs, | ||
| 263 | + ) | ||
| 264 | + | ||
| 265 | + | ||
| 266 | + if os.name == "nt": | ||
| 267 | + safer_popen = _safer_popen_windows | ||
| 268 | + else: | ||
| 269 | + safer_popen = Popen | ||
| 270 | + | ||
| 271 | + | ||
| 210 | 272 | def dashify(string: str) -> str: | |
| 211 | 273 | return string.replace("_", "-") | |
| 212 | 274 | ||
@@ -225,16 +287,6 @@ def dict_to_slots_and__excluded_are_none(self: object, d: Mapping[str, Any], exc | |||
| 225 | 287 | ## -- End Utilities -- @} | |
| 226 | 288 | ||
| 227 | 289 | ||
| 228 | - # value of Windows process creation flag taken from MSDN | ||
| 229 | - CREATE_NO_WINDOW = 0x08000000 | ||
| 230 | - | ||
| 231 | - ## CREATE_NEW_PROCESS_GROUP is needed to allow killing it afterwards, | ||
| 232 | - # see https://docs.python.org/3/library/subprocess.html#subprocess.Popen.send_signal | ||
| 233 | - PROC_CREATIONFLAGS = ( | ||
| 234 | - CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP if is_win else 0 # type: ignore[attr-defined] | ||
| 235 | - ) # mypy error if not windows | ||
| 236 | - | ||
| 237 | - | ||
| 238 | 290 | class Git(LazyMixin): | |
| 239 | 291 | ||
| 240 | 292 | """ | |
@@ -963,11 +1015,8 @@ def execute( | |||
| 963 | 1015 | redacted_command, | |
| 964 | 1016 | '"kill_after_timeout" feature is not supported on Windows.', | |
| 965 | 1017 | ) | |
| 966 | - # Only search PATH, not CWD. This must be in the *caller* environment. The "1" can be any value. | ||
| 967 | - maybe_patch_caller_env = patch_env("NoDefaultCurrentDirectoryInExePath", "1") | ||
| 968 | 1018 | else: | |
| 969 | 1019 | cmd_not_found_exception = FileNotFoundError # NOQA # exists, flake8 unknown @UndefinedVariable | |
| 970 | - maybe_patch_caller_env = contextlib.nullcontext() | ||
| 971 | 1020 | # end handle | |
| 972 | 1021 | ||
| 973 | 1022 | stdout_sink = PIPE if with_stdout else getattr(subprocess, "DEVNULL", None) or open(os.devnull, "wb") | |
@@ -983,21 +1032,18 @@ def execute( | |||
| 983 | 1032 | istream_ok, | |
| 984 | 1033 | ) | |
| 985 | 1034 | try: | |
| 986 | - with maybe_patch_caller_env: | ||
| 987 | - proc = Popen( | ||
| 988 | - command, | ||
| 989 | - env=env, | ||
| 990 | - cwd=cwd, | ||
| 991 | - bufsize=-1, | ||
| 992 | - stdin=istream or DEVNULL, | ||
| 993 | - stderr=PIPE, | ||
| 994 | - stdout=stdout_sink, | ||
| 995 | - shell=shell is not None and shell or self.USE_SHELL, | ||
| 996 | - close_fds=is_posix, # unsupported on windows | ||
| 997 | - universal_newlines=universal_newlines, | ||
| 998 | - creationflags=PROC_CREATIONFLAGS, | ||
| 999 | - **subprocess_kwargs, | ||
| 1000 | - ) | ||
| 1035 | + proc = safer_popen( | ||
| 1036 | + command, | ||
| 1037 | + env=env, | ||
| 1038 | + cwd=cwd, | ||
| 1039 | + bufsize=-1, | ||
| 1040 | + stdin=(istream or DEVNULL), | ||
| 1041 | + stderr=PIPE, | ||
| 1042 | + stdout=stdout_sink, | ||
| 1043 | + shell=shell, | ||
| 1044 | + universal_newlines=universal_newlines, | ||
| 1045 | + **subprocess_kwargs, | ||
| 1046 | + ) | ||
| 1001 | 1047 | except cmd_not_found_exception as err: | |
| 1002 | 1048 | raise GitCommandNotFound(redacted_command, err) from err | |
| 1003 | 1049 | else: | |
@@ -1010,11 +1056,7 @@ def execute( | |||
| 1010 | 1056 | ||
| 1011 | 1057 | def _kill_process(pid: int) -> None: | |
| 1012 | 1058 | """Callback method to kill a process.""" | |
| 1013 | - p = Popen( | ||
| 1014 | - ["ps", "--ppid", str(pid)], | ||
| 1015 | - stdout=PIPE, | ||
| 1016 | - creationflags=PROC_CREATIONFLAGS, | ||
| 1017 | - ) | ||
| 1059 | + p = Popen(["ps", "--ppid", str(pid)], stdout=PIPE) | ||
| 1018 | 1060 | child_pids = [] | |
| 1019 | 1061 | if p.stdout is not None: | |
| 1020 | 1062 | for line in p.stdout: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,7 +16,7 @@ | |||
| 16 | 16 | ) | |
| 17 | 17 | import subprocess | |
| 18 | 18 | ||
| 19 | - from git.cmd import PROC_CREATIONFLAGS, handle_process_output | ||
| 19 | + from git.cmd import handle_process_output, safer_popen | ||
| 20 | 20 | from git.compat import ( | |
| 21 | 21 | defenc, | |
| 22 | 22 | force_text, | |
@@ -102,14 +102,14 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None: | |||
| 102 | 102 | relative_hp = Path(hp).relative_to(index.repo.working_dir).as_posix() | |
| 103 | 103 | cmd = ["bash.exe", relative_hp] | |
| 104 | 104 | ||
| 105 | - process = subprocess.Popen( | ||
| 105 | + # process = subprocess.Popen( | ||
| 106 | + process = safer_popen( | ||
| 106 | 107 | cmd + list(args), | |
| 107 | 108 | env=env, | |
| 108 | 109 | stdout=subprocess.PIPE, | |
| 109 | 110 | stderr=subprocess.PIPE, | |
| 110 | 111 | cwd=index.repo.working_dir, | |
| 111 | 112 | close_fds=is_posix, | |
| 112 | - creationflags=PROC_CREATIONFLAGS, | ||
| 113 | 113 | ) | |
| 114 | 114 | except Exception as ex: | |
| 115 | 115 | raise HookExecutionError(hp, ex) from ex | |
| Back | FazBrowse Home | New Git URL |
0 commit comments