Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@simple-git/argv-parser

Package Overview
Dependencies
Maintainers
2
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@simple-git/argv-parser - npm Package Compare versions

Comparing version
1.0.3
to
1.1.0
+6
dist/src/args/parse-argv.d.ts
import type { ParsedArgv } from './parse-argv.types';
/**
* Parse the tokens that would be forwarded to a `git` child-process and
* return a structured summary of what the invocation does.
*/
export declare function parseArgv(...tokens: readonly unknown[]): ParsedArgv;
import type { Vulnerability } from '../vulnerabilities/vulnerability.types';
/** Where a config value originates / which scope it targets. */
export type ConfigScope = 'inline' | 'env' | 'local' | 'global' | 'system' | 'worktree' | 'file';
/** A single flag or option found in the token list. */
export interface ParsedFlag {
/** Canonical name: e.g. `'-m'`, `'--amend'`, `'--no-verify'`. */
name: string;
/** Value consumed by this flag, when applicable. */
value?: string;
}
/** A config key that this invocation reads via `git config`. */
export interface ConfigRead {
/** Lower-cased dotted key, e.g. `'user.name'`. */
key: string;
scope: ConfigScope;
}
/** A config key that this invocation writes. */
export interface ConfigWrite extends ConfigRead {
/**
* The value being written.
* Absent for delete-style operations (`--unset`, `--remove-section`).
* For `scope: 'env'` this is the environment-variable *name*, not the
* resolved config value.
*/
value?: string;
}
export interface ParsedConfigActivity {
/** Config keys read by a `git config` read operation. */
read: ConfigRead[];
/** Config keys written by this invocation (inline overrides and `git config` writes). */
write: ConfigWrite[];
}
/**
* Fully parsed representation of a set of varargs to be passed into the `git` child process.
*/
export interface ParsedArgv {
/**
* The git sub-command, e.g. `'commit'`, `'push'`.
* `null` when the list contains only global flags (`['--version']`, `[]`).
*/
task: string | null;
/**
* Every flag and option in the tokens (global + command-level), with
* combined short clusters expanded: `-uc` → `[{name:'-u'}, {name:'-c'}]`.
*/
flags: ParsedFlag[];
/**
* File-system paths: tokens after `--`, or `pathspec()` wrapper objects.
* */
paths: string[];
/**
* Activities being requested for the `git` config
*/
config: ParsedConfigActivity;
/**
* Attack vectors discovered in the arguments
*/
readonly vulnerabilities: Vulnerability[];
}
import type { ParsedConfigActivity } from '../args/parse-argv.types';
import type { Vulnerability } from '../vulnerabilities/vulnerability.types';
export declare function parseEnv(raw: Record<string, unknown>): {
config: ParsedConfigActivity;
vulnerabilities: Vulnerability[];
};
import type { ParsedConfigActivity } from '../args/parse-argv.types';
import type { Vulnerability } from './vulnerability.types';
export declare function detectVulnerableConfigWrites({ write, }: ParsedConfigActivity): Generator<Vulnerability>;
import type { Flag } from '../flags/flags.helpers';
import type { Vulnerability } from './vulnerability.types';
export declare function detectVulnerableFlags(task: null | string, flags: Flag[]): Generator<Vulnerability>;
/**
* Retrieves just the vulnerabilities identified in the supplied varargs tokens
* and environment variables.
*/
export declare function vulnerabilityCheck(tokens: readonly string[], env: Record<string, unknown>): import("./vulnerability.types").Vulnerability[];
+1
-1

@@ -1,2 +0,2 @@

"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("@simple-git/args-pathspec");function*m(e,t){const n=t==="global";for(const o of e)o.isGlobal===n&&(yield o)}const S=new Set(["--add","--edit","--remove-section","--rename-section","--replace-all","--unset","--unset-all","-e"]),x=new Set(["--get","--get-all","--get-color","--get-colorbool","--get-regexp","--get-urlmatch","--list","-l"]),y=new Set(["edit","remove-section","rename-section","set","unset"]),k=new Set(["get","get-color","get-colorbool","list"]);function C(e,t){for(const{name:o}of m(e,"task")){if(S.has(o))return f(!0,t);if(x.has(o))return f(!1,t)}const n=t.at(0)?.toLowerCase();return n===void 0?null:y.has(n)?f(!0,t.slice(1)):k.has(n)?f(!1,t.slice(1)):t.length===1?f(!1,t):f(!0,t)}function f(e=!1,t=[]){const n=t.at(0)?.toLowerCase();return n===void 0?null:{isWrite:e,isRead:!e,key:n,value:t.at(1)}}function P(e,t){return t.isWrite&&t.value!==void 0?{key:t.key,value:t.value,scope:e}:{key:t.key,scope:e}}function A(e){const t=e?.indexOf("=")||-1;return!e||t<0?null:{key:e.slice(0,t).trim().toLowerCase(),value:e.slice(t+1)}}function N(e){for(const{name:t}of m(e,"task"))switch(t){case"--global":return"global";case"--system":return"system";case"--worktree":return"worktree";case"--local":return"local";case"--file":case"-f":return"file"}return"local"}function U({name:e}){if(e==="-c"||e==="--config")return"inline";if(e==="--config-env")return"env"}function*F(e){for(const t of e){const n=U(t),o=n&&A(t.value);o&&(yield{...o,scope:n})}}function M(e,t,n){const o={read:[],write:[...F(t)]};return e==="config"&&G(o,N(t),C(t,n)),o}function G(e,t,n){if(n===null)return;const o=P(t,n);n.isWrite?e.write.push(o):e.read.push(o)}const w={short:new Map([["c",!0]])},O={short:new Map([["C",!0],["P",!1],["h",!1],["p",!1],["v",!1],...w.short.entries()]),long:new Set(["attr-source","config-env","exec-path","git-dir","list-cmds","namespace","super-prefix","work-tree"])},E={clone:{short:new Map([["b",!0],["j",!0],["l",!1],["n",!1],["o",!0],["q",!1],["s",!1],["u",!0]]),long:new Set(["branch","config","jobs","origin","upload-pack","u"])},commit:{short:new Map([["C",!0],["F",!0],["c",!0],["m",!0],["t",!0]]),long:new Set(["file","message","reedit-message","reuse-message","template"])},config:{short:new Map([["e",!1],["f",!0],["l",!1]]),long:new Set(["blob","comment","default","file","type","value"])},fetch:{short:new Map,long:new Set(["upload-pack"])},pull:{short:new Map,long:new Set(["upload-pack"])},push:{short:new Map,long:new Set(["exec","receive-pack"])}},I={short:new Map,long:new Set};function L(e){const t=E[e??""]??I;return{short:new Map([...w.short.entries(),...t.short.entries()]),long:t.long}}function v(e,t=O){if(e.startsWith("--")){const n=e.indexOf("=");if(n>2)return[{name:e.slice(0,n),value:e.slice(n+1),needsNext:!1}];const o=e.slice(2);return[{name:e,needsNext:t.long.has(o)}]}if(e.length===2){const n=e.charAt(1),o=t.short.get(n);return[{name:e,needsNext:o===!0}]}return R(e,t.short)}function R(e,t){const n=e.slice(1).split(""),o=[];for(let a=0;a<n.length;a++){const s=n[a],r=t.get(s);if(r===void 0)return[{name:e,needsNext:!1}];if(r){const l=n.slice(a+1).join("");if(l&&![...l].every(p=>t.has(p)))return o.push({name:`-${s}`,value:l,needsNext:!1}),o}o.push({name:`-${s}`,needsNext:r})}return o}function T(e,t=[]){let n=0;for(;n<e.length;){const o=String(e[n]);if(!o.startsWith("-")||o.length<2)break;const a=v(o);let s=n+1;for(const r of a){const l={name:r.name,value:r.value,absorbedNext:!1,isGlobal:!0};r.needsNext&&l.value===void 0&&s<e.length&&(l.value=String(e[s]),l.absorbedNext=!0,s++),t.push(l)}n=s}return{flags:t,taskIndex:n}}function W(e,t,n=[]){const o=L(t),a=[],s=[];let r=0;for(;r<e.length;){const l=e[r];if(d.isPathSpec(l)){s.push(...d.toPaths(l)),r++;continue}const u=String(l);if(u==="--"){for(let c=r+1;c<e.length;c++){const i=e[c];d.isPathSpec(i)?s.push(...d.toPaths(i)):s.push(String(i))}break}if(!u.startsWith("-")||u.length<2){a.push(u),r++;continue}const p=v(u,o);let h=r+1;for(const c of p){const i={name:c.name,value:c.value,absorbedNext:!1,isGlobal:!1};c.needsNext&&i.value===void 0&&h<e.length&&!d.isPathSpec(e[h])&&(i.value=String(e[h]),i.absorbedNext=!0,h++),n.push(i)}r=h}return{flags:n,positionals:a,pathspecs:s}}function*_({write:e}){for(const t of e)for(const n of j){const o=n(t.key);o&&(yield o)}}function g(e,t,n=String(e)){const o=typeof e=="string"?new RegExp(`\\s*${e}`,"i"):e;return function(s){if(o.test(s))return{category:t,message:`Configuring ${n} is not permitted without enabling ${t}`}}}const j=[g(/^\s*protocol(.[a-z]+)?.allow/i,"allowUnsafeProtocolOverride","protocol.allow"),g("core.sshCommand","allowUnsafeSshCommand"),g("core.fsmonitor","allowUnsafeFsMonitor"),g("core.gitProxy","allowUnsafeGitProxy"),g("core.hooksPath","allowUnsafeHooksPath"),g("diff.external","allowUnsafeDiffExternal")];function*$(e,t){for(const n of t)/^--(upload|receive)-pack/.test(n.name)&&(yield{category:"allowUnsafePack",message:"Use of --upload-pack or --receive-pack is not permitted without enabling allowUnsafePack"}),e==="clone"&&(/^-\w*u/.test(n.name)||n.name==="--u")&&(yield{category:"allowUnsafePack",message:"Use of clone with option -u is not permitted without enabling allowUnsafePack"}),e==="push"&&/^--exec/.test(n.name)&&(yield{category:"allowUnsafePack",message:"Use of push with option --exec is not permitted without enabling allowUnsafePack"})}function b(e,t,n){const o=[...$(e,t),..._(n)];return{categories:o.reduce((s,r)=>s.add(r.category),new Set),vulnerabilities:o}}function q(...e){const{flags:t,taskIndex:n}=T(e),o=n<e.length?String(e[n]).toLowerCase():null,a=o!==null?e.slice(n+1):[],{positionals:s,pathspecs:r}=W(a,o,t),l=M(o,t,s);return{task:o,flags:t.map(B),paths:r,config:l,vulnerabilities:b(o,t,l)}}function B({value:e,name:t}){return e!==void 0?{name:t,value:e}:{name:t}}exports.parseArgv=q;exports.vulnerabilityAnalysis=b;
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("@simple-git/args-pathspec");function*v(e,t){const n=t==="global";for(const o of e)o.isGlobal===n&&(yield o)}const S=new Set(["--add","--edit","--remove-section","--rename-section","--replace-all","--unset","--unset-all","-e"]),P=new Set(["--get","--get-all","--get-color","--get-colorbool","--get-regexp","--get-urlmatch","--list","-l"]),E=new Set(["edit","remove-section","rename-section","set","unset"]),A=new Set(["get","get-color","get-colorbool","list"]);function F(e,t){for(const{name:o}of v(e,"task")){if(S.has(o))return p(!0,t);if(P.has(o))return p(!1,t)}const n=t.at(0)?.toLowerCase();return n===void 0?null:E.has(n)?p(!0,t.slice(1)):A.has(n)?p(!1,t.slice(1)):t.length===1?p(!1,t):p(!0,t)}function p(e=!1,t=[]){const n=t.at(0)?.toLowerCase();return n===void 0?null:{isWrite:e,isRead:!e,key:n,value:t.at(1)}}function M(e,t){return t.isWrite&&t.value!==void 0?{key:t.key,value:t.value,scope:e}:{key:t.key,scope:e}}function N(e){const t=e?.indexOf("=")||-1;return!e||t<0?null:{key:e.slice(0,t).trim().toLowerCase(),value:e.slice(t+1)}}function G(e){for(const{name:t}of v(e,"task"))switch(t){case"--global":return"global";case"--system":return"system";case"--worktree":return"worktree";case"--local":return"local";case"--file":case"-f":return"file"}return"local"}function O({name:e}){if(e==="-c"||e==="--config")return"inline";if(e==="--config-env")return"env"}function*$(e){for(const t of e){const n=O(t),o=n&&N(t.value);o&&(yield{...o,scope:n})}}function D(e,t,n){const o={read:[],write:[...$(t)]};return e==="config"&&L(o,G(t),F(t,n)),o}function L(e,t,n){if(n===null)return;const o=M(t,n);n.isWrite?e.write.push(o):e.read.push(o)}const U={short:new Map([["c",!0]])},T={short:new Map([["C",!0],["P",!1],["h",!1],["p",!1],["v",!1],...U.short.entries()]),long:new Set(["attr-source","config-env","exec-path","git-dir","list-cmds","namespace","super-prefix","work-tree"])},R={clone:{short:new Map([["b",!0],["j",!0],["l",!1],["n",!1],["o",!0],["q",!1],["s",!1],["u",!0]]),long:new Set(["branch","config","jobs","origin","upload-pack","u","template"])},commit:{short:new Map([["C",!0],["F",!0],["c",!0],["m",!0],["t",!0]]),long:new Set(["file","message","reedit-message","reuse-message","template"])},config:{short:new Map([["e",!1],["f",!0],["l",!1]]),long:new Set(["blob","comment","default","file","type","value"])},fetch:{short:new Map,long:new Set(["upload-pack"])},init:{short:new Map,long:new Set(["template"])},pull:{short:new Map,long:new Set(["upload-pack"])},push:{short:new Map,long:new Set(["exec","receive-pack"])}},I={short:new Map,long:new Set};function W(e){const t=R[e??""]??I;return{short:new Map([...U.short.entries(),...t.short.entries()]),long:t.long}}function b(e,t=T){if(e.startsWith("--")){const n=e.indexOf("=");if(n>2)return[{name:e.slice(0,n),value:e.slice(n+1),needsNext:!1}];const o=e.slice(2);return[{name:e,needsNext:t.long.has(o)}]}if(e.length===2){const n=e.charAt(1),o=t.short.get(n);return[{name:e,needsNext:o===!0}]}return j(e,t.short)}function j(e,t){const n=e.slice(1).split(""),o=[];for(let s=0;s<n.length;s++){const a=n[s],r=t.get(a);if(r===void 0)return[{name:e,needsNext:!1}];if(r){const l=n.slice(s+1).join("");if(l&&![...l].every(m=>t.has(m)))return o.push({name:`-${a}`,value:l,needsNext:!1}),o}o.push({name:`-${a}`,needsNext:r})}return o}function B(e,t=[]){let n=0;for(;n<e.length;){const o=String(e[n]);if(!o.startsWith("-")||o.length<2)break;const s=b(o);let a=n+1;for(const r of s){const l={name:r.name,value:r.value,absorbedNext:!1,isGlobal:!0};r.needsNext&&l.value===void 0&&a<e.length&&(l.value=String(e[a]),l.absorbedNext=!0,a++),t.push(l)}n=a}return{flags:t,taskIndex:n}}function q(e,t,n=[]){const o=W(t),s=[],a=[];let r=0;for(;r<e.length;){const l=e[r];if(h.isPathSpec(l)){a.push(...h.toPaths(l)),r++;continue}const f=String(l);if(f==="--"){for(let g=r+1;g<e.length;g++){const u=e[g];h.isPathSpec(u)?a.push(...h.toPaths(u)):a.push(String(u))}break}if(!f.startsWith("-")||f.length<2){s.push(f),r++;continue}const m=b(f,o);let d=r+1;for(const g of m){const u={name:g.name,value:g.value,absorbedNext:!1,isGlobal:!1};g.needsNext&&u.value===void 0&&d<e.length&&!h.isPathSpec(e[d])&&(u.value=String(e[d]),u.absorbedNext=!0,d++),n.push(u)}r=d}return{flags:n,positionals:s,pathspecs:a}}function*V({write:e}){for(const t of e)for(const n of K){const o=n(t.key);o&&(yield o)}}function c(e,t,n=String(e)){const o=typeof e=="string"?new RegExp(`\\s*${e.toLowerCase()}`):e;return function(a){if(o.test(a))return{category:t,message:`Configuring ${n} is not permitted without enabling ${t}`}}}function i(e,t){const n=new RegExp(`\\s*${e.toLowerCase().replace(/\./g,"(..+)?.")}`);return c(n,t,e)}const K=[c("alias","allowUnsafeAlias"),c("core.askPass","allowUnsafeAskPass"),c("core.editor","allowUnsafeEditor"),c("core.fsmonitor","allowUnsafeFsMonitor"),c("core.gitProxy","allowUnsafeGitProxy"),c("core.hooksPath","allowUnsafeHooksPath"),c("core.pager","allowUnsafePager"),c("core.sshCommand","allowUnsafeSshCommand"),i("credential.helper","allowUnsafeCredentialHelper"),i("diff.command","allowUnsafeDiffExternal"),c("diff.external","allowUnsafeDiffExternal"),i("diff.textconv","allowUnsafeDiffTextConv"),i("filter.clean","allowUnsafeFilter"),i("filter.smudge","allowUnsafeFilter"),i("gpg.program","allowUnsafeGpgProgram"),c("init.templateDir","allowUnsafeTemplateDir"),i("merge.driver","allowUnsafeMergeDriver"),i("mergetool.path","allowUnsafeMergeDriver"),i("mergetool.cmd","allowUnsafeMergeDriver"),i("protocol.allow","allowUnsafeProtocolOverride"),i("remote.receivepack","allowUnsafePack"),i("remote.uploadpack","allowUnsafePack"),c("sequence.editor","allowUnsafeEditor")];function*H(e,t){for(const n of t)for(const o of Y){const s=o(e,n.name);s&&(yield s)}}function w(e,t,n,o=String(t)){const s=typeof t=="string"?new RegExp(`\\s*${t.toLowerCase()}`):t,a=`Use of ${e?`${e} with option `:""}${o} is not permitted without enabling ${n}`;return function(l,f){if((!e||l===e)&&s.test(f))return{category:n,message:a}}}const Y=[w(null,/--(upload|receive)-pack/,"allowUnsafePack","--upload-pack or --receive-pack"),w("clone",/^-\w*u/,"allowUnsafePack"),w("clone","--u","allowUnsafePack"),w("push","--exec","allowUnsafePack"),w(null,"--template","allowUnsafeTemplateDir")];function C(e,t,n){return[...H(e,t),...V(n)]}function x(...e){const{flags:t,taskIndex:n}=B(e),o=n<e.length?String(e[n]).toLowerCase():null,s=o!==null?e.slice(n+1):[],{positionals:a,pathspecs:r}=q(s,o,t),l=D(o,t,a);return{task:o,flags:t.map(z),paths:r,config:l,vulnerabilities:C(o,t,l)}}function z({value:e,name:t}){return e!==void 0?{name:t,value:e}:{name:t}}const y={editor:"allowUnsafeEditor",git_askpass:"allowUnsafeAskPass",git_config_global:"allowUnsafeConfigPaths",git_config_system:"allowUnsafeConfigPaths",git_config_count:"allowUnsafeConfigEnvCount",git_config:"allowUnsafeConfigPaths",git_editor:"allowUnsafeEditor",git_exec_path:"allowUnsafeConfigPaths",git_external_diff:"allowUnsafeDiffExternal",git_pager:"allowUnsafePager",git_proxy_command:"allowUnsafeGitProxy",git_template_dir:"allowUnsafeTemplateDir",git_sequence_editor:"allowUnsafeEditor",git_ssh:"allowUnsafeSshCommand",git_ssh_command:"allowUnsafeSshCommand",pager:"allowUnsafePager",prefix:"allowUnsafeConfigPaths",ssh_askpass:"allowUnsafeAskPass"};function*J(e){const t=parseInt(e.git_config_count??"0",10);for(let n=0;n<t;n++){const o=e[`git_config_key_${n}`],s=e[`git_config_value_${n}`];o!==void 0&&(yield{key:o.toLowerCase().trim(),value:s,scope:"env"})}}function*Q(e){for(const t of Object.keys(e))if(k(t)){const n=y[t];yield{category:n,message:`Use of "${t.toUpperCase()}" is not permitted without enabling ${n}`}}}function k(e){return Object.hasOwn(y,e)}function X(e){const t={};for(const[n,o]of Object.entries(e)){const s=n.toLowerCase().trim();(k(s)||s.startsWith("git"))&&(t[s]=String(o))}return t}function _(e){const t=X(e),n={read:[],write:[...J(t)]},o=[...Q(t),...C(null,[],n)];return{config:n,vulnerabilities:o}}function Z(e,t){return[...x(...e).vulnerabilities,..._(t).vulnerabilities]}exports.parseArgv=x;exports.parseEnv=_;exports.vulnerabilityCheck=Z;
//# sourceMappingURL=index.cjs.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs","sources":["../src/flags/flags.helpers.ts","../src/config/config-operands.ts","../src/config/detect-config-action.ts","../src/config/analyse-config.ts","../src/tokens/flag-specs.ts","../src/tokens/token-expander.ts","../src/flags/parse-global-flags.ts","../src/flags/parse-task-flags.ts","../src/vulnerabilities/detect-config-writes.ts","../src/vulnerabilities/detect-upload-pack.ts","../src/vulnerabilities/vulnerability-analysis.ts","../src/parse-argv.ts"],"sourcesContent":["export interface Flag {\n name: string;\n value?: string;\n /** Value came from the next token rather than being embedded after `=`. */\n absorbedNext: boolean;\n /** Switch appeared before the git sub-command. */\n isGlobal: boolean;\n}\n\nexport function* scopedFlags(flags: Flag[], scope: 'global' | 'task') {\n const findGlobal = scope === 'global';\n for (const flag of flags) {\n if (flag.isGlobal === findGlobal) {\n yield flag;\n }\n }\n}\n","// Flags that unambiguously signal a write operation on git config.\nexport const CONFIG_WRITE_FLAGS = new Set([\n '--add',\n '--edit',\n '--remove-section',\n '--rename-section',\n '--replace-all',\n '--unset',\n '--unset-all',\n '-e',\n]);\n\n// Flags that unambiguously signal a read operation.\nexport const CONFIG_READ_FLAGS = new Set([\n '--get',\n '--get-all',\n '--get-color',\n '--get-colorbool',\n '--get-regexp',\n '--get-urlmatch',\n '--list',\n '-l',\n]);\n\n// Sub-command verbs accepted as the first positional by newer git versions.\nexport const CONFIG_WRITE_VERBS = new Set([\n 'edit',\n 'remove-section',\n 'rename-section',\n 'set',\n 'unset',\n]);\nexport const CONFIG_READ_VERBS = new Set(['get', 'get-color', 'get-colorbool', 'list']);\n","import { type Flag, scopedFlags } from '../flags/flags.helpers';\nimport type { ConfigScope } from '../parse-argv.types';\nimport type { ConfigOperation } from './config.types';\nimport {\n CONFIG_READ_FLAGS,\n CONFIG_READ_VERBS,\n CONFIG_WRITE_FLAGS,\n CONFIG_WRITE_VERBS,\n} from './config-operands';\n\nexport function detectConfigAction(flags: Flag[], positionals: string[]): ConfigOperation | null {\n for (const { name } of scopedFlags(flags, 'task')) {\n if (CONFIG_WRITE_FLAGS.has(name)) {\n return configOperation(true, positionals);\n }\n if (CONFIG_READ_FLAGS.has(name)) {\n return configOperation(false, positionals);\n }\n }\n\n const verb = positionals.at(0)?.toLowerCase();\n\n if (verb === undefined) {\n return null;\n }\n\n if (CONFIG_WRITE_VERBS.has(verb)) {\n return configOperation(true, positionals.slice(1));\n }\n\n if (CONFIG_READ_VERBS.has(verb)) {\n return configOperation(false, positionals.slice(1));\n }\n\n if (positionals.length === 1) {\n return configOperation(false, positionals);\n }\n\n return configOperation(true, positionals);\n}\n\nfunction configOperation(isWrite = false, positionals: string[] = []): ConfigOperation | null {\n const key = positionals.at(0)?.toLowerCase();\n\n if (key === undefined) {\n return null;\n }\n\n return {\n isWrite,\n isRead: !isWrite,\n key,\n value: positionals.at(1),\n };\n}\n\nexport function toOperation(scope: ConfigScope, operation: ConfigOperation) {\n if (operation.isWrite && operation.value !== undefined) {\n return { key: operation.key, value: operation.value, scope };\n }\n return { key: operation.key, scope };\n}\n","import { type Flag, scopedFlags } from '../flags/flags.helpers';\nimport type { ConfigScope, ConfigWrite, ParsedConfigActivity } from '../parse-argv.types';\nimport type { ConfigOperation } from './config.types';\nimport { detectConfigAction, toOperation } from './detect-config-action';\n\nfunction parseAssignment(raw: string | undefined): { key: string; value: string } | null {\n const eq = raw?.indexOf('=') || -1;\n\n if (!raw || eq < 0) {\n return null;\n }\n\n return {\n key: raw.slice(0, eq).trim().toLowerCase(),\n value: raw.slice(eq + 1),\n };\n}\n\nfunction detectConfigScope(flags: Flag[]): ConfigScope {\n for (const { name } of scopedFlags(flags, 'task')) {\n switch (name) {\n case '--global':\n return 'global';\n case '--system':\n return 'system';\n case '--worktree':\n return 'worktree';\n case '--local':\n return 'local';\n case '--file':\n case '-f':\n return 'file';\n }\n }\n return 'local';\n}\n\nfunction detectConfigOverrideScope({ name }: Flag): ConfigScope | void {\n if (name === '-c' || name === '--config') {\n return 'inline';\n }\n if (name === '--config-env') {\n return 'env';\n }\n}\n\n/**\n * Generates the stream of ConfigWrite settings found in the supplied flags,\n * triggered by `-c` and `--config` for inline configuration and `--config-env`\n * to set a config setting based on environment variable.\n */\nfunction* collectWriteFlags(flags: Flag[]): Generator<ConfigWrite> {\n for (const flag of flags) {\n const scope = detectConfigOverrideScope(flag);\n const assignment = scope && parseAssignment(flag.value);\n\n if (assignment) {\n yield {\n ...assignment,\n scope,\n };\n }\n }\n}\n\nexport function collectConfigAccess(\n task: string | null,\n flags: Flag[],\n positionals: string[]\n): ParsedConfigActivity {\n const parsedConfig: ParsedConfigActivity = {\n read: [],\n write: [...collectWriteFlags(flags)],\n };\n\n if (task === 'config') {\n appendParsedConfigAction(\n parsedConfig,\n detectConfigScope(flags),\n detectConfigAction(flags, positionals)\n );\n }\n\n return parsedConfig;\n}\n\nfunction appendParsedConfigAction(\n parsedConfig: ParsedConfigActivity,\n scope: ConfigScope,\n action: ConfigOperation | null\n) {\n if (action === null) {\n return;\n }\n\n const config = toOperation(scope, action);\n if (action.isWrite) {\n parsedConfig.write.push(config);\n } else {\n parsedConfig.read.push(config);\n }\n}\n","// ── Option tables ─────────────────────────────────────────────────────────────\n//\n// Each scope has:\n// short – Map<char, consumesNext> (known single-letter switches; true = takes next token)\n// long – Set<stem> (long switch stems, without --, that take the next token)\n//\n// Only switches listed here are \"known\". An unknown char anywhere in a combined\n// cluster causes the entire cluster to be kept as one opaque token.\n\nexport interface FlagSpec {\n readonly short: ReadonlyMap<string, boolean>;\n readonly long: ReadonlySet<string>;\n}\n\nconst UNIVERSAL: FlagSpec = {\n short: new Map([\n ['c', true], // -c <k=v> set config key for this invocation\n ]),\n long: new Set(),\n};\n\nexport const GLOBAL: FlagSpec = {\n short: new Map([\n ['C', true], // -C <path> change working directory\n ['P', false], // -P no pager (alias for --no-pager)\n ['h', false], // -h help\n ['p', false], // -p paginate\n ['v', false], // -v version\n ...UNIVERSAL.short.entries(),\n ]),\n long: new Set([\n 'attr-source',\n 'config-env',\n 'exec-path',\n 'git-dir',\n 'list-cmds',\n 'namespace',\n 'super-prefix',\n 'work-tree',\n ]),\n};\n\nconst COMMANDS: Record<string, FlagSpec> = {\n clone: {\n short: new Map([\n ['b', true], // -b <branch>\n ['j', true], // -j <n> parallel jobs\n ['l', false], // -l local\n ['n', false], // -n no-checkout\n ['o', true], // -o <name> remote name\n ['q', false], // -q quiet\n ['s', false], // -s shared\n ['u', true], // -u <upload-pack>\n ]),\n long: new Set(['branch', 'config', 'jobs', 'origin', 'upload-pack', 'u']),\n },\n commit: {\n short: new Map([\n ['C', true], // -C <commit> reuse message\n ['F', true], // -F <file> read message from file\n ['c', true], // -c <commit> reedit message\n ['m', true], // -m <msg>\n ['t', true], // -t <template>\n ]),\n long: new Set(['file', 'message', 'reedit-message', 'reuse-message', 'template']),\n },\n config: {\n short: new Map([\n ['e', false], // -e open editor\n ['f', true], // -f <file>\n ['l', false], // -l list\n ]),\n long: new Set(['blob', 'comment', 'default', 'file', 'type', 'value']),\n },\n fetch: {\n short: new Map(),\n long: new Set(['upload-pack']),\n },\n pull: {\n short: new Map(),\n long: new Set(['upload-pack']),\n },\n push: {\n short: new Map(),\n long: new Set(['exec', 'receive-pack']),\n },\n};\n\nconst EMPTY: FlagSpec = { short: new Map(), long: new Set() };\n\nexport function getFlagSpecForTask(task?: string | null) {\n const spec = COMMANDS[task ?? ''] ?? EMPTY;\n\n return {\n short: new Map([...UNIVERSAL.short.entries(), ...spec.short.entries()]),\n long: spec.long,\n };\n}\n","import { GLOBAL } from './flag-specs';\n\n/** Parse a single raw token (e.g. `'-m'`, `'--amend'`, `'-uc'`) into one or\n * more switch descriptors. Values are not yet resolved for needsNext=true. */\nexport function expandToken(\n raw: string,\n spec = GLOBAL\n): Array<{\n name: string;\n value?: string;\n needsNext: boolean;\n}> {\n if (raw.startsWith('--')) {\n const eq = raw.indexOf('=');\n if (eq > 2) {\n return [{ name: raw.slice(0, eq), value: raw.slice(eq + 1), needsNext: false }];\n }\n const stem = raw.slice(2);\n return [{ name: raw, needsNext: spec.long.has(stem) }];\n }\n\n // Single short switch\n if (raw.length === 2) {\n const char = raw.charAt(1);\n const consumes = spec.short.get(char);\n return [{ name: raw, needsNext: consumes === true }];\n }\n\n // Combined short cluster: try to expand char-by-char\n return expandCluster(raw, spec.short);\n}\n\nfunction expandCluster(\n raw: string,\n shortSpec: ReadonlyMap<string, boolean>\n): Array<{ name: string; value?: string; needsNext: boolean }> {\n const chars = raw.slice(1).split('');\n const result: Array<{ name: string; value?: string; needsNext: boolean }> = [];\n\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n const consumes = shortSpec.get(char);\n\n if (consumes === undefined) {\n // Unknown char: keep the whole raw token as opaque\n return [{ name: raw, needsNext: false }];\n }\n\n if (consumes) {\n const remainder = chars.slice(i + 1).join('');\n if (remainder) {\n const remainderAllKnown = [...remainder].every((c) => shortSpec.has(c));\n if (!remainderAllKnown) {\n // Remaining chars are the embedded value, not separate flags\n result.push({ name: `-${char}`, value: remainder, needsNext: false });\n return result;\n }\n }\n }\n\n result.push({ name: `-${char}`, needsNext: consumes });\n }\n\n return result;\n}\n","import { expandToken } from '../tokens/token-expander';\nimport type { Flag } from './flags.helpers';\n\nexport interface GlobalFlags {\n flags: Flag[];\n taskIndex: number;\n}\n\nexport function parseGlobalFlags(tokens: readonly unknown[], flags: Flag[] = []): GlobalFlags {\n let i = 0;\n\n while (i < tokens.length) {\n const raw = String(tokens[i]);\n if (!raw.startsWith('-') || raw.length < 2) break;\n\n const parsed = expandToken(raw);\n let next = i + 1;\n\n for (const token of parsed) {\n const flag: Flag = {\n name: token.name,\n value: token.value,\n absorbedNext: false,\n isGlobal: true,\n };\n if (token.needsNext && flag.value === undefined && next < tokens.length) {\n flag.value = String(tokens[next]);\n flag.absorbedNext = true;\n next++;\n }\n flags.push(flag);\n }\n\n i = next;\n }\n\n return { flags, taskIndex: i };\n}\n","import { isPathSpec, toPaths } from '@simple-git/args-pathspec';\n\nimport { getFlagSpecForTask } from '../tokens/flag-specs';\nimport { expandToken } from '../tokens/token-expander';\nimport type { Flag } from './flags.helpers';\n\ntype TaskFlags = {\n flags: Flag[];\n positionals: string[];\n pathspecs: string[];\n};\n\nexport function parseTaskFlags(\n tokens: readonly unknown[],\n task: string | null,\n flags: Flag[] = []\n): TaskFlags {\n const spec = getFlagSpecForTask(task);\n const positionals: string[] = [];\n const pathspecs: string[] = [];\n\n let i = 0;\n while (i < tokens.length) {\n const current = tokens[i];\n\n if (isPathSpec(current)) {\n pathspecs.push(...toPaths(current as string));\n i++;\n continue;\n }\n\n const raw = String(current);\n\n if (raw === '--') {\n for (let j = i + 1; j < tokens.length; j++) {\n const t = tokens[j];\n isPathSpec(t) ? pathspecs.push(...toPaths(t as string)) : pathspecs.push(String(t));\n }\n break;\n }\n\n if (!raw.startsWith('-') || raw.length < 2) {\n positionals.push(raw);\n i++;\n continue;\n }\n\n const parsed = expandToken(raw, spec);\n let next = i + 1;\n\n for (const token of parsed) {\n const flag: Flag = {\n name: token.name,\n value: token.value,\n absorbedNext: false,\n isGlobal: false,\n };\n if (\n token.needsNext &&\n flag.value === undefined &&\n next < tokens.length &&\n !isPathSpec(tokens[next])\n ) {\n flag.value = String(tokens[next]);\n flag.absorbedNext = true;\n next++;\n }\n flags.push(flag);\n }\n\n i = next;\n }\n\n return { flags, positionals, pathspecs };\n}\n","import type { ParsedConfigActivity } from '../parse-argv.types';\nimport type { Vulnerability, VulnerabilityCategory } from './vulnerability.types';\n\nexport function* detectConfigWrites({ write }: ParsedConfigActivity): Generator<Vulnerability> {\n for (const config of write) {\n for (const helper of preventUnsafeConfig) {\n const vulnerability = helper(config.key);\n if (vulnerability) {\n yield vulnerability;\n }\n }\n }\n}\n\nfunction preventConfigBuilder(\n config: string | RegExp,\n category: VulnerabilityCategory,\n message = String(config)\n) {\n const regex = typeof config === 'string' ? new RegExp(`\\\\s*${config}`, 'i') : config;\n\n return function preventCommand(key: string): Vulnerability | void {\n if (regex.test(key)) {\n return {\n category,\n message: `Configuring ${message} is not permitted without enabling ${category}`,\n };\n }\n };\n}\n\nconst preventUnsafeConfig = [\n preventConfigBuilder(\n /^\\s*protocol(.[a-z]+)?.allow/i,\n 'allowUnsafeProtocolOverride',\n 'protocol.allow'\n ),\n preventConfigBuilder('core.sshCommand', 'allowUnsafeSshCommand'),\n preventConfigBuilder('core.fsmonitor', 'allowUnsafeFsMonitor'),\n preventConfigBuilder('core.gitProxy', 'allowUnsafeGitProxy'),\n preventConfigBuilder('core.hooksPath', 'allowUnsafeHooksPath'),\n preventConfigBuilder('diff.external', 'allowUnsafeDiffExternal'),\n];\n","import type { Flag } from '../flags/flags.helpers';\nimport type { Vulnerability } from './vulnerability.types';\n\nexport function* detectUploadPack(task: null | string, flags: Flag[]): Generator<Vulnerability> {\n for (const flag of flags) {\n if (/^--(upload|receive)-pack/.test(flag.name)) {\n yield {\n category: 'allowUnsafePack',\n message:\n 'Use of --upload-pack or --receive-pack is not permitted without enabling allowUnsafePack',\n };\n }\n if (task === 'clone' && (/^-\\w*u/.test(flag.name) || flag.name === '--u')) {\n yield {\n category: 'allowUnsafePack',\n message:\n 'Use of clone with option -u is not permitted without enabling allowUnsafePack',\n };\n }\n if (task === 'push' && /^--exec/.test(flag.name)) {\n yield {\n category: 'allowUnsafePack',\n message:\n 'Use of push with option --exec is not permitted without enabling allowUnsafePack',\n };\n }\n }\n}\n","import type { Flag } from '../flags/flags.helpers';\nimport type { ParsedConfigActivity } from '../parse-argv.types';\nimport { detectConfigWrites } from './detect-config-writes';\nimport { detectUploadPack } from './detect-upload-pack';\nimport type {\n ParsedVulnerabilities,\n Vulnerability,\n VulnerabilityCategory,\n} from './vulnerability.types';\n\nexport function vulnerabilityAnalysis(\n task: null | string,\n flags: Flag[],\n config: ParsedConfigActivity\n): ParsedVulnerabilities {\n const vulnerabilities: Vulnerability[] = [\n ...detectUploadPack(task, flags),\n ...detectConfigWrites(config),\n ];\n const categories = vulnerabilities.reduce((all, vulnerability) => {\n return all.add(vulnerability.category);\n }, new Set<VulnerabilityCategory>());\n\n return {\n categories,\n vulnerabilities,\n };\n}\n","import { collectConfigAccess } from './config/analyse-config';\nimport type { Flag } from './flags/flags.helpers';\nimport { parseGlobalFlags } from './flags/parse-global-flags';\nimport { parseTaskFlags } from './flags/parse-task-flags';\nimport type { ParsedArgv, ParsedFlag } from './parse-argv.types';\nimport { vulnerabilityAnalysis } from './vulnerabilities/vulnerability-analysis';\n\n/**\n * Parse the tokens that would be forwarded to a `git` child-process and\n * return a structured summary of what the invocation does.\n */\nexport function parseArgv(...tokens: readonly unknown[]): ParsedArgv {\n const { flags, taskIndex } = parseGlobalFlags(tokens);\n\n const task = taskIndex < tokens.length ? String(tokens[taskIndex]).toLowerCase() : null;\n const taskTokens = task !== null ? tokens.slice(taskIndex + 1) : [];\n\n const { positionals, pathspecs } = parseTaskFlags(taskTokens, task, flags);\n const config = collectConfigAccess(task, flags, positionals);\n\n return {\n task,\n flags: flags.map(toParsedFlag),\n paths: pathspecs,\n config,\n vulnerabilities: vulnerabilityAnalysis(task, flags, config),\n };\n}\n\nfunction toParsedFlag({ value, name }: Flag): ParsedFlag {\n return value !== undefined ? { name, value } : { name };\n}\n"],"names":["scopedFlags","flags","scope","findGlobal","flag","CONFIG_WRITE_FLAGS","CONFIG_READ_FLAGS","CONFIG_WRITE_VERBS","CONFIG_READ_VERBS","detectConfigAction","positionals","name","configOperation","verb","isWrite","key","toOperation","operation","parseAssignment","raw","eq","detectConfigScope","detectConfigOverrideScope","collectWriteFlags","assignment","collectConfigAccess","task","parsedConfig","appendParsedConfigAction","action","config","UNIVERSAL","GLOBAL","COMMANDS","EMPTY","getFlagSpecForTask","spec","expandToken","stem","char","consumes","expandCluster","shortSpec","chars","result","i","remainder","c","parseGlobalFlags","tokens","parsed","next","token","parseTaskFlags","pathspecs","current","isPathSpec","toPaths","j","t","detectConfigWrites","write","helper","preventUnsafeConfig","vulnerability","preventConfigBuilder","category","message","regex","detectUploadPack","vulnerabilityAnalysis","vulnerabilities","all","parseArgv","taskIndex","taskTokens","toParsedFlag","value"],"mappings":"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"}
{"version":3,"file":"index.cjs","sources":["../src/flags/flags.helpers.ts","../src/config/config-operands.ts","../src/config/detect-config-action.ts","../src/config/analyse-config.ts","../src/tokens/flag-specs.ts","../src/tokens/token-expander.ts","../src/flags/parse-global-flags.ts","../src/flags/parse-task-flags.ts","../src/vulnerabilities/detect-vulnerable-config-writes.ts","../src/vulnerabilities/detect-vulnerable-flags.ts","../src/vulnerabilities/vulnerability-analysis.ts","../src/args/parse-argv.ts","../src/env/parse-env.ts","../src/vulnerabilities/vulnerability-check.ts"],"sourcesContent":["export interface Flag {\n name: string;\n value?: string;\n /** Value came from the next token rather than being embedded after `=`. */\n absorbedNext: boolean;\n /** Switch appeared before the git sub-command. */\n isGlobal: boolean;\n}\n\nexport function* scopedFlags(flags: Flag[], scope: 'global' | 'task') {\n const findGlobal = scope === 'global';\n for (const flag of flags) {\n if (flag.isGlobal === findGlobal) {\n yield flag;\n }\n }\n}\n","// Flags that unambiguously signal a write operation on git config.\nexport const CONFIG_WRITE_FLAGS = new Set([\n '--add',\n '--edit',\n '--remove-section',\n '--rename-section',\n '--replace-all',\n '--unset',\n '--unset-all',\n '-e',\n]);\n\n// Flags that unambiguously signal a read operation.\nexport const CONFIG_READ_FLAGS = new Set([\n '--get',\n '--get-all',\n '--get-color',\n '--get-colorbool',\n '--get-regexp',\n '--get-urlmatch',\n '--list',\n '-l',\n]);\n\n// Sub-command verbs accepted as the first positional by newer git versions.\nexport const CONFIG_WRITE_VERBS = new Set([\n 'edit',\n 'remove-section',\n 'rename-section',\n 'set',\n 'unset',\n]);\nexport const CONFIG_READ_VERBS = new Set(['get', 'get-color', 'get-colorbool', 'list']);\n","import type { ConfigScope } from '../args/parse-argv.types';\nimport { type Flag, scopedFlags } from '../flags/flags.helpers';\nimport type { ConfigOperation } from './config.types';\nimport {\n CONFIG_READ_FLAGS,\n CONFIG_READ_VERBS,\n CONFIG_WRITE_FLAGS,\n CONFIG_WRITE_VERBS,\n} from './config-operands';\n\nexport function detectConfigAction(flags: Flag[], positionals: string[]): ConfigOperation | null {\n for (const { name } of scopedFlags(flags, 'task')) {\n if (CONFIG_WRITE_FLAGS.has(name)) {\n return configOperation(true, positionals);\n }\n if (CONFIG_READ_FLAGS.has(name)) {\n return configOperation(false, positionals);\n }\n }\n\n const verb = positionals.at(0)?.toLowerCase();\n\n if (verb === undefined) {\n return null;\n }\n\n if (CONFIG_WRITE_VERBS.has(verb)) {\n return configOperation(true, positionals.slice(1));\n }\n\n if (CONFIG_READ_VERBS.has(verb)) {\n return configOperation(false, positionals.slice(1));\n }\n\n if (positionals.length === 1) {\n return configOperation(false, positionals);\n }\n\n return configOperation(true, positionals);\n}\n\nfunction configOperation(isWrite = false, positionals: string[] = []): ConfigOperation | null {\n const key = positionals.at(0)?.toLowerCase();\n\n if (key === undefined) {\n return null;\n }\n\n return {\n isWrite,\n isRead: !isWrite,\n key,\n value: positionals.at(1),\n };\n}\n\nexport function toOperation(scope: ConfigScope, operation: ConfigOperation) {\n if (operation.isWrite && operation.value !== undefined) {\n return { key: operation.key, value: operation.value, scope };\n }\n return { key: operation.key, scope };\n}\n","import type { ConfigScope, ConfigWrite, ParsedConfigActivity } from '../args/parse-argv.types';\nimport { type Flag, scopedFlags } from '../flags/flags.helpers';\nimport type { ConfigOperation } from './config.types';\nimport { detectConfigAction, toOperation } from './detect-config-action';\n\nfunction parseAssignment(raw: string | undefined): { key: string; value: string } | null {\n const eq = raw?.indexOf('=') || -1;\n\n if (!raw || eq < 0) {\n return null;\n }\n\n return {\n key: raw.slice(0, eq).trim().toLowerCase(),\n value: raw.slice(eq + 1),\n };\n}\n\nfunction detectConfigScope(flags: Flag[]): ConfigScope {\n for (const { name } of scopedFlags(flags, 'task')) {\n switch (name) {\n case '--global':\n return 'global';\n case '--system':\n return 'system';\n case '--worktree':\n return 'worktree';\n case '--local':\n return 'local';\n case '--file':\n case '-f':\n return 'file';\n }\n }\n return 'local';\n}\n\nfunction detectConfigOverrideScope({ name }: Flag): ConfigScope | void {\n if (name === '-c' || name === '--config') {\n return 'inline';\n }\n if (name === '--config-env') {\n return 'env';\n }\n}\n\n/**\n * Generates the stream of ConfigWrite settings found in the supplied flags,\n * triggered by `-c` and `--config` for inline configuration and `--config-env`\n * to set a config setting based on environment variable.\n */\nfunction* collectWriteFlags(flags: Flag[]): Generator<ConfigWrite> {\n for (const flag of flags) {\n const scope = detectConfigOverrideScope(flag);\n const assignment = scope && parseAssignment(flag.value);\n\n if (assignment) {\n yield {\n ...assignment,\n scope,\n };\n }\n }\n}\n\nexport function collectConfigAccess(\n task: string | null,\n flags: Flag[],\n positionals: string[]\n): ParsedConfigActivity {\n const parsedConfig: ParsedConfigActivity = {\n read: [],\n write: [...collectWriteFlags(flags)],\n };\n\n if (task === 'config') {\n appendParsedConfigAction(\n parsedConfig,\n detectConfigScope(flags),\n detectConfigAction(flags, positionals)\n );\n }\n\n return parsedConfig;\n}\n\nfunction appendParsedConfigAction(\n parsedConfig: ParsedConfigActivity,\n scope: ConfigScope,\n action: ConfigOperation | null\n) {\n if (action === null) {\n return;\n }\n\n const config = toOperation(scope, action);\n if (action.isWrite) {\n parsedConfig.write.push(config);\n } else {\n parsedConfig.read.push(config);\n }\n}\n","// ── Option tables ─────────────────────────────────────────────────────────────\n//\n// Each scope has:\n// short – Map<char, consumesNext> (known single-letter switches; true = takes next token)\n// long – Set<stem> (long switch stems, without --, that take the next token)\n//\n// Only switches listed here are \"known\". An unknown char anywhere in a combined\n// cluster causes the entire cluster to be kept as one opaque token.\n\nexport interface FlagSpec {\n readonly short: ReadonlyMap<string, boolean>;\n readonly long: ReadonlySet<string>;\n}\n\nconst UNIVERSAL: FlagSpec = {\n short: new Map([\n ['c', true], // -c <k=v> set config key for this invocation\n ]),\n long: new Set(),\n};\n\nexport const GLOBAL: FlagSpec = {\n short: new Map([\n ['C', true], // -C <path> change working directory\n ['P', false], // -P no pager (alias for --no-pager)\n ['h', false], // -h help\n ['p', false], // -p paginate\n ['v', false], // -v version\n ...UNIVERSAL.short.entries(),\n ]),\n long: new Set([\n 'attr-source',\n 'config-env',\n 'exec-path',\n 'git-dir',\n 'list-cmds',\n 'namespace',\n 'super-prefix',\n 'work-tree',\n ]),\n};\n\nconst COMMANDS: Record<string, FlagSpec> = {\n clone: {\n short: new Map([\n ['b', true], // -b <branch>\n ['j', true], // -j <n> parallel jobs\n ['l', false], // -l local\n ['n', false], // -n no-checkout\n ['o', true], // -o <name> remote name\n ['q', false], // -q quiet\n ['s', false], // -s shared\n ['u', true], // -u <upload-pack>\n ]),\n long: new Set(['branch', 'config', 'jobs', 'origin', 'upload-pack', 'u', 'template']),\n },\n commit: {\n short: new Map([\n ['C', true], // -C <commit> reuse message\n ['F', true], // -F <file> read message from file\n ['c', true], // -c <commit> reedit message\n ['m', true], // -m <msg>\n ['t', true], // -t <template>\n ]),\n long: new Set(['file', 'message', 'reedit-message', 'reuse-message', 'template']),\n },\n config: {\n short: new Map([\n ['e', false], // -e open editor\n ['f', true], // -f <file>\n ['l', false], // -l list\n ]),\n long: new Set(['blob', 'comment', 'default', 'file', 'type', 'value']),\n },\n fetch: {\n short: new Map(),\n long: new Set(['upload-pack']),\n },\n init: {\n short: new Map(),\n long: new Set(['template']),\n },\n pull: {\n short: new Map(),\n long: new Set(['upload-pack']),\n },\n push: {\n short: new Map(),\n long: new Set(['exec', 'receive-pack']),\n },\n};\n\nconst EMPTY: FlagSpec = { short: new Map(), long: new Set() };\n\nexport function getFlagSpecForTask(task?: string | null) {\n const spec = COMMANDS[task ?? ''] ?? EMPTY;\n\n return {\n short: new Map([...UNIVERSAL.short.entries(), ...spec.short.entries()]),\n long: spec.long,\n };\n}\n","import { GLOBAL } from './flag-specs';\n\n/** Parse a single raw token (e.g. `'-m'`, `'--amend'`, `'-uc'`) into one or\n * more switch descriptors. Values are not yet resolved for needsNext=true. */\nexport function expandToken(\n raw: string,\n spec = GLOBAL\n): Array<{\n name: string;\n value?: string;\n needsNext: boolean;\n}> {\n if (raw.startsWith('--')) {\n const eq = raw.indexOf('=');\n if (eq > 2) {\n return [{ name: raw.slice(0, eq), value: raw.slice(eq + 1), needsNext: false }];\n }\n const stem = raw.slice(2);\n return [{ name: raw, needsNext: spec.long.has(stem) }];\n }\n\n // Single short switch\n if (raw.length === 2) {\n const char = raw.charAt(1);\n const consumes = spec.short.get(char);\n return [{ name: raw, needsNext: consumes === true }];\n }\n\n // Combined short cluster: try to expand char-by-char\n return expandCluster(raw, spec.short);\n}\n\nfunction expandCluster(\n raw: string,\n shortSpec: ReadonlyMap<string, boolean>\n): Array<{ name: string; value?: string; needsNext: boolean }> {\n const chars = raw.slice(1).split('');\n const result: Array<{ name: string; value?: string; needsNext: boolean }> = [];\n\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n const consumes = shortSpec.get(char);\n\n if (consumes === undefined) {\n // Unknown char: keep the whole raw token as opaque\n return [{ name: raw, needsNext: false }];\n }\n\n if (consumes) {\n const remainder = chars.slice(i + 1).join('');\n if (remainder) {\n const remainderAllKnown = [...remainder].every((c) => shortSpec.has(c));\n if (!remainderAllKnown) {\n // Remaining chars are the embedded value, not separate flags\n result.push({ name: `-${char}`, value: remainder, needsNext: false });\n return result;\n }\n }\n }\n\n result.push({ name: `-${char}`, needsNext: consumes });\n }\n\n return result;\n}\n","import { expandToken } from '../tokens/token-expander';\nimport type { Flag } from './flags.helpers';\n\nexport interface GlobalFlags {\n flags: Flag[];\n taskIndex: number;\n}\n\nexport function parseGlobalFlags(tokens: readonly unknown[], flags: Flag[] = []): GlobalFlags {\n let i = 0;\n\n while (i < tokens.length) {\n const raw = String(tokens[i]);\n if (!raw.startsWith('-') || raw.length < 2) break;\n\n const parsed = expandToken(raw);\n let next = i + 1;\n\n for (const token of parsed) {\n const flag: Flag = {\n name: token.name,\n value: token.value,\n absorbedNext: false,\n isGlobal: true,\n };\n if (token.needsNext && flag.value === undefined && next < tokens.length) {\n flag.value = String(tokens[next]);\n flag.absorbedNext = true;\n next++;\n }\n flags.push(flag);\n }\n\n i = next;\n }\n\n return { flags, taskIndex: i };\n}\n","import { isPathSpec, toPaths } from '@simple-git/args-pathspec';\n\nimport { getFlagSpecForTask } from '../tokens/flag-specs';\nimport { expandToken } from '../tokens/token-expander';\nimport type { Flag } from './flags.helpers';\n\ntype TaskFlags = {\n flags: Flag[];\n positionals: string[];\n pathspecs: string[];\n};\n\nexport function parseTaskFlags(\n tokens: readonly unknown[],\n task: string | null,\n flags: Flag[] = []\n): TaskFlags {\n const spec = getFlagSpecForTask(task);\n const positionals: string[] = [];\n const pathspecs: string[] = [];\n\n let i = 0;\n while (i < tokens.length) {\n const current = tokens[i];\n\n if (isPathSpec(current)) {\n pathspecs.push(...toPaths(current as string));\n i++;\n continue;\n }\n\n const raw = String(current);\n\n if (raw === '--') {\n for (let j = i + 1; j < tokens.length; j++) {\n const t = tokens[j];\n isPathSpec(t) ? pathspecs.push(...toPaths(t as string)) : pathspecs.push(String(t));\n }\n break;\n }\n\n if (!raw.startsWith('-') || raw.length < 2) {\n positionals.push(raw);\n i++;\n continue;\n }\n\n const parsed = expandToken(raw, spec);\n let next = i + 1;\n\n for (const token of parsed) {\n const flag: Flag = {\n name: token.name,\n value: token.value,\n absorbedNext: false,\n isGlobal: false,\n };\n if (\n token.needsNext &&\n flag.value === undefined &&\n next < tokens.length &&\n !isPathSpec(tokens[next])\n ) {\n flag.value = String(tokens[next]);\n flag.absorbedNext = true;\n next++;\n }\n flags.push(flag);\n }\n\n i = next;\n }\n\n return { flags, positionals, pathspecs };\n}\n","import type { ParsedConfigActivity } from '../args/parse-argv.types';\nimport type { Vulnerability, VulnerabilityCategory } from './vulnerability.types';\n\nexport function* detectVulnerableConfigWrites({\n write,\n}: ParsedConfigActivity): Generator<Vulnerability> {\n for (const config of write) {\n for (const helper of preventUnsafeConfig) {\n const vulnerability = helper(config.key);\n if (vulnerability) {\n yield vulnerability;\n }\n }\n }\n}\n\nfunction preventConfigBuilder(\n config: string | RegExp,\n category: VulnerabilityCategory,\n message = String(config)\n) {\n const regex = typeof config === 'string' ? new RegExp(`\\\\s*${config.toLowerCase()}`) : config;\n\n return function preventCommand(key: string): Vulnerability | void {\n if (regex.test(key)) {\n return {\n category,\n message: `Configuring ${message} is not permitted without enabling ${category}`,\n };\n }\n };\n}\n\nfunction preventExpandedConfigBuilder(config: string, category: VulnerabilityCategory) {\n const regex = new RegExp(`\\\\s*${config.toLowerCase().replace(/\\./g, '(\\..+)?.')}`);\n return preventConfigBuilder(regex, category, config);\n}\n\nconst preventUnsafeConfig = [\n preventConfigBuilder('alias', 'allowUnsafeAlias'),\n preventConfigBuilder('core.askPass', 'allowUnsafeAskPass'),\n preventConfigBuilder('core.editor', 'allowUnsafeEditor'),\n preventConfigBuilder('core.fsmonitor', 'allowUnsafeFsMonitor'),\n preventConfigBuilder('core.gitProxy', 'allowUnsafeGitProxy'),\n preventConfigBuilder('core.hooksPath', 'allowUnsafeHooksPath'),\n preventConfigBuilder('core.pager', 'allowUnsafePager'),\n preventConfigBuilder('core.sshCommand', 'allowUnsafeSshCommand'),\n preventExpandedConfigBuilder('credential.helper', 'allowUnsafeCredentialHelper'),\n preventExpandedConfigBuilder('diff.command', 'allowUnsafeDiffExternal'),\n preventConfigBuilder('diff.external', 'allowUnsafeDiffExternal'),\n preventExpandedConfigBuilder('diff.textconv', 'allowUnsafeDiffTextConv'),\n preventExpandedConfigBuilder('filter.clean', 'allowUnsafeFilter'),\n preventExpandedConfigBuilder('filter.smudge', 'allowUnsafeFilter'),\n preventExpandedConfigBuilder('gpg.program', 'allowUnsafeGpgProgram'),\n preventConfigBuilder('init.templateDir', 'allowUnsafeTemplateDir'),\n preventExpandedConfigBuilder('merge.driver', 'allowUnsafeMergeDriver'),\n preventExpandedConfigBuilder('mergetool.path', 'allowUnsafeMergeDriver'),\n preventExpandedConfigBuilder('mergetool.cmd', 'allowUnsafeMergeDriver'),\n preventExpandedConfigBuilder('protocol.allow', 'allowUnsafeProtocolOverride'),\n preventExpandedConfigBuilder('remote.receivepack', 'allowUnsafePack'),\n preventExpandedConfigBuilder('remote.uploadpack', 'allowUnsafePack'),\n preventConfigBuilder('sequence.editor', 'allowUnsafeEditor'),\n];\n","import type { Flag } from '../flags/flags.helpers';\nimport type { Vulnerability, VulnerabilityCategory } from './vulnerability.types';\n\nexport function* detectVulnerableFlags(\n task: null | string,\n flags: Flag[]\n): Generator<Vulnerability> {\n for (const flag of flags) {\n for (const helper of preventUnsafeFlags) {\n const vulnerability = helper(task, flag.name);\n if (vulnerability) {\n yield vulnerability;\n }\n }\n }\n}\n\nfunction preventFlagBuilder(\n task: string | null,\n flag: string | RegExp,\n category: VulnerabilityCategory,\n name = String(flag)\n) {\n const regex = typeof flag === 'string' ? new RegExp(`\\\\s*${flag.toLowerCase()}`) : flag;\n const message = `Use of ${task ? `${task} with option ` : ''}${name} is not permitted without enabling ${category}`;\n\n return function preventFlag(currentTask: string | null, flagName: string): Vulnerability | void {\n if ((!task || currentTask === task) && regex.test(flagName)) {\n return {\n category,\n message,\n };\n }\n };\n}\n\nconst preventUnsafeFlags = [\n preventFlagBuilder(\n null,\n /--(upload|receive)-pack/,\n 'allowUnsafePack',\n '--upload-pack or --receive-pack'\n ),\n preventFlagBuilder('clone', /^-\\w*u/, 'allowUnsafePack'),\n preventFlagBuilder('clone', '--u', 'allowUnsafePack'),\n preventFlagBuilder('push', '--exec', 'allowUnsafePack'),\n preventFlagBuilder(null, '--template', 'allowUnsafeTemplateDir'),\n];\n","import type { ParsedConfigActivity } from '../args/parse-argv.types';\nimport type { Flag } from '../flags/flags.helpers';\nimport { detectVulnerableConfigWrites } from './detect-vulnerable-config-writes';\nimport { detectVulnerableFlags } from './detect-vulnerable-flags';\nimport type { Vulnerability } from './vulnerability.types';\n\nexport function vulnerabilityAnalysis(\n task: null | string,\n flags: Flag[],\n config: ParsedConfigActivity\n): Vulnerability[] {\n return [...detectVulnerableFlags(task, flags), ...detectVulnerableConfigWrites(config)];\n}\n","import { collectConfigAccess } from '../config/analyse-config';\nimport type { Flag } from '../flags/flags.helpers';\nimport { parseGlobalFlags } from '../flags/parse-global-flags';\nimport { parseTaskFlags } from '../flags/parse-task-flags';\nimport { vulnerabilityAnalysis } from '../vulnerabilities/vulnerability-analysis';\nimport type { ParsedArgv, ParsedFlag } from './parse-argv.types';\n\n/**\n * Parse the tokens that would be forwarded to a `git` child-process and\n * return a structured summary of what the invocation does.\n */\nexport function parseArgv(...tokens: readonly unknown[]): ParsedArgv {\n const { flags, taskIndex } = parseGlobalFlags(tokens);\n\n const task = taskIndex < tokens.length ? String(tokens[taskIndex]).toLowerCase() : null;\n const taskTokens = task !== null ? tokens.slice(taskIndex + 1) : [];\n\n const { positionals, pathspecs } = parseTaskFlags(taskTokens, task, flags);\n const config = collectConfigAccess(task, flags, positionals);\n\n return {\n task,\n flags: flags.map(toParsedFlag),\n paths: pathspecs,\n config,\n vulnerabilities: vulnerabilityAnalysis(task, flags, config),\n };\n}\n\nfunction toParsedFlag({ value, name }: Flag): ParsedFlag {\n return value !== undefined ? { name, value } : { name };\n}\n","import type { ConfigWrite, ParsedConfigActivity } from '../args/parse-argv.types';\nimport type { Vulnerability, VulnerabilityCategory } from '../vulnerabilities/vulnerability.types';\nimport { vulnerabilityAnalysis } from '../vulnerabilities/vulnerability-analysis';\n\nconst GitEnvKeys = {\n 'editor': 'allowUnsafeEditor',\n 'git_askpass': 'allowUnsafeAskPass',\n 'git_config_global': 'allowUnsafeConfigPaths',\n 'git_config_system': 'allowUnsafeConfigPaths',\n 'git_config_count': 'allowUnsafeConfigEnvCount',\n 'git_config': 'allowUnsafeConfigPaths',\n 'git_editor': 'allowUnsafeEditor',\n 'git_exec_path': 'allowUnsafeConfigPaths',\n 'git_external_diff': 'allowUnsafeDiffExternal',\n 'git_pager': 'allowUnsafePager',\n 'git_proxy_command': 'allowUnsafeGitProxy',\n 'git_template_dir': 'allowUnsafeTemplateDir',\n 'git_sequence_editor': 'allowUnsafeEditor',\n 'git_ssh': 'allowUnsafeSshCommand',\n 'git_ssh_command': 'allowUnsafeSshCommand',\n 'pager': 'allowUnsafePager',\n 'prefix': 'allowUnsafeConfigPaths',\n 'ssh_askpass': 'allowUnsafeAskPass',\n} as const satisfies Record<string, VulnerabilityCategory>;\n\ntype GitEnv = Record<string, string> & {\n git_config_count?: string;\n};\n\nfunction* collectConfigByCount(env: GitEnv): Generator<ConfigWrite> {\n const count = parseInt(env.git_config_count ?? '0', 10);\n for (let index = 0; index < count; index++) {\n const key = env[`git_config_key_${index}`];\n const value = env[`git_config_value_${index}`];\n\n if (key !== undefined) {\n yield { key: key.toLowerCase().trim(), value, scope: 'env' };\n }\n }\n}\n\nfunction* collectConfigVulnerabilities(env: GitEnv): Generator<Vulnerability> {\n for (const key of Object.keys(env)) {\n if (isGitEnvKey(key)) {\n const category = GitEnvKeys[key];\n yield {\n category,\n message: `Use of \"${key.toUpperCase()}\" is not permitted without enabling ${category}`,\n };\n }\n }\n}\n\nfunction isGitEnvKey(key: string): key is keyof typeof GitEnvKeys {\n return Object.hasOwn(GitEnvKeys, key);\n}\n\nfunction prepareEnv(env: Record<string, unknown>): GitEnv {\n const gitEnv: GitEnv = {};\n for (const [key, value] of Object.entries(env)) {\n const envKey = key.toLowerCase().trim();\n if (isGitEnvKey(envKey) || envKey.startsWith('git')) {\n gitEnv[envKey] = String(value);\n }\n }\n return gitEnv;\n}\n\nexport function parseEnv(raw: Record<string, unknown>) {\n const env = prepareEnv(raw);\n const config: ParsedConfigActivity = {\n read: [],\n write: [...collectConfigByCount(env)],\n };\n const vulnerabilities = [\n ...collectConfigVulnerabilities(env),\n ...vulnerabilityAnalysis(null, [], config),\n ];\n\n return {\n config,\n vulnerabilities,\n };\n}\n","import { parseArgv } from '../args/parse-argv';\nimport { parseEnv } from '../env/parse-env';\n\n/**\n * Retrieves just the vulnerabilities identified in the supplied varargs tokens\n * and environment variables.\n */\nexport function vulnerabilityCheck(tokens: readonly string[], env: Record<string, unknown>) {\n return [...parseArgv(...tokens).vulnerabilities, ...parseEnv(env).vulnerabilities];\n}\n"],"names":["scopedFlags","flags","scope","findGlobal","flag","CONFIG_WRITE_FLAGS","CONFIG_READ_FLAGS","CONFIG_WRITE_VERBS","CONFIG_READ_VERBS","detectConfigAction","positionals","name","configOperation","verb","isWrite","key","toOperation","operation","parseAssignment","raw","eq","detectConfigScope","detectConfigOverrideScope","collectWriteFlags","assignment","collectConfigAccess","task","parsedConfig","appendParsedConfigAction","action","config","UNIVERSAL","GLOBAL","COMMANDS","EMPTY","getFlagSpecForTask","spec","expandToken","stem","char","consumes","expandCluster","shortSpec","chars","result","i","remainder","c","parseGlobalFlags","tokens","parsed","next","token","parseTaskFlags","pathspecs","current","isPathSpec","toPaths","j","t","detectVulnerableConfigWrites","write","helper","preventUnsafeConfig","vulnerability","preventConfigBuilder","category","message","regex","preventExpandedConfigBuilder","detectVulnerableFlags","preventUnsafeFlags","preventFlagBuilder","currentTask","flagName","vulnerabilityAnalysis","parseArgv","taskIndex","taskTokens","toParsedFlag","value","GitEnvKeys","collectConfigByCount","env","count","index","collectConfigVulnerabilities","isGitEnvKey","prepareEnv","gitEnv","envKey","parseEnv","vulnerabilities","vulnerabilityCheck"],"mappings":"6HASO,SAAUA,EAAYC,EAAeC,EAA0B,CACnE,MAAMC,EAAaD,IAAU,SAC7B,UAAWE,KAAQH,EACZG,EAAK,WAAaD,IACnB,MAAMC,EAGf,CCfO,MAAMC,MAAyB,IAAI,CACvC,QACA,SACA,mBACA,mBACA,gBACA,UACA,cACA,IACH,CAAC,EAGYC,MAAwB,IAAI,CACtC,QACA,YACA,cACA,kBACA,eACA,iBACA,SACA,IACH,CAAC,EAGYC,MAAyB,IAAI,CACvC,OACA,iBACA,iBACA,MACA,OACH,CAAC,EACYC,MAAwB,IAAI,CAAC,MAAO,YAAa,gBAAiB,MAAM,CAAC,ECtB/E,SAASC,EAAmBR,EAAeS,EAA+C,CAC9F,SAAW,CAAE,KAAAC,CAAA,IAAUX,EAAYC,EAAO,MAAM,EAAG,CAChD,GAAII,EAAmB,IAAIM,CAAI,EAC5B,OAAOC,EAAgB,GAAMF,CAAW,EAE3C,GAAIJ,EAAkB,IAAIK,CAAI,EAC3B,OAAOC,EAAgB,GAAOF,CAAW,CAE/C,CAEA,MAAMG,EAAOH,EAAY,GAAG,CAAC,GAAG,YAAA,EAEhC,OAAIG,IAAS,OACH,KAGNN,EAAmB,IAAIM,CAAI,EACrBD,EAAgB,GAAMF,EAAY,MAAM,CAAC,CAAC,EAGhDF,EAAkB,IAAIK,CAAI,EACpBD,EAAgB,GAAOF,EAAY,MAAM,CAAC,CAAC,EAGjDA,EAAY,SAAW,EACjBE,EAAgB,GAAOF,CAAW,EAGrCE,EAAgB,GAAMF,CAAW,CAC3C,CAEA,SAASE,EAAgBE,EAAU,GAAOJ,EAAwB,CAAA,EAA4B,CAC3F,MAAMK,EAAML,EAAY,GAAG,CAAC,GAAG,YAAA,EAE/B,OAAIK,IAAQ,OACF,KAGH,CACJ,QAAAD,EACA,OAAQ,CAACA,EACT,IAAAC,EACA,MAAOL,EAAY,GAAG,CAAC,CAAA,CAE7B,CAEO,SAASM,EAAYd,EAAoBe,EAA4B,CACzE,OAAIA,EAAU,SAAWA,EAAU,QAAU,OACnC,CAAE,IAAKA,EAAU,IAAK,MAAOA,EAAU,MAAO,MAAAf,CAAA,EAEjD,CAAE,IAAKe,EAAU,IAAK,MAAAf,CAAA,CAChC,CCxDA,SAASgB,EAAgBC,EAAgE,CACtF,MAAMC,EAAKD,GAAK,QAAQ,GAAG,GAAK,GAEhC,MAAI,CAACA,GAAOC,EAAK,EACP,KAGH,CACJ,IAAKD,EAAI,MAAM,EAAGC,CAAE,EAAE,KAAA,EAAO,YAAA,EAC7B,MAAOD,EAAI,MAAMC,EAAK,CAAC,CAAA,CAE7B,CAEA,SAASC,EAAkBpB,EAA4B,CACpD,SAAW,CAAE,KAAAU,CAAA,IAAUX,EAAYC,EAAO,MAAM,EAC7C,OAAQU,EAAA,CACL,IAAK,WACF,MAAO,SACV,IAAK,WACF,MAAO,SACV,IAAK,aACF,MAAO,WACV,IAAK,UACF,MAAO,QACV,IAAK,SACL,IAAK,KACF,MAAO,MAAA,CAGhB,MAAO,OACV,CAEA,SAASW,EAA0B,CAAE,KAAAX,GAAkC,CACpE,GAAIA,IAAS,MAAQA,IAAS,WAC3B,MAAO,SAEV,GAAIA,IAAS,eACV,MAAO,KAEb,CAOA,SAAUY,EAAkBtB,EAAuC,CAChE,UAAWG,KAAQH,EAAO,CACvB,MAAMC,EAAQoB,EAA0BlB,CAAI,EACtCoB,EAAatB,GAASgB,EAAgBd,EAAK,KAAK,EAElDoB,IACD,KAAM,CACH,GAAGA,EACH,MAAAtB,CAAA,EAGT,CACH,CAEO,SAASuB,EACbC,EACAzB,EACAS,EACqB,CACrB,MAAMiB,EAAqC,CACxC,KAAM,CAAA,EACN,MAAO,CAAC,GAAGJ,EAAkBtB,CAAK,CAAC,CAAA,EAGtC,OAAIyB,IAAS,UACVE,EACGD,EACAN,EAAkBpB,CAAK,EACvBQ,EAAmBR,EAAOS,CAAW,CAAA,EAIpCiB,CACV,CAEA,SAASC,EACND,EACAzB,EACA2B,EACD,CACC,GAAIA,IAAW,KACZ,OAGH,MAAMC,EAASd,EAAYd,EAAO2B,CAAM,EACpCA,EAAO,QACRF,EAAa,MAAM,KAAKG,CAAM,EAE9BH,EAAa,KAAK,KAAKG,CAAM,CAEnC,CCvFA,MAAMC,EAAsB,CACzB,UAAW,IAAI,CACZ,CAAC,IAAK,EAAI,CAAA,CACZ,CAEJ,EAEaC,EAAmB,CAC7B,MAAO,IAAI,IAAI,CACZ,CAAC,IAAK,EAAI,EACV,CAAC,IAAK,EAAK,EACX,CAAC,IAAK,EAAK,EACX,CAAC,IAAK,EAAK,EACX,CAAC,IAAK,EAAK,EACX,GAAGD,EAAU,MAAM,QAAA,CAAQ,CAC7B,EACD,SAAU,IAAI,CACX,cACA,aACA,YACA,UACA,YACA,YACA,eACA,WAAA,CACF,CACJ,EAEME,EAAqC,CACxC,MAAO,CACJ,UAAW,IAAI,CACZ,CAAC,IAAK,EAAI,EACV,CAAC,IAAK,EAAI,EACV,CAAC,IAAK,EAAK,EACX,CAAC,IAAK,EAAK,EACX,CAAC,IAAK,EAAI,EACV,CAAC,IAAK,EAAK,EACX,CAAC,IAAK,EAAK,EACX,CAAC,IAAK,EAAI,CAAA,CACZ,EACD,KAAM,IAAI,IAAI,CAAC,SAAU,SAAU,OAAQ,SAAU,cAAe,IAAK,UAAU,CAAC,CAAA,EAEvF,OAAQ,CACL,UAAW,IAAI,CACZ,CAAC,IAAK,EAAI,EACV,CAAC,IAAK,EAAI,EACV,CAAC,IAAK,EAAI,EACV,CAAC,IAAK,EAAI,EACV,CAAC,IAAK,EAAI,CAAA,CACZ,EACD,SAAU,IAAI,CAAC,OAAQ,UAAW,iBAAkB,gBAAiB,UAAU,CAAC,CAAA,EAEnF,OAAQ,CACL,UAAW,IAAI,CACZ,CAAC,IAAK,EAAK,EACX,CAAC,IAAK,EAAI,EACV,CAAC,IAAK,EAAK,CAAA,CACb,EACD,KAAM,IAAI,IAAI,CAAC,OAAQ,UAAW,UAAW,OAAQ,OAAQ,OAAO,CAAC,CAAA,EAExE,MAAO,CACJ,UAAW,IACX,KAAM,IAAI,IAAI,CAAC,aAAa,CAAC,CAAA,EAEhC,KAAM,CACH,UAAW,IACX,KAAM,IAAI,IAAI,CAAC,UAAU,CAAC,CAAA,EAE7B,KAAM,CACH,UAAW,IACX,KAAM,IAAI,IAAI,CAAC,aAAa,CAAC,CAAA,EAEhC,KAAM,CACH,UAAW,IACX,KAAM,IAAI,IAAI,CAAC,OAAQ,cAAc,CAAC,CAAA,CAE5C,EAEMC,EAAkB,CAAE,MAAO,IAAI,IAAO,KAAM,IAAI,GAAI,EAEnD,SAASC,EAAmBT,EAAsB,CACtD,MAAMU,EAAOH,EAASP,GAAQ,EAAE,GAAKQ,EAErC,MAAO,CACJ,MAAO,IAAI,IAAI,CAAC,GAAGH,EAAU,MAAM,QAAA,EAAW,GAAGK,EAAK,MAAM,QAAA,CAAS,CAAC,EACtE,KAAMA,EAAK,IAAA,CAEjB,CCjGO,SAASC,EACblB,EACAiB,EAAOJ,EAKP,CACA,GAAIb,EAAI,WAAW,IAAI,EAAG,CACvB,MAAMC,EAAKD,EAAI,QAAQ,GAAG,EAC1B,GAAIC,EAAK,EACN,MAAO,CAAC,CAAE,KAAMD,EAAI,MAAM,EAAGC,CAAE,EAAG,MAAOD,EAAI,MAAMC,EAAK,CAAC,EAAG,UAAW,GAAO,EAEjF,MAAMkB,EAAOnB,EAAI,MAAM,CAAC,EACxB,MAAO,CAAC,CAAE,KAAMA,EAAK,UAAWiB,EAAK,KAAK,IAAIE,CAAI,EAAG,CACxD,CAGA,GAAInB,EAAI,SAAW,EAAG,CACnB,MAAMoB,EAAOpB,EAAI,OAAO,CAAC,EACnBqB,EAAWJ,EAAK,MAAM,IAAIG,CAAI,EACpC,MAAO,CAAC,CAAE,KAAMpB,EAAK,UAAWqB,IAAa,GAAM,CACtD,CAGA,OAAOC,EAActB,EAAKiB,EAAK,KAAK,CACvC,CAEA,SAASK,EACNtB,EACAuB,EAC4D,CAC5D,MAAMC,EAAQxB,EAAI,MAAM,CAAC,EAAE,MAAM,EAAE,EAC7ByB,EAAsE,CAAA,EAE5E,QAASC,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACpC,MAAMN,EAAOI,EAAME,CAAC,EACdL,EAAWE,EAAU,IAAIH,CAAI,EAEnC,GAAIC,IAAa,OAEd,MAAO,CAAC,CAAE,KAAMrB,EAAK,UAAW,GAAO,EAG1C,GAAIqB,EAAU,CACX,MAAMM,EAAYH,EAAM,MAAME,EAAI,CAAC,EAAE,KAAK,EAAE,EAC5C,GAAIC,GAEG,CADsB,CAAC,GAAGA,CAAS,EAAE,MAAOC,GAAML,EAAU,IAAIK,CAAC,CAAC,EAGnE,OAAAH,EAAO,KAAK,CAAE,KAAM,IAAIL,CAAI,GAAI,MAAOO,EAAW,UAAW,EAAA,CAAO,EAC7DF,CAGhB,CAEAA,EAAO,KAAK,CAAE,KAAM,IAAIL,CAAI,GAAI,UAAWC,EAAU,CACxD,CAEA,OAAOI,CACV,CCxDO,SAASI,EAAiBC,EAA4BhD,EAAgB,GAAiB,CAC3F,IAAI4C,EAAI,EAER,KAAOA,EAAII,EAAO,QAAQ,CACvB,MAAM9B,EAAM,OAAO8B,EAAOJ,CAAC,CAAC,EAC5B,GAAI,CAAC1B,EAAI,WAAW,GAAG,GAAKA,EAAI,OAAS,EAAG,MAE5C,MAAM+B,EAASb,EAAYlB,CAAG,EAC9B,IAAIgC,EAAON,EAAI,EAEf,UAAWO,KAASF,EAAQ,CACzB,MAAM9C,EAAa,CAChB,KAAMgD,EAAM,KACZ,MAAOA,EAAM,MACb,aAAc,GACd,SAAU,EAAA,EAETA,EAAM,WAAahD,EAAK,QAAU,QAAa+C,EAAOF,EAAO,SAC9D7C,EAAK,MAAQ,OAAO6C,EAAOE,CAAI,CAAC,EAChC/C,EAAK,aAAe,GACpB+C,KAEHlD,EAAM,KAAKG,CAAI,CAClB,CAEAyC,EAAIM,CACP,CAEA,MAAO,CAAE,MAAAlD,EAAO,UAAW4C,CAAA,CAC9B,CCzBO,SAASQ,EACbJ,EACAvB,EACAzB,EAAgB,CAAA,EACN,CACV,MAAMmC,EAAOD,EAAmBT,CAAI,EAC9BhB,EAAwB,CAAA,EACxB4C,EAAsB,CAAA,EAE5B,IAAIT,EAAI,EACR,KAAOA,EAAII,EAAO,QAAQ,CACvB,MAAMM,EAAUN,EAAOJ,CAAC,EAExB,GAAIW,EAAAA,WAAWD,CAAO,EAAG,CACtBD,EAAU,KAAK,GAAGG,EAAAA,QAAQF,CAAiB,CAAC,EAC5CV,IACA,QACH,CAEA,MAAM1B,EAAM,OAAOoC,CAAO,EAE1B,GAAIpC,IAAQ,KAAM,CACf,QAASuC,EAAIb,EAAI,EAAGa,EAAIT,EAAO,OAAQS,IAAK,CACzC,MAAMC,EAAIV,EAAOS,CAAC,EAClBF,EAAAA,WAAWG,CAAC,EAAIL,EAAU,KAAK,GAAGG,EAAAA,QAAQE,CAAW,CAAC,EAAIL,EAAU,KAAK,OAAOK,CAAC,CAAC,CACrF,CACA,KACH,CAEA,GAAI,CAACxC,EAAI,WAAW,GAAG,GAAKA,EAAI,OAAS,EAAG,CACzCT,EAAY,KAAKS,CAAG,EACpB0B,IACA,QACH,CAEA,MAAMK,EAASb,EAAYlB,EAAKiB,CAAI,EACpC,IAAIe,EAAON,EAAI,EAEf,UAAWO,KAASF,EAAQ,CACzB,MAAM9C,EAAa,CAChB,KAAMgD,EAAM,KACZ,MAAOA,EAAM,MACb,aAAc,GACd,SAAU,EAAA,EAGVA,EAAM,WACNhD,EAAK,QAAU,QACf+C,EAAOF,EAAO,QACd,CAACO,EAAAA,WAAWP,EAAOE,CAAI,CAAC,IAExB/C,EAAK,MAAQ,OAAO6C,EAAOE,CAAI,CAAC,EAChC/C,EAAK,aAAe,GACpB+C,KAEHlD,EAAM,KAAKG,CAAI,CAClB,CAEAyC,EAAIM,CACP,CAEA,MAAO,CAAE,MAAAlD,EAAO,YAAAS,EAAa,UAAA4C,CAAA,CAChC,CCvEO,SAAUM,EAA6B,CAC3C,MAAAC,CACH,EAAmD,CAChD,UAAW/B,KAAU+B,EAClB,UAAWC,KAAUC,EAAqB,CACvC,MAAMC,EAAgBF,EAAOhC,EAAO,GAAG,EACnCkC,IACD,MAAMA,EAEZ,CAEN,CAEA,SAASC,EACNnC,EACAoC,EACAC,EAAU,OAAOrC,CAAM,EACxB,CACC,MAAMsC,EAAQ,OAAOtC,GAAW,SAAW,IAAI,OAAO,OAAOA,EAAO,aAAa,EAAE,EAAIA,EAEvF,OAAO,SAAwBf,EAAmC,CAC/D,GAAIqD,EAAM,KAAKrD,CAAG,EACf,MAAO,CACJ,SAAAmD,EACA,QAAS,eAAeC,CAAO,sCAAsCD,CAAQ,EAAA,CAGtF,CACH,CAEA,SAASG,EAA6BvC,EAAgBoC,EAAiC,CACpF,MAAME,EAAQ,IAAI,OAAO,OAAOtC,EAAO,YAAA,EAAc,QAAQ,MAAO,SAAU,CAAC,EAAE,EACjF,OAAOmC,EAAqBG,EAAOF,EAAUpC,CAAM,CACtD,CAEA,MAAMiC,EAAsB,CACzBE,EAAqB,QAAS,kBAAkB,EAChDA,EAAqB,eAAgB,oBAAoB,EACzDA,EAAqB,cAAe,mBAAmB,EACvDA,EAAqB,iBAAkB,sBAAsB,EAC7DA,EAAqB,gBAAiB,qBAAqB,EAC3DA,EAAqB,iBAAkB,sBAAsB,EAC7DA,EAAqB,aAAc,kBAAkB,EACrDA,EAAqB,kBAAmB,uBAAuB,EAC/DI,EAA6B,oBAAqB,6BAA6B,EAC/EA,EAA6B,eAAgB,yBAAyB,EACtEJ,EAAqB,gBAAiB,yBAAyB,EAC/DI,EAA6B,gBAAiB,yBAAyB,EACvEA,EAA6B,eAAgB,mBAAmB,EAChEA,EAA6B,gBAAiB,mBAAmB,EACjEA,EAA6B,cAAe,uBAAuB,EACnEJ,EAAqB,mBAAoB,wBAAwB,EACjEI,EAA6B,eAAgB,wBAAwB,EACrEA,EAA6B,iBAAkB,wBAAwB,EACvEA,EAA6B,gBAAiB,wBAAwB,EACtEA,EAA6B,iBAAkB,6BAA6B,EAC5EA,EAA6B,qBAAsB,iBAAiB,EACpEA,EAA6B,oBAAqB,iBAAiB,EACnEJ,EAAqB,kBAAmB,mBAAmB,CAC9D,EC3DO,SAAUK,EACd5C,EACAzB,EACyB,CACzB,UAAWG,KAAQH,EAChB,UAAW6D,KAAUS,EAAoB,CACtC,MAAMP,EAAgBF,EAAOpC,EAAMtB,EAAK,IAAI,EACxC4D,IACD,MAAMA,EAEZ,CAEN,CAEA,SAASQ,EACN9C,EACAtB,EACA8D,EACAvD,EAAO,OAAOP,CAAI,EACnB,CACC,MAAMgE,EAAQ,OAAOhE,GAAS,SAAW,IAAI,OAAO,OAAOA,EAAK,aAAa,EAAE,EAAIA,EAC7E+D,EAAU,UAAUzC,EAAO,GAAGA,CAAI,gBAAkB,EAAE,GAAGf,CAAI,sCAAsCuD,CAAQ,GAEjH,OAAO,SAAqBO,EAA4BC,EAAwC,CAC7F,IAAK,CAAChD,GAAQ+C,IAAgB/C,IAAS0C,EAAM,KAAKM,CAAQ,EACvD,MAAO,CACJ,SAAAR,EACA,QAAAC,CAAA,CAGT,CACH,CAEA,MAAMI,EAAqB,CACxBC,EACG,KACA,0BACA,kBACA,iCAAA,EAEHA,EAAmB,QAAS,SAAU,iBAAiB,EACvDA,EAAmB,QAAS,MAAO,iBAAiB,EACpDA,EAAmB,OAAQ,SAAU,iBAAiB,EACtDA,EAAmB,KAAM,aAAc,wBAAwB,CAClE,ECzCO,SAASG,EACbjD,EACAzB,EACA6B,EACgB,CAChB,MAAO,CAAC,GAAGwC,EAAsB5C,EAAMzB,CAAK,EAAG,GAAG2D,EAA6B9B,CAAM,CAAC,CACzF,CCDO,SAAS8C,KAAa3B,EAAwC,CAClE,KAAM,CAAE,MAAAhD,EAAO,UAAA4E,GAAc7B,EAAiBC,CAAM,EAE9CvB,EAAOmD,EAAY5B,EAAO,OAAS,OAAOA,EAAO4B,CAAS,CAAC,EAAE,YAAA,EAAgB,KAC7EC,EAAapD,IAAS,KAAOuB,EAAO,MAAM4B,EAAY,CAAC,EAAI,CAAA,EAE3D,CAAE,YAAAnE,EAAa,UAAA4C,CAAA,EAAcD,EAAeyB,EAAYpD,EAAMzB,CAAK,EACnE6B,EAASL,EAAoBC,EAAMzB,EAAOS,CAAW,EAE3D,MAAO,CACJ,KAAAgB,EACA,MAAOzB,EAAM,IAAI8E,CAAY,EAC7B,MAAOzB,EACP,OAAAxB,EACA,gBAAiB6C,EAAsBjD,EAAMzB,EAAO6B,CAAM,CAAA,CAEhE,CAEA,SAASiD,EAAa,CAAE,MAAAC,EAAO,KAAArE,GAA0B,CACtD,OAAOqE,IAAU,OAAY,CAAE,KAAArE,EAAM,MAAAqE,CAAA,EAAU,CAAE,KAAArE,CAAA,CACpD,CC3BA,MAAMsE,EAAa,CAChB,OAAU,oBACV,YAAe,qBACf,kBAAqB,yBACrB,kBAAqB,yBACrB,iBAAoB,4BACpB,WAAc,yBACd,WAAc,oBACd,cAAiB,yBACjB,kBAAqB,0BACrB,UAAa,mBACb,kBAAqB,sBACrB,iBAAoB,yBACpB,oBAAuB,oBACvB,QAAW,wBACX,gBAAmB,wBACnB,MAAS,mBACT,OAAU,yBACV,YAAe,oBAClB,EAMA,SAAUC,EAAqBC,EAAqC,CACjE,MAAMC,EAAQ,SAASD,EAAI,kBAAoB,IAAK,EAAE,EACtD,QAASE,EAAQ,EAAGA,EAAQD,EAAOC,IAAS,CACzC,MAAMtE,EAAMoE,EAAI,kBAAkBE,CAAK,EAAE,EACnCL,EAAQG,EAAI,oBAAoBE,CAAK,EAAE,EAEzCtE,IAAQ,SACT,KAAM,CAAE,IAAKA,EAAI,YAAA,EAAc,OAAQ,MAAAiE,EAAO,MAAO,KAAA,EAE3D,CACH,CAEA,SAAUM,EAA6BH,EAAuC,CAC3E,UAAWpE,KAAO,OAAO,KAAKoE,CAAG,EAC9B,GAAII,EAAYxE,CAAG,EAAG,CACnB,MAAMmD,EAAWe,EAAWlE,CAAG,EAC/B,KAAM,CACH,SAAAmD,EACA,QAAS,WAAWnD,EAAI,YAAA,CAAa,uCAAuCmD,CAAQ,EAAA,CAE1F,CAEN,CAEA,SAASqB,EAAYxE,EAA6C,CAC/D,OAAO,OAAO,OAAOkE,EAAYlE,CAAG,CACvC,CAEA,SAASyE,EAAWL,EAAsC,CACvD,MAAMM,EAAiB,CAAA,EACvB,SAAW,CAAC1E,EAAKiE,CAAK,IAAK,OAAO,QAAQG,CAAG,EAAG,CAC7C,MAAMO,EAAS3E,EAAI,YAAA,EAAc,KAAA,GAC7BwE,EAAYG,CAAM,GAAKA,EAAO,WAAW,KAAK,KAC/CD,EAAOC,CAAM,EAAI,OAAOV,CAAK,EAEnC,CACA,OAAOS,CACV,CAEO,SAASE,EAASxE,EAA8B,CACpD,MAAMgE,EAAMK,EAAWrE,CAAG,EACpBW,EAA+B,CAClC,KAAM,CAAA,EACN,MAAO,CAAC,GAAGoD,EAAqBC,CAAG,CAAC,CAAA,EAEjCS,EAAkB,CACrB,GAAGN,EAA6BH,CAAG,EACnC,GAAGR,EAAsB,KAAM,CAAA,EAAI7C,CAAM,CAAA,EAG5C,MAAO,CACJ,OAAAA,EACA,gBAAA8D,CAAA,CAEN,CC5EO,SAASC,EAAmB5C,EAA2BkC,EAA8B,CACzF,MAAO,CAAC,GAAGP,EAAU,GAAG3B,CAAM,EAAE,gBAAiB,GAAG0C,EAASR,CAAG,EAAE,eAAe,CACpF"}

@@ -1,4 +0,5 @@

export { parseArgv } from './src/parse-argv';
export type { ConfigRead, ConfigScope, ConfigWrite, ParsedArgv, ParsedFlag, } from './src/parse-argv.types';
export type { Vulnerability, VulnerabilityCategory, } from './src/vulnerabilities/vulnerability.types';
export { vulnerabilityAnalysis } from './src/vulnerabilities/vulnerability-analysis';
export { parseArgv } from './src/args/parse-argv';
export type { ConfigRead, ConfigScope, ConfigWrite, ParsedArgv, ParsedFlag, } from './src/args/parse-argv.types';
export { parseEnv } from './src/env/parse-env';
export type { Vulnerability, VulnerabilityCategory, VulnerabilityCategoryFlags, } from './src/vulnerabilities/vulnerability.types';
export { vulnerabilityCheck } from './src/vulnerabilities/vulnerability-check';

@@ -1,3 +0,3 @@

import { isPathSpec as p, toPaths as m } from "@simple-git/args-pathspec";
function* w(e, t) {
import { isPathSpec as m, toPaths as v } from "@simple-git/args-pathspec";
function* U(e, t) {
const n = t === "global";

@@ -7,3 +7,3 @@ for (const o of e)

}
const x = /* @__PURE__ */ new Set([
const y = /* @__PURE__ */ new Set([
"--add",

@@ -26,3 +26,3 @@ "--edit",

"-l"
]), k = /* @__PURE__ */ new Set([
]), P = /* @__PURE__ */ new Set([
"edit",

@@ -33,14 +33,14 @@ "remove-section",

"unset"
]), y = /* @__PURE__ */ new Set(["get", "get-color", "get-colorbool", "list"]);
function C(e, t) {
for (const { name: o } of w(e, "task")) {
if (x.has(o))
return f(!0, t);
]), E = /* @__PURE__ */ new Set(["get", "get-color", "get-colorbool", "list"]);
function F(e, t) {
for (const { name: o } of U(e, "task")) {
if (y.has(o))
return p(!0, t);
if (S.has(o))
return f(!1, t);
return p(!1, t);
}
const n = t.at(0)?.toLowerCase();
return n === void 0 ? null : k.has(n) ? f(!0, t.slice(1)) : y.has(n) ? f(!1, t.slice(1)) : t.length === 1 ? f(!1, t) : f(!0, t);
return n === void 0 ? null : P.has(n) ? p(!0, t.slice(1)) : E.has(n) ? p(!1, t.slice(1)) : t.length === 1 ? p(!1, t) : p(!0, t);
}
function f(e = !1, t = []) {
function p(e = !1, t = []) {
const n = t.at(0)?.toLowerCase();

@@ -54,6 +54,6 @@ return n === void 0 ? null : {

}
function N(e, t) {
function A(e, t) {
return t.isWrite && t.value !== void 0 ? { key: t.key, value: t.value, scope: e } : { key: t.key, scope: e };
}
function P(e) {
function M(e) {
const t = e?.indexOf("=") || -1;

@@ -65,4 +65,4 @@ return !e || t < 0 ? null : {

}
function U(e) {
for (const { name: t } of w(e, "task"))
function N(e) {
for (const { name: t } of U(e, "task"))
switch (t) {

@@ -83,3 +83,3 @@ case "--global":

}
function A({ name: e }) {
function G({ name: e }) {
if (e === "-c" || e === "--config")

@@ -90,5 +90,5 @@ return "inline";

}
function* F(e) {
function* O(e) {
for (const t of e) {
const n = A(t), o = n && P(t.value);
const n = G(t), o = n && M(t.value);
o && (yield {

@@ -100,20 +100,20 @@ ...o,

}
function M(e, t, n) {
function $(e, t, n) {
const o = {
read: [],
write: [...F(t)]
write: [...O(t)]
};
return e === "config" && G(
return e === "config" && D(
o,
U(t),
C(t, n)
N(t),
F(t, n)
), o;
}
function G(e, t, n) {
function D(e, t, n) {
if (n === null)
return;
const o = N(t, n);
const o = A(t, n);
n.isWrite ? e.write.push(o) : e.read.push(o);
}
const v = {
const x = {
short: /* @__PURE__ */ new Map([

@@ -123,3 +123,3 @@ ["c", !0]

])
}, O = {
}, L = {
short: new Map([

@@ -136,3 +136,3 @@ ["C", !0],

// -v version
...v.short.entries()
...x.short.entries()
]),

@@ -149,3 +149,3 @@ long: /* @__PURE__ */ new Set([

])
}, E = {
}, R = {
clone: {

@@ -170,3 +170,3 @@ short: /* @__PURE__ */ new Map([

]),
long: /* @__PURE__ */ new Set(["branch", "config", "jobs", "origin", "upload-pack", "u"])
long: /* @__PURE__ */ new Set(["branch", "config", "jobs", "origin", "upload-pack", "u", "template"])
},

@@ -203,2 +203,6 @@ commit: {

},
init: {
short: /* @__PURE__ */ new Map(),
long: /* @__PURE__ */ new Set(["template"])
},
pull: {

@@ -212,11 +216,11 @@ short: /* @__PURE__ */ new Map(),

}
}, I = { short: /* @__PURE__ */ new Map(), long: /* @__PURE__ */ new Set() };
function L(e) {
const t = E[e ?? ""] ?? I;
}, T = { short: /* @__PURE__ */ new Map(), long: /* @__PURE__ */ new Set() };
function I(e) {
const t = R[e ?? ""] ?? T;
return {
short: new Map([...v.short.entries(), ...t.short.entries()]),
short: new Map([...x.short.entries(), ...t.short.entries()]),
long: t.long
};
}
function b(e, t = O) {
function C(e, t = L) {
if (e.startsWith("--")) {

@@ -233,20 +237,20 @@ const n = e.indexOf("=");

}
return R(e, t.short);
return W(e, t.short);
}
function R(e, t) {
function W(e, t) {
const n = e.slice(1).split(""), o = [];
for (let a = 0; a < n.length; a++) {
const s = n[a], r = t.get(s);
for (let s = 0; s < n.length; s++) {
const l = n[s], r = t.get(l);
if (r === void 0)
return [{ name: e, needsNext: !1 }];
if (r) {
const l = n.slice(a + 1).join("");
if (l && ![...l].every((h) => t.has(h)))
return o.push({ name: `-${s}`, value: l, needsNext: !1 }), o;
const a = n.slice(s + 1).join("");
if (a && ![...a].every((w) => t.has(w)))
return o.push({ name: `-${l}`, value: a, needsNext: !1 }), o;
}
o.push({ name: `-${s}`, needsNext: r });
o.push({ name: `-${l}`, needsNext: r });
}
return o;
}
function W(e, t = []) {
function j(e, t = []) {
let n = 0;

@@ -256,6 +260,6 @@ for (; n < e.length; ) {

if (!o.startsWith("-") || o.length < 2) break;
const a = b(o);
let s = n + 1;
for (const r of a) {
const l = {
const s = C(o);
let l = n + 1;
for (const r of s) {
const a = {
name: r.name,

@@ -266,47 +270,49 @@ value: r.value,

};
r.needsNext && l.value === void 0 && s < e.length && (l.value = String(e[s]), l.absorbedNext = !0, s++), t.push(l);
r.needsNext && a.value === void 0 && l < e.length && (a.value = String(e[l]), a.absorbedNext = !0, l++), t.push(a);
}
n = s;
n = l;
}
return { flags: t, taskIndex: n };
}
function _(e, t, n = []) {
const o = L(t), a = [], s = [];
function B(e, t, n = []) {
const o = I(t), s = [], l = [];
let r = 0;
for (; r < e.length; ) {
const l = e[r];
if (p(l)) {
s.push(...m(l)), r++;
const a = e[r];
if (m(a)) {
l.push(...v(a)), r++;
continue;
}
const u = String(l);
if (u === "--") {
for (let c = r + 1; c < e.length; c++) {
const i = e[c];
p(i) ? s.push(...m(i)) : s.push(String(i));
const f = String(a);
if (f === "--") {
for (let g = r + 1; g < e.length; g++) {
const u = e[g];
m(u) ? l.push(...v(u)) : l.push(String(u));
}
break;
}
if (!u.startsWith("-") || u.length < 2) {
a.push(u), r++;
if (!f.startsWith("-") || f.length < 2) {
s.push(f), r++;
continue;
}
const h = b(u, o);
const w = C(f, o);
let d = r + 1;
for (const c of h) {
const i = {
name: c.name,
value: c.value,
for (const g of w) {
const u = {
name: g.name,
value: g.value,
absorbedNext: !1,
isGlobal: !1
};
c.needsNext && i.value === void 0 && d < e.length && !p(e[d]) && (i.value = String(e[d]), i.absorbedNext = !0, d++), n.push(i);
g.needsNext && u.value === void 0 && d < e.length && !m(e[d]) && (u.value = String(e[d]), u.absorbedNext = !0, d++), n.push(u);
}
r = d;
}
return { flags: n, positionals: a, pathspecs: s };
return { flags: n, positionals: s, pathspecs: l };
}
function* T({ write: e }) {
function* V({
write: e
}) {
for (const t of e)
for (const n of $) {
for (const n of q) {
const o = n(t.key);

@@ -316,6 +322,6 @@ o && (yield o);

}
function g(e, t, n = String(e)) {
const o = typeof e == "string" ? new RegExp(`\\s*${e}`, "i") : e;
return function(s) {
if (o.test(s))
function c(e, t, n = String(e)) {
const o = typeof e == "string" ? new RegExp(`\\s*${e.toLowerCase()}`) : e;
return function(l) {
if (o.test(l))
return {

@@ -327,54 +333,145 @@ category: t,

}
const $ = [
g(
/^\s*protocol(.[a-z]+)?.allow/i,
"allowUnsafeProtocolOverride",
"protocol.allow"
),
g("core.sshCommand", "allowUnsafeSshCommand"),
g("core.fsmonitor", "allowUnsafeFsMonitor"),
g("core.gitProxy", "allowUnsafeGitProxy"),
g("core.hooksPath", "allowUnsafeHooksPath"),
g("diff.external", "allowUnsafeDiffExternal")
function i(e, t) {
const n = new RegExp(`\\s*${e.toLowerCase().replace(/\./g, "(..+)?.")}`);
return c(n, t, e);
}
const q = [
c("alias", "allowUnsafeAlias"),
c("core.askPass", "allowUnsafeAskPass"),
c("core.editor", "allowUnsafeEditor"),
c("core.fsmonitor", "allowUnsafeFsMonitor"),
c("core.gitProxy", "allowUnsafeGitProxy"),
c("core.hooksPath", "allowUnsafeHooksPath"),
c("core.pager", "allowUnsafePager"),
c("core.sshCommand", "allowUnsafeSshCommand"),
i("credential.helper", "allowUnsafeCredentialHelper"),
i("diff.command", "allowUnsafeDiffExternal"),
c("diff.external", "allowUnsafeDiffExternal"),
i("diff.textconv", "allowUnsafeDiffTextConv"),
i("filter.clean", "allowUnsafeFilter"),
i("filter.smudge", "allowUnsafeFilter"),
i("gpg.program", "allowUnsafeGpgProgram"),
c("init.templateDir", "allowUnsafeTemplateDir"),
i("merge.driver", "allowUnsafeMergeDriver"),
i("mergetool.path", "allowUnsafeMergeDriver"),
i("mergetool.cmd", "allowUnsafeMergeDriver"),
i("protocol.allow", "allowUnsafeProtocolOverride"),
i("remote.receivepack", "allowUnsafePack"),
i("remote.uploadpack", "allowUnsafePack"),
c("sequence.editor", "allowUnsafeEditor")
];
function* j(e, t) {
function* K(e, t) {
for (const n of t)
/^--(upload|receive)-pack/.test(n.name) && (yield {
category: "allowUnsafePack",
message: "Use of --upload-pack or --receive-pack is not permitted without enabling allowUnsafePack"
}), e === "clone" && (/^-\w*u/.test(n.name) || n.name === "--u") && (yield {
category: "allowUnsafePack",
message: "Use of clone with option -u is not permitted without enabling allowUnsafePack"
}), e === "push" && /^--exec/.test(n.name) && (yield {
category: "allowUnsafePack",
message: "Use of push with option --exec is not permitted without enabling allowUnsafePack"
});
for (const o of H) {
const s = o(e, n.name);
s && (yield s);
}
}
function B(e, t, n) {
const o = [
...j(e, t),
...T(n)
];
return {
categories: o.reduce((s, r) => s.add(r.category), /* @__PURE__ */ new Set()),
vulnerabilities: o
function h(e, t, n, o = String(t)) {
const s = typeof t == "string" ? new RegExp(`\\s*${t.toLowerCase()}`) : t, l = `Use of ${e ? `${e} with option ` : ""}${o} is not permitted without enabling ${n}`;
return function(a, f) {
if ((!e || a === e) && s.test(f))
return {
category: n,
message: l
};
};
}
function V(...e) {
const { flags: t, taskIndex: n } = W(e), o = n < e.length ? String(e[n]).toLowerCase() : null, a = o !== null ? e.slice(n + 1) : [], { positionals: s, pathspecs: r } = _(a, o, t), l = M(o, t, s);
const H = [
h(
null,
/--(upload|receive)-pack/,
"allowUnsafePack",
"--upload-pack or --receive-pack"
),
h("clone", /^-\w*u/, "allowUnsafePack"),
h("clone", "--u", "allowUnsafePack"),
h("push", "--exec", "allowUnsafePack"),
h(null, "--template", "allowUnsafeTemplateDir")
];
function b(e, t, n) {
return [...K(e, t), ...V(n)];
}
function Y(...e) {
const { flags: t, taskIndex: n } = j(e), o = n < e.length ? String(e[n]).toLowerCase() : null, s = o !== null ? e.slice(n + 1) : [], { positionals: l, pathspecs: r } = B(s, o, t), a = $(o, t, l);
return {
task: o,
flags: t.map(D),
flags: t.map(z),
paths: r,
config: l,
vulnerabilities: B(o, t, l)
config: a,
vulnerabilities: b(o, t, a)
};
}
function D({ value: e, name: t }) {
function z({ value: e, name: t }) {
return e !== void 0 ? { name: t, value: e } : { name: t };
}
const _ = {
editor: "allowUnsafeEditor",
git_askpass: "allowUnsafeAskPass",
git_config_global: "allowUnsafeConfigPaths",
git_config_system: "allowUnsafeConfigPaths",
git_config_count: "allowUnsafeConfigEnvCount",
git_config: "allowUnsafeConfigPaths",
git_editor: "allowUnsafeEditor",
git_exec_path: "allowUnsafeConfigPaths",
git_external_diff: "allowUnsafeDiffExternal",
git_pager: "allowUnsafePager",
git_proxy_command: "allowUnsafeGitProxy",
git_template_dir: "allowUnsafeTemplateDir",
git_sequence_editor: "allowUnsafeEditor",
git_ssh: "allowUnsafeSshCommand",
git_ssh_command: "allowUnsafeSshCommand",
pager: "allowUnsafePager",
prefix: "allowUnsafeConfigPaths",
ssh_askpass: "allowUnsafeAskPass"
};
function* J(e) {
const t = parseInt(e.git_config_count ?? "0", 10);
for (let n = 0; n < t; n++) {
const o = e[`git_config_key_${n}`], s = e[`git_config_value_${n}`];
o !== void 0 && (yield { key: o.toLowerCase().trim(), value: s, scope: "env" });
}
}
function* Q(e) {
for (const t of Object.keys(e))
if (k(t)) {
const n = _[t];
yield {
category: n,
message: `Use of "${t.toUpperCase()}" is not permitted without enabling ${n}`
};
}
}
function k(e) {
return Object.hasOwn(_, e);
}
function X(e) {
const t = {};
for (const [n, o] of Object.entries(e)) {
const s = n.toLowerCase().trim();
(k(s) || s.startsWith("git")) && (t[s] = String(o));
}
return t;
}
function Z(e) {
const t = X(e), n = {
read: [],
write: [...J(t)]
}, o = [
...Q(t),
...b(null, [], n)
];
return {
config: n,
vulnerabilities: o
};
}
function te(e, t) {
return [...Y(...e).vulnerabilities, ...Z(t).vulnerabilities];
}
export {
V as parseArgv,
B as vulnerabilityAnalysis
Y as parseArgv,
Z as parseEnv,
te as vulnerabilityCheck
};
//# sourceMappingURL=index.mjs.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.mjs","sources":["../src/flags/flags.helpers.ts","../src/config/config-operands.ts","../src/config/detect-config-action.ts","../src/config/analyse-config.ts","../src/tokens/flag-specs.ts","../src/tokens/token-expander.ts","../src/flags/parse-global-flags.ts","../src/flags/parse-task-flags.ts","../src/vulnerabilities/detect-config-writes.ts","../src/vulnerabilities/detect-upload-pack.ts","../src/vulnerabilities/vulnerability-analysis.ts","../src/parse-argv.ts"],"sourcesContent":["export interface Flag {\n name: string;\n value?: string;\n /** Value came from the next token rather than being embedded after `=`. */\n absorbedNext: boolean;\n /** Switch appeared before the git sub-command. */\n isGlobal: boolean;\n}\n\nexport function* scopedFlags(flags: Flag[], scope: 'global' | 'task') {\n const findGlobal = scope === 'global';\n for (const flag of flags) {\n if (flag.isGlobal === findGlobal) {\n yield flag;\n }\n }\n}\n","// Flags that unambiguously signal a write operation on git config.\nexport const CONFIG_WRITE_FLAGS = new Set([\n '--add',\n '--edit',\n '--remove-section',\n '--rename-section',\n '--replace-all',\n '--unset',\n '--unset-all',\n '-e',\n]);\n\n// Flags that unambiguously signal a read operation.\nexport const CONFIG_READ_FLAGS = new Set([\n '--get',\n '--get-all',\n '--get-color',\n '--get-colorbool',\n '--get-regexp',\n '--get-urlmatch',\n '--list',\n '-l',\n]);\n\n// Sub-command verbs accepted as the first positional by newer git versions.\nexport const CONFIG_WRITE_VERBS = new Set([\n 'edit',\n 'remove-section',\n 'rename-section',\n 'set',\n 'unset',\n]);\nexport const CONFIG_READ_VERBS = new Set(['get', 'get-color', 'get-colorbool', 'list']);\n","import { type Flag, scopedFlags } from '../flags/flags.helpers';\nimport type { ConfigScope } from '../parse-argv.types';\nimport type { ConfigOperation } from './config.types';\nimport {\n CONFIG_READ_FLAGS,\n CONFIG_READ_VERBS,\n CONFIG_WRITE_FLAGS,\n CONFIG_WRITE_VERBS,\n} from './config-operands';\n\nexport function detectConfigAction(flags: Flag[], positionals: string[]): ConfigOperation | null {\n for (const { name } of scopedFlags(flags, 'task')) {\n if (CONFIG_WRITE_FLAGS.has(name)) {\n return configOperation(true, positionals);\n }\n if (CONFIG_READ_FLAGS.has(name)) {\n return configOperation(false, positionals);\n }\n }\n\n const verb = positionals.at(0)?.toLowerCase();\n\n if (verb === undefined) {\n return null;\n }\n\n if (CONFIG_WRITE_VERBS.has(verb)) {\n return configOperation(true, positionals.slice(1));\n }\n\n if (CONFIG_READ_VERBS.has(verb)) {\n return configOperation(false, positionals.slice(1));\n }\n\n if (positionals.length === 1) {\n return configOperation(false, positionals);\n }\n\n return configOperation(true, positionals);\n}\n\nfunction configOperation(isWrite = false, positionals: string[] = []): ConfigOperation | null {\n const key = positionals.at(0)?.toLowerCase();\n\n if (key === undefined) {\n return null;\n }\n\n return {\n isWrite,\n isRead: !isWrite,\n key,\n value: positionals.at(1),\n };\n}\n\nexport function toOperation(scope: ConfigScope, operation: ConfigOperation) {\n if (operation.isWrite && operation.value !== undefined) {\n return { key: operation.key, value: operation.value, scope };\n }\n return { key: operation.key, scope };\n}\n","import { type Flag, scopedFlags } from '../flags/flags.helpers';\nimport type { ConfigScope, ConfigWrite, ParsedConfigActivity } from '../parse-argv.types';\nimport type { ConfigOperation } from './config.types';\nimport { detectConfigAction, toOperation } from './detect-config-action';\n\nfunction parseAssignment(raw: string | undefined): { key: string; value: string } | null {\n const eq = raw?.indexOf('=') || -1;\n\n if (!raw || eq < 0) {\n return null;\n }\n\n return {\n key: raw.slice(0, eq).trim().toLowerCase(),\n value: raw.slice(eq + 1),\n };\n}\n\nfunction detectConfigScope(flags: Flag[]): ConfigScope {\n for (const { name } of scopedFlags(flags, 'task')) {\n switch (name) {\n case '--global':\n return 'global';\n case '--system':\n return 'system';\n case '--worktree':\n return 'worktree';\n case '--local':\n return 'local';\n case '--file':\n case '-f':\n return 'file';\n }\n }\n return 'local';\n}\n\nfunction detectConfigOverrideScope({ name }: Flag): ConfigScope | void {\n if (name === '-c' || name === '--config') {\n return 'inline';\n }\n if (name === '--config-env') {\n return 'env';\n }\n}\n\n/**\n * Generates the stream of ConfigWrite settings found in the supplied flags,\n * triggered by `-c` and `--config` for inline configuration and `--config-env`\n * to set a config setting based on environment variable.\n */\nfunction* collectWriteFlags(flags: Flag[]): Generator<ConfigWrite> {\n for (const flag of flags) {\n const scope = detectConfigOverrideScope(flag);\n const assignment = scope && parseAssignment(flag.value);\n\n if (assignment) {\n yield {\n ...assignment,\n scope,\n };\n }\n }\n}\n\nexport function collectConfigAccess(\n task: string | null,\n flags: Flag[],\n positionals: string[]\n): ParsedConfigActivity {\n const parsedConfig: ParsedConfigActivity = {\n read: [],\n write: [...collectWriteFlags(flags)],\n };\n\n if (task === 'config') {\n appendParsedConfigAction(\n parsedConfig,\n detectConfigScope(flags),\n detectConfigAction(flags, positionals)\n );\n }\n\n return parsedConfig;\n}\n\nfunction appendParsedConfigAction(\n parsedConfig: ParsedConfigActivity,\n scope: ConfigScope,\n action: ConfigOperation | null\n) {\n if (action === null) {\n return;\n }\n\n const config = toOperation(scope, action);\n if (action.isWrite) {\n parsedConfig.write.push(config);\n } else {\n parsedConfig.read.push(config);\n }\n}\n","// ── Option tables ─────────────────────────────────────────────────────────────\n//\n// Each scope has:\n// short – Map<char, consumesNext> (known single-letter switches; true = takes next token)\n// long – Set<stem> (long switch stems, without --, that take the next token)\n//\n// Only switches listed here are \"known\". An unknown char anywhere in a combined\n// cluster causes the entire cluster to be kept as one opaque token.\n\nexport interface FlagSpec {\n readonly short: ReadonlyMap<string, boolean>;\n readonly long: ReadonlySet<string>;\n}\n\nconst UNIVERSAL: FlagSpec = {\n short: new Map([\n ['c', true], // -c <k=v> set config key for this invocation\n ]),\n long: new Set(),\n};\n\nexport const GLOBAL: FlagSpec = {\n short: new Map([\n ['C', true], // -C <path> change working directory\n ['P', false], // -P no pager (alias for --no-pager)\n ['h', false], // -h help\n ['p', false], // -p paginate\n ['v', false], // -v version\n ...UNIVERSAL.short.entries(),\n ]),\n long: new Set([\n 'attr-source',\n 'config-env',\n 'exec-path',\n 'git-dir',\n 'list-cmds',\n 'namespace',\n 'super-prefix',\n 'work-tree',\n ]),\n};\n\nconst COMMANDS: Record<string, FlagSpec> = {\n clone: {\n short: new Map([\n ['b', true], // -b <branch>\n ['j', true], // -j <n> parallel jobs\n ['l', false], // -l local\n ['n', false], // -n no-checkout\n ['o', true], // -o <name> remote name\n ['q', false], // -q quiet\n ['s', false], // -s shared\n ['u', true], // -u <upload-pack>\n ]),\n long: new Set(['branch', 'config', 'jobs', 'origin', 'upload-pack', 'u']),\n },\n commit: {\n short: new Map([\n ['C', true], // -C <commit> reuse message\n ['F', true], // -F <file> read message from file\n ['c', true], // -c <commit> reedit message\n ['m', true], // -m <msg>\n ['t', true], // -t <template>\n ]),\n long: new Set(['file', 'message', 'reedit-message', 'reuse-message', 'template']),\n },\n config: {\n short: new Map([\n ['e', false], // -e open editor\n ['f', true], // -f <file>\n ['l', false], // -l list\n ]),\n long: new Set(['blob', 'comment', 'default', 'file', 'type', 'value']),\n },\n fetch: {\n short: new Map(),\n long: new Set(['upload-pack']),\n },\n pull: {\n short: new Map(),\n long: new Set(['upload-pack']),\n },\n push: {\n short: new Map(),\n long: new Set(['exec', 'receive-pack']),\n },\n};\n\nconst EMPTY: FlagSpec = { short: new Map(), long: new Set() };\n\nexport function getFlagSpecForTask(task?: string | null) {\n const spec = COMMANDS[task ?? ''] ?? EMPTY;\n\n return {\n short: new Map([...UNIVERSAL.short.entries(), ...spec.short.entries()]),\n long: spec.long,\n };\n}\n","import { GLOBAL } from './flag-specs';\n\n/** Parse a single raw token (e.g. `'-m'`, `'--amend'`, `'-uc'`) into one or\n * more switch descriptors. Values are not yet resolved for needsNext=true. */\nexport function expandToken(\n raw: string,\n spec = GLOBAL\n): Array<{\n name: string;\n value?: string;\n needsNext: boolean;\n}> {\n if (raw.startsWith('--')) {\n const eq = raw.indexOf('=');\n if (eq > 2) {\n return [{ name: raw.slice(0, eq), value: raw.slice(eq + 1), needsNext: false }];\n }\n const stem = raw.slice(2);\n return [{ name: raw, needsNext: spec.long.has(stem) }];\n }\n\n // Single short switch\n if (raw.length === 2) {\n const char = raw.charAt(1);\n const consumes = spec.short.get(char);\n return [{ name: raw, needsNext: consumes === true }];\n }\n\n // Combined short cluster: try to expand char-by-char\n return expandCluster(raw, spec.short);\n}\n\nfunction expandCluster(\n raw: string,\n shortSpec: ReadonlyMap<string, boolean>\n): Array<{ name: string; value?: string; needsNext: boolean }> {\n const chars = raw.slice(1).split('');\n const result: Array<{ name: string; value?: string; needsNext: boolean }> = [];\n\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n const consumes = shortSpec.get(char);\n\n if (consumes === undefined) {\n // Unknown char: keep the whole raw token as opaque\n return [{ name: raw, needsNext: false }];\n }\n\n if (consumes) {\n const remainder = chars.slice(i + 1).join('');\n if (remainder) {\n const remainderAllKnown = [...remainder].every((c) => shortSpec.has(c));\n if (!remainderAllKnown) {\n // Remaining chars are the embedded value, not separate flags\n result.push({ name: `-${char}`, value: remainder, needsNext: false });\n return result;\n }\n }\n }\n\n result.push({ name: `-${char}`, needsNext: consumes });\n }\n\n return result;\n}\n","import { expandToken } from '../tokens/token-expander';\nimport type { Flag } from './flags.helpers';\n\nexport interface GlobalFlags {\n flags: Flag[];\n taskIndex: number;\n}\n\nexport function parseGlobalFlags(tokens: readonly unknown[], flags: Flag[] = []): GlobalFlags {\n let i = 0;\n\n while (i < tokens.length) {\n const raw = String(tokens[i]);\n if (!raw.startsWith('-') || raw.length < 2) break;\n\n const parsed = expandToken(raw);\n let next = i + 1;\n\n for (const token of parsed) {\n const flag: Flag = {\n name: token.name,\n value: token.value,\n absorbedNext: false,\n isGlobal: true,\n };\n if (token.needsNext && flag.value === undefined && next < tokens.length) {\n flag.value = String(tokens[next]);\n flag.absorbedNext = true;\n next++;\n }\n flags.push(flag);\n }\n\n i = next;\n }\n\n return { flags, taskIndex: i };\n}\n","import { isPathSpec, toPaths } from '@simple-git/args-pathspec';\n\nimport { getFlagSpecForTask } from '../tokens/flag-specs';\nimport { expandToken } from '../tokens/token-expander';\nimport type { Flag } from './flags.helpers';\n\ntype TaskFlags = {\n flags: Flag[];\n positionals: string[];\n pathspecs: string[];\n};\n\nexport function parseTaskFlags(\n tokens: readonly unknown[],\n task: string | null,\n flags: Flag[] = []\n): TaskFlags {\n const spec = getFlagSpecForTask(task);\n const positionals: string[] = [];\n const pathspecs: string[] = [];\n\n let i = 0;\n while (i < tokens.length) {\n const current = tokens[i];\n\n if (isPathSpec(current)) {\n pathspecs.push(...toPaths(current as string));\n i++;\n continue;\n }\n\n const raw = String(current);\n\n if (raw === '--') {\n for (let j = i + 1; j < tokens.length; j++) {\n const t = tokens[j];\n isPathSpec(t) ? pathspecs.push(...toPaths(t as string)) : pathspecs.push(String(t));\n }\n break;\n }\n\n if (!raw.startsWith('-') || raw.length < 2) {\n positionals.push(raw);\n i++;\n continue;\n }\n\n const parsed = expandToken(raw, spec);\n let next = i + 1;\n\n for (const token of parsed) {\n const flag: Flag = {\n name: token.name,\n value: token.value,\n absorbedNext: false,\n isGlobal: false,\n };\n if (\n token.needsNext &&\n flag.value === undefined &&\n next < tokens.length &&\n !isPathSpec(tokens[next])\n ) {\n flag.value = String(tokens[next]);\n flag.absorbedNext = true;\n next++;\n }\n flags.push(flag);\n }\n\n i = next;\n }\n\n return { flags, positionals, pathspecs };\n}\n","import type { ParsedConfigActivity } from '../parse-argv.types';\nimport type { Vulnerability, VulnerabilityCategory } from './vulnerability.types';\n\nexport function* detectConfigWrites({ write }: ParsedConfigActivity): Generator<Vulnerability> {\n for (const config of write) {\n for (const helper of preventUnsafeConfig) {\n const vulnerability = helper(config.key);\n if (vulnerability) {\n yield vulnerability;\n }\n }\n }\n}\n\nfunction preventConfigBuilder(\n config: string | RegExp,\n category: VulnerabilityCategory,\n message = String(config)\n) {\n const regex = typeof config === 'string' ? new RegExp(`\\\\s*${config}`, 'i') : config;\n\n return function preventCommand(key: string): Vulnerability | void {\n if (regex.test(key)) {\n return {\n category,\n message: `Configuring ${message} is not permitted without enabling ${category}`,\n };\n }\n };\n}\n\nconst preventUnsafeConfig = [\n preventConfigBuilder(\n /^\\s*protocol(.[a-z]+)?.allow/i,\n 'allowUnsafeProtocolOverride',\n 'protocol.allow'\n ),\n preventConfigBuilder('core.sshCommand', 'allowUnsafeSshCommand'),\n preventConfigBuilder('core.fsmonitor', 'allowUnsafeFsMonitor'),\n preventConfigBuilder('core.gitProxy', 'allowUnsafeGitProxy'),\n preventConfigBuilder('core.hooksPath', 'allowUnsafeHooksPath'),\n preventConfigBuilder('diff.external', 'allowUnsafeDiffExternal'),\n];\n","import type { Flag } from '../flags/flags.helpers';\nimport type { Vulnerability } from './vulnerability.types';\n\nexport function* detectUploadPack(task: null | string, flags: Flag[]): Generator<Vulnerability> {\n for (const flag of flags) {\n if (/^--(upload|receive)-pack/.test(flag.name)) {\n yield {\n category: 'allowUnsafePack',\n message:\n 'Use of --upload-pack or --receive-pack is not permitted without enabling allowUnsafePack',\n };\n }\n if (task === 'clone' && (/^-\\w*u/.test(flag.name) || flag.name === '--u')) {\n yield {\n category: 'allowUnsafePack',\n message:\n 'Use of clone with option -u is not permitted without enabling allowUnsafePack',\n };\n }\n if (task === 'push' && /^--exec/.test(flag.name)) {\n yield {\n category: 'allowUnsafePack',\n message:\n 'Use of push with option --exec is not permitted without enabling allowUnsafePack',\n };\n }\n }\n}\n","import type { Flag } from '../flags/flags.helpers';\nimport type { ParsedConfigActivity } from '../parse-argv.types';\nimport { detectConfigWrites } from './detect-config-writes';\nimport { detectUploadPack } from './detect-upload-pack';\nimport type {\n ParsedVulnerabilities,\n Vulnerability,\n VulnerabilityCategory,\n} from './vulnerability.types';\n\nexport function vulnerabilityAnalysis(\n task: null | string,\n flags: Flag[],\n config: ParsedConfigActivity\n): ParsedVulnerabilities {\n const vulnerabilities: Vulnerability[] = [\n ...detectUploadPack(task, flags),\n ...detectConfigWrites(config),\n ];\n const categories = vulnerabilities.reduce((all, vulnerability) => {\n return all.add(vulnerability.category);\n }, new Set<VulnerabilityCategory>());\n\n return {\n categories,\n vulnerabilities,\n };\n}\n","import { collectConfigAccess } from './config/analyse-config';\nimport type { Flag } from './flags/flags.helpers';\nimport { parseGlobalFlags } from './flags/parse-global-flags';\nimport { parseTaskFlags } from './flags/parse-task-flags';\nimport type { ParsedArgv, ParsedFlag } from './parse-argv.types';\nimport { vulnerabilityAnalysis } from './vulnerabilities/vulnerability-analysis';\n\n/**\n * Parse the tokens that would be forwarded to a `git` child-process and\n * return a structured summary of what the invocation does.\n */\nexport function parseArgv(...tokens: readonly unknown[]): ParsedArgv {\n const { flags, taskIndex } = parseGlobalFlags(tokens);\n\n const task = taskIndex < tokens.length ? String(tokens[taskIndex]).toLowerCase() : null;\n const taskTokens = task !== null ? tokens.slice(taskIndex + 1) : [];\n\n const { positionals, pathspecs } = parseTaskFlags(taskTokens, task, flags);\n const config = collectConfigAccess(task, flags, positionals);\n\n return {\n task,\n flags: flags.map(toParsedFlag),\n paths: pathspecs,\n config,\n vulnerabilities: vulnerabilityAnalysis(task, flags, config),\n };\n}\n\nfunction toParsedFlag({ value, name }: Flag): ParsedFlag {\n return value !== undefined ? { name, value } : { name };\n}\n"],"names":["scopedFlags","flags","scope","findGlobal","flag","CONFIG_WRITE_FLAGS","CONFIG_READ_FLAGS","CONFIG_WRITE_VERBS","CONFIG_READ_VERBS","detectConfigAction","positionals","name","configOperation","verb","isWrite","key","toOperation","operation","parseAssignment","raw","eq","detectConfigScope","detectConfigOverrideScope","collectWriteFlags","assignment","collectConfigAccess","task","parsedConfig","appendParsedConfigAction","action","config","UNIVERSAL","GLOBAL","COMMANDS","EMPTY","getFlagSpecForTask","spec","expandToken","stem","char","consumes","expandCluster","shortSpec","chars","result","i","remainder","c","parseGlobalFlags","tokens","parsed","next","token","parseTaskFlags","pathspecs","current","isPathSpec","toPaths","j","t","detectConfigWrites","write","helper","preventUnsafeConfig","vulnerability","preventConfigBuilder","category","message","regex","detectUploadPack","vulnerabilityAnalysis","vulnerabilities","all","parseArgv","taskIndex","taskTokens","toParsedFlag","value"],"mappings":"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"}
{"version":3,"file":"index.mjs","sources":["../src/flags/flags.helpers.ts","../src/config/config-operands.ts","../src/config/detect-config-action.ts","../src/config/analyse-config.ts","../src/tokens/flag-specs.ts","../src/tokens/token-expander.ts","../src/flags/parse-global-flags.ts","../src/flags/parse-task-flags.ts","../src/vulnerabilities/detect-vulnerable-config-writes.ts","../src/vulnerabilities/detect-vulnerable-flags.ts","../src/vulnerabilities/vulnerability-analysis.ts","../src/args/parse-argv.ts","../src/env/parse-env.ts","../src/vulnerabilities/vulnerability-check.ts"],"sourcesContent":["export interface Flag {\n name: string;\n value?: string;\n /** Value came from the next token rather than being embedded after `=`. */\n absorbedNext: boolean;\n /** Switch appeared before the git sub-command. */\n isGlobal: boolean;\n}\n\nexport function* scopedFlags(flags: Flag[], scope: 'global' | 'task') {\n const findGlobal = scope === 'global';\n for (const flag of flags) {\n if (flag.isGlobal === findGlobal) {\n yield flag;\n }\n }\n}\n","// Flags that unambiguously signal a write operation on git config.\nexport const CONFIG_WRITE_FLAGS = new Set([\n '--add',\n '--edit',\n '--remove-section',\n '--rename-section',\n '--replace-all',\n '--unset',\n '--unset-all',\n '-e',\n]);\n\n// Flags that unambiguously signal a read operation.\nexport const CONFIG_READ_FLAGS = new Set([\n '--get',\n '--get-all',\n '--get-color',\n '--get-colorbool',\n '--get-regexp',\n '--get-urlmatch',\n '--list',\n '-l',\n]);\n\n// Sub-command verbs accepted as the first positional by newer git versions.\nexport const CONFIG_WRITE_VERBS = new Set([\n 'edit',\n 'remove-section',\n 'rename-section',\n 'set',\n 'unset',\n]);\nexport const CONFIG_READ_VERBS = new Set(['get', 'get-color', 'get-colorbool', 'list']);\n","import type { ConfigScope } from '../args/parse-argv.types';\nimport { type Flag, scopedFlags } from '../flags/flags.helpers';\nimport type { ConfigOperation } from './config.types';\nimport {\n CONFIG_READ_FLAGS,\n CONFIG_READ_VERBS,\n CONFIG_WRITE_FLAGS,\n CONFIG_WRITE_VERBS,\n} from './config-operands';\n\nexport function detectConfigAction(flags: Flag[], positionals: string[]): ConfigOperation | null {\n for (const { name } of scopedFlags(flags, 'task')) {\n if (CONFIG_WRITE_FLAGS.has(name)) {\n return configOperation(true, positionals);\n }\n if (CONFIG_READ_FLAGS.has(name)) {\n return configOperation(false, positionals);\n }\n }\n\n const verb = positionals.at(0)?.toLowerCase();\n\n if (verb === undefined) {\n return null;\n }\n\n if (CONFIG_WRITE_VERBS.has(verb)) {\n return configOperation(true, positionals.slice(1));\n }\n\n if (CONFIG_READ_VERBS.has(verb)) {\n return configOperation(false, positionals.slice(1));\n }\n\n if (positionals.length === 1) {\n return configOperation(false, positionals);\n }\n\n return configOperation(true, positionals);\n}\n\nfunction configOperation(isWrite = false, positionals: string[] = []): ConfigOperation | null {\n const key = positionals.at(0)?.toLowerCase();\n\n if (key === undefined) {\n return null;\n }\n\n return {\n isWrite,\n isRead: !isWrite,\n key,\n value: positionals.at(1),\n };\n}\n\nexport function toOperation(scope: ConfigScope, operation: ConfigOperation) {\n if (operation.isWrite && operation.value !== undefined) {\n return { key: operation.key, value: operation.value, scope };\n }\n return { key: operation.key, scope };\n}\n","import type { ConfigScope, ConfigWrite, ParsedConfigActivity } from '../args/parse-argv.types';\nimport { type Flag, scopedFlags } from '../flags/flags.helpers';\nimport type { ConfigOperation } from './config.types';\nimport { detectConfigAction, toOperation } from './detect-config-action';\n\nfunction parseAssignment(raw: string | undefined): { key: string; value: string } | null {\n const eq = raw?.indexOf('=') || -1;\n\n if (!raw || eq < 0) {\n return null;\n }\n\n return {\n key: raw.slice(0, eq).trim().toLowerCase(),\n value: raw.slice(eq + 1),\n };\n}\n\nfunction detectConfigScope(flags: Flag[]): ConfigScope {\n for (const { name } of scopedFlags(flags, 'task')) {\n switch (name) {\n case '--global':\n return 'global';\n case '--system':\n return 'system';\n case '--worktree':\n return 'worktree';\n case '--local':\n return 'local';\n case '--file':\n case '-f':\n return 'file';\n }\n }\n return 'local';\n}\n\nfunction detectConfigOverrideScope({ name }: Flag): ConfigScope | void {\n if (name === '-c' || name === '--config') {\n return 'inline';\n }\n if (name === '--config-env') {\n return 'env';\n }\n}\n\n/**\n * Generates the stream of ConfigWrite settings found in the supplied flags,\n * triggered by `-c` and `--config` for inline configuration and `--config-env`\n * to set a config setting based on environment variable.\n */\nfunction* collectWriteFlags(flags: Flag[]): Generator<ConfigWrite> {\n for (const flag of flags) {\n const scope = detectConfigOverrideScope(flag);\n const assignment = scope && parseAssignment(flag.value);\n\n if (assignment) {\n yield {\n ...assignment,\n scope,\n };\n }\n }\n}\n\nexport function collectConfigAccess(\n task: string | null,\n flags: Flag[],\n positionals: string[]\n): ParsedConfigActivity {\n const parsedConfig: ParsedConfigActivity = {\n read: [],\n write: [...collectWriteFlags(flags)],\n };\n\n if (task === 'config') {\n appendParsedConfigAction(\n parsedConfig,\n detectConfigScope(flags),\n detectConfigAction(flags, positionals)\n );\n }\n\n return parsedConfig;\n}\n\nfunction appendParsedConfigAction(\n parsedConfig: ParsedConfigActivity,\n scope: ConfigScope,\n action: ConfigOperation | null\n) {\n if (action === null) {\n return;\n }\n\n const config = toOperation(scope, action);\n if (action.isWrite) {\n parsedConfig.write.push(config);\n } else {\n parsedConfig.read.push(config);\n }\n}\n","// ── Option tables ─────────────────────────────────────────────────────────────\n//\n// Each scope has:\n// short – Map<char, consumesNext> (known single-letter switches; true = takes next token)\n// long – Set<stem> (long switch stems, without --, that take the next token)\n//\n// Only switches listed here are \"known\". An unknown char anywhere in a combined\n// cluster causes the entire cluster to be kept as one opaque token.\n\nexport interface FlagSpec {\n readonly short: ReadonlyMap<string, boolean>;\n readonly long: ReadonlySet<string>;\n}\n\nconst UNIVERSAL: FlagSpec = {\n short: new Map([\n ['c', true], // -c <k=v> set config key for this invocation\n ]),\n long: new Set(),\n};\n\nexport const GLOBAL: FlagSpec = {\n short: new Map([\n ['C', true], // -C <path> change working directory\n ['P', false], // -P no pager (alias for --no-pager)\n ['h', false], // -h help\n ['p', false], // -p paginate\n ['v', false], // -v version\n ...UNIVERSAL.short.entries(),\n ]),\n long: new Set([\n 'attr-source',\n 'config-env',\n 'exec-path',\n 'git-dir',\n 'list-cmds',\n 'namespace',\n 'super-prefix',\n 'work-tree',\n ]),\n};\n\nconst COMMANDS: Record<string, FlagSpec> = {\n clone: {\n short: new Map([\n ['b', true], // -b <branch>\n ['j', true], // -j <n> parallel jobs\n ['l', false], // -l local\n ['n', false], // -n no-checkout\n ['o', true], // -o <name> remote name\n ['q', false], // -q quiet\n ['s', false], // -s shared\n ['u', true], // -u <upload-pack>\n ]),\n long: new Set(['branch', 'config', 'jobs', 'origin', 'upload-pack', 'u', 'template']),\n },\n commit: {\n short: new Map([\n ['C', true], // -C <commit> reuse message\n ['F', true], // -F <file> read message from file\n ['c', true], // -c <commit> reedit message\n ['m', true], // -m <msg>\n ['t', true], // -t <template>\n ]),\n long: new Set(['file', 'message', 'reedit-message', 'reuse-message', 'template']),\n },\n config: {\n short: new Map([\n ['e', false], // -e open editor\n ['f', true], // -f <file>\n ['l', false], // -l list\n ]),\n long: new Set(['blob', 'comment', 'default', 'file', 'type', 'value']),\n },\n fetch: {\n short: new Map(),\n long: new Set(['upload-pack']),\n },\n init: {\n short: new Map(),\n long: new Set(['template']),\n },\n pull: {\n short: new Map(),\n long: new Set(['upload-pack']),\n },\n push: {\n short: new Map(),\n long: new Set(['exec', 'receive-pack']),\n },\n};\n\nconst EMPTY: FlagSpec = { short: new Map(), long: new Set() };\n\nexport function getFlagSpecForTask(task?: string | null) {\n const spec = COMMANDS[task ?? ''] ?? EMPTY;\n\n return {\n short: new Map([...UNIVERSAL.short.entries(), ...spec.short.entries()]),\n long: spec.long,\n };\n}\n","import { GLOBAL } from './flag-specs';\n\n/** Parse a single raw token (e.g. `'-m'`, `'--amend'`, `'-uc'`) into one or\n * more switch descriptors. Values are not yet resolved for needsNext=true. */\nexport function expandToken(\n raw: string,\n spec = GLOBAL\n): Array<{\n name: string;\n value?: string;\n needsNext: boolean;\n}> {\n if (raw.startsWith('--')) {\n const eq = raw.indexOf('=');\n if (eq > 2) {\n return [{ name: raw.slice(0, eq), value: raw.slice(eq + 1), needsNext: false }];\n }\n const stem = raw.slice(2);\n return [{ name: raw, needsNext: spec.long.has(stem) }];\n }\n\n // Single short switch\n if (raw.length === 2) {\n const char = raw.charAt(1);\n const consumes = spec.short.get(char);\n return [{ name: raw, needsNext: consumes === true }];\n }\n\n // Combined short cluster: try to expand char-by-char\n return expandCluster(raw, spec.short);\n}\n\nfunction expandCluster(\n raw: string,\n shortSpec: ReadonlyMap<string, boolean>\n): Array<{ name: string; value?: string; needsNext: boolean }> {\n const chars = raw.slice(1).split('');\n const result: Array<{ name: string; value?: string; needsNext: boolean }> = [];\n\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n const consumes = shortSpec.get(char);\n\n if (consumes === undefined) {\n // Unknown char: keep the whole raw token as opaque\n return [{ name: raw, needsNext: false }];\n }\n\n if (consumes) {\n const remainder = chars.slice(i + 1).join('');\n if (remainder) {\n const remainderAllKnown = [...remainder].every((c) => shortSpec.has(c));\n if (!remainderAllKnown) {\n // Remaining chars are the embedded value, not separate flags\n result.push({ name: `-${char}`, value: remainder, needsNext: false });\n return result;\n }\n }\n }\n\n result.push({ name: `-${char}`, needsNext: consumes });\n }\n\n return result;\n}\n","import { expandToken } from '../tokens/token-expander';\nimport type { Flag } from './flags.helpers';\n\nexport interface GlobalFlags {\n flags: Flag[];\n taskIndex: number;\n}\n\nexport function parseGlobalFlags(tokens: readonly unknown[], flags: Flag[] = []): GlobalFlags {\n let i = 0;\n\n while (i < tokens.length) {\n const raw = String(tokens[i]);\n if (!raw.startsWith('-') || raw.length < 2) break;\n\n const parsed = expandToken(raw);\n let next = i + 1;\n\n for (const token of parsed) {\n const flag: Flag = {\n name: token.name,\n value: token.value,\n absorbedNext: false,\n isGlobal: true,\n };\n if (token.needsNext && flag.value === undefined && next < tokens.length) {\n flag.value = String(tokens[next]);\n flag.absorbedNext = true;\n next++;\n }\n flags.push(flag);\n }\n\n i = next;\n }\n\n return { flags, taskIndex: i };\n}\n","import { isPathSpec, toPaths } from '@simple-git/args-pathspec';\n\nimport { getFlagSpecForTask } from '../tokens/flag-specs';\nimport { expandToken } from '../tokens/token-expander';\nimport type { Flag } from './flags.helpers';\n\ntype TaskFlags = {\n flags: Flag[];\n positionals: string[];\n pathspecs: string[];\n};\n\nexport function parseTaskFlags(\n tokens: readonly unknown[],\n task: string | null,\n flags: Flag[] = []\n): TaskFlags {\n const spec = getFlagSpecForTask(task);\n const positionals: string[] = [];\n const pathspecs: string[] = [];\n\n let i = 0;\n while (i < tokens.length) {\n const current = tokens[i];\n\n if (isPathSpec(current)) {\n pathspecs.push(...toPaths(current as string));\n i++;\n continue;\n }\n\n const raw = String(current);\n\n if (raw === '--') {\n for (let j = i + 1; j < tokens.length; j++) {\n const t = tokens[j];\n isPathSpec(t) ? pathspecs.push(...toPaths(t as string)) : pathspecs.push(String(t));\n }\n break;\n }\n\n if (!raw.startsWith('-') || raw.length < 2) {\n positionals.push(raw);\n i++;\n continue;\n }\n\n const parsed = expandToken(raw, spec);\n let next = i + 1;\n\n for (const token of parsed) {\n const flag: Flag = {\n name: token.name,\n value: token.value,\n absorbedNext: false,\n isGlobal: false,\n };\n if (\n token.needsNext &&\n flag.value === undefined &&\n next < tokens.length &&\n !isPathSpec(tokens[next])\n ) {\n flag.value = String(tokens[next]);\n flag.absorbedNext = true;\n next++;\n }\n flags.push(flag);\n }\n\n i = next;\n }\n\n return { flags, positionals, pathspecs };\n}\n","import type { ParsedConfigActivity } from '../args/parse-argv.types';\nimport type { Vulnerability, VulnerabilityCategory } from './vulnerability.types';\n\nexport function* detectVulnerableConfigWrites({\n write,\n}: ParsedConfigActivity): Generator<Vulnerability> {\n for (const config of write) {\n for (const helper of preventUnsafeConfig) {\n const vulnerability = helper(config.key);\n if (vulnerability) {\n yield vulnerability;\n }\n }\n }\n}\n\nfunction preventConfigBuilder(\n config: string | RegExp,\n category: VulnerabilityCategory,\n message = String(config)\n) {\n const regex = typeof config === 'string' ? new RegExp(`\\\\s*${config.toLowerCase()}`) : config;\n\n return function preventCommand(key: string): Vulnerability | void {\n if (regex.test(key)) {\n return {\n category,\n message: `Configuring ${message} is not permitted without enabling ${category}`,\n };\n }\n };\n}\n\nfunction preventExpandedConfigBuilder(config: string, category: VulnerabilityCategory) {\n const regex = new RegExp(`\\\\s*${config.toLowerCase().replace(/\\./g, '(\\..+)?.')}`);\n return preventConfigBuilder(regex, category, config);\n}\n\nconst preventUnsafeConfig = [\n preventConfigBuilder('alias', 'allowUnsafeAlias'),\n preventConfigBuilder('core.askPass', 'allowUnsafeAskPass'),\n preventConfigBuilder('core.editor', 'allowUnsafeEditor'),\n preventConfigBuilder('core.fsmonitor', 'allowUnsafeFsMonitor'),\n preventConfigBuilder('core.gitProxy', 'allowUnsafeGitProxy'),\n preventConfigBuilder('core.hooksPath', 'allowUnsafeHooksPath'),\n preventConfigBuilder('core.pager', 'allowUnsafePager'),\n preventConfigBuilder('core.sshCommand', 'allowUnsafeSshCommand'),\n preventExpandedConfigBuilder('credential.helper', 'allowUnsafeCredentialHelper'),\n preventExpandedConfigBuilder('diff.command', 'allowUnsafeDiffExternal'),\n preventConfigBuilder('diff.external', 'allowUnsafeDiffExternal'),\n preventExpandedConfigBuilder('diff.textconv', 'allowUnsafeDiffTextConv'),\n preventExpandedConfigBuilder('filter.clean', 'allowUnsafeFilter'),\n preventExpandedConfigBuilder('filter.smudge', 'allowUnsafeFilter'),\n preventExpandedConfigBuilder('gpg.program', 'allowUnsafeGpgProgram'),\n preventConfigBuilder('init.templateDir', 'allowUnsafeTemplateDir'),\n preventExpandedConfigBuilder('merge.driver', 'allowUnsafeMergeDriver'),\n preventExpandedConfigBuilder('mergetool.path', 'allowUnsafeMergeDriver'),\n preventExpandedConfigBuilder('mergetool.cmd', 'allowUnsafeMergeDriver'),\n preventExpandedConfigBuilder('protocol.allow', 'allowUnsafeProtocolOverride'),\n preventExpandedConfigBuilder('remote.receivepack', 'allowUnsafePack'),\n preventExpandedConfigBuilder('remote.uploadpack', 'allowUnsafePack'),\n preventConfigBuilder('sequence.editor', 'allowUnsafeEditor'),\n];\n","import type { Flag } from '../flags/flags.helpers';\nimport type { Vulnerability, VulnerabilityCategory } from './vulnerability.types';\n\nexport function* detectVulnerableFlags(\n task: null | string,\n flags: Flag[]\n): Generator<Vulnerability> {\n for (const flag of flags) {\n for (const helper of preventUnsafeFlags) {\n const vulnerability = helper(task, flag.name);\n if (vulnerability) {\n yield vulnerability;\n }\n }\n }\n}\n\nfunction preventFlagBuilder(\n task: string | null,\n flag: string | RegExp,\n category: VulnerabilityCategory,\n name = String(flag)\n) {\n const regex = typeof flag === 'string' ? new RegExp(`\\\\s*${flag.toLowerCase()}`) : flag;\n const message = `Use of ${task ? `${task} with option ` : ''}${name} is not permitted without enabling ${category}`;\n\n return function preventFlag(currentTask: string | null, flagName: string): Vulnerability | void {\n if ((!task || currentTask === task) && regex.test(flagName)) {\n return {\n category,\n message,\n };\n }\n };\n}\n\nconst preventUnsafeFlags = [\n preventFlagBuilder(\n null,\n /--(upload|receive)-pack/,\n 'allowUnsafePack',\n '--upload-pack or --receive-pack'\n ),\n preventFlagBuilder('clone', /^-\\w*u/, 'allowUnsafePack'),\n preventFlagBuilder('clone', '--u', 'allowUnsafePack'),\n preventFlagBuilder('push', '--exec', 'allowUnsafePack'),\n preventFlagBuilder(null, '--template', 'allowUnsafeTemplateDir'),\n];\n","import type { ParsedConfigActivity } from '../args/parse-argv.types';\nimport type { Flag } from '../flags/flags.helpers';\nimport { detectVulnerableConfigWrites } from './detect-vulnerable-config-writes';\nimport { detectVulnerableFlags } from './detect-vulnerable-flags';\nimport type { Vulnerability } from './vulnerability.types';\n\nexport function vulnerabilityAnalysis(\n task: null | string,\n flags: Flag[],\n config: ParsedConfigActivity\n): Vulnerability[] {\n return [...detectVulnerableFlags(task, flags), ...detectVulnerableConfigWrites(config)];\n}\n","import { collectConfigAccess } from '../config/analyse-config';\nimport type { Flag } from '../flags/flags.helpers';\nimport { parseGlobalFlags } from '../flags/parse-global-flags';\nimport { parseTaskFlags } from '../flags/parse-task-flags';\nimport { vulnerabilityAnalysis } from '../vulnerabilities/vulnerability-analysis';\nimport type { ParsedArgv, ParsedFlag } from './parse-argv.types';\n\n/**\n * Parse the tokens that would be forwarded to a `git` child-process and\n * return a structured summary of what the invocation does.\n */\nexport function parseArgv(...tokens: readonly unknown[]): ParsedArgv {\n const { flags, taskIndex } = parseGlobalFlags(tokens);\n\n const task = taskIndex < tokens.length ? String(tokens[taskIndex]).toLowerCase() : null;\n const taskTokens = task !== null ? tokens.slice(taskIndex + 1) : [];\n\n const { positionals, pathspecs } = parseTaskFlags(taskTokens, task, flags);\n const config = collectConfigAccess(task, flags, positionals);\n\n return {\n task,\n flags: flags.map(toParsedFlag),\n paths: pathspecs,\n config,\n vulnerabilities: vulnerabilityAnalysis(task, flags, config),\n };\n}\n\nfunction toParsedFlag({ value, name }: Flag): ParsedFlag {\n return value !== undefined ? { name, value } : { name };\n}\n","import type { ConfigWrite, ParsedConfigActivity } from '../args/parse-argv.types';\nimport type { Vulnerability, VulnerabilityCategory } from '../vulnerabilities/vulnerability.types';\nimport { vulnerabilityAnalysis } from '../vulnerabilities/vulnerability-analysis';\n\nconst GitEnvKeys = {\n 'editor': 'allowUnsafeEditor',\n 'git_askpass': 'allowUnsafeAskPass',\n 'git_config_global': 'allowUnsafeConfigPaths',\n 'git_config_system': 'allowUnsafeConfigPaths',\n 'git_config_count': 'allowUnsafeConfigEnvCount',\n 'git_config': 'allowUnsafeConfigPaths',\n 'git_editor': 'allowUnsafeEditor',\n 'git_exec_path': 'allowUnsafeConfigPaths',\n 'git_external_diff': 'allowUnsafeDiffExternal',\n 'git_pager': 'allowUnsafePager',\n 'git_proxy_command': 'allowUnsafeGitProxy',\n 'git_template_dir': 'allowUnsafeTemplateDir',\n 'git_sequence_editor': 'allowUnsafeEditor',\n 'git_ssh': 'allowUnsafeSshCommand',\n 'git_ssh_command': 'allowUnsafeSshCommand',\n 'pager': 'allowUnsafePager',\n 'prefix': 'allowUnsafeConfigPaths',\n 'ssh_askpass': 'allowUnsafeAskPass',\n} as const satisfies Record<string, VulnerabilityCategory>;\n\ntype GitEnv = Record<string, string> & {\n git_config_count?: string;\n};\n\nfunction* collectConfigByCount(env: GitEnv): Generator<ConfigWrite> {\n const count = parseInt(env.git_config_count ?? '0', 10);\n for (let index = 0; index < count; index++) {\n const key = env[`git_config_key_${index}`];\n const value = env[`git_config_value_${index}`];\n\n if (key !== undefined) {\n yield { key: key.toLowerCase().trim(), value, scope: 'env' };\n }\n }\n}\n\nfunction* collectConfigVulnerabilities(env: GitEnv): Generator<Vulnerability> {\n for (const key of Object.keys(env)) {\n if (isGitEnvKey(key)) {\n const category = GitEnvKeys[key];\n yield {\n category,\n message: `Use of \"${key.toUpperCase()}\" is not permitted without enabling ${category}`,\n };\n }\n }\n}\n\nfunction isGitEnvKey(key: string): key is keyof typeof GitEnvKeys {\n return Object.hasOwn(GitEnvKeys, key);\n}\n\nfunction prepareEnv(env: Record<string, unknown>): GitEnv {\n const gitEnv: GitEnv = {};\n for (const [key, value] of Object.entries(env)) {\n const envKey = key.toLowerCase().trim();\n if (isGitEnvKey(envKey) || envKey.startsWith('git')) {\n gitEnv[envKey] = String(value);\n }\n }\n return gitEnv;\n}\n\nexport function parseEnv(raw: Record<string, unknown>) {\n const env = prepareEnv(raw);\n const config: ParsedConfigActivity = {\n read: [],\n write: [...collectConfigByCount(env)],\n };\n const vulnerabilities = [\n ...collectConfigVulnerabilities(env),\n ...vulnerabilityAnalysis(null, [], config),\n ];\n\n return {\n config,\n vulnerabilities,\n };\n}\n","import { parseArgv } from '../args/parse-argv';\nimport { parseEnv } from '../env/parse-env';\n\n/**\n * Retrieves just the vulnerabilities identified in the supplied varargs tokens\n * and environment variables.\n */\nexport function vulnerabilityCheck(tokens: readonly string[], env: Record<string, unknown>) {\n return [...parseArgv(...tokens).vulnerabilities, ...parseEnv(env).vulnerabilities];\n}\n"],"names":["scopedFlags","flags","scope","findGlobal","flag","CONFIG_WRITE_FLAGS","CONFIG_READ_FLAGS","CONFIG_WRITE_VERBS","CONFIG_READ_VERBS","detectConfigAction","positionals","name","configOperation","verb","isWrite","key","toOperation","operation","parseAssignment","raw","eq","detectConfigScope","detectConfigOverrideScope","collectWriteFlags","assignment","collectConfigAccess","task","parsedConfig","appendParsedConfigAction","action","config","UNIVERSAL","GLOBAL","COMMANDS","EMPTY","getFlagSpecForTask","spec","expandToken","stem","char","consumes","expandCluster","shortSpec","chars","result","i","remainder","c","parseGlobalFlags","tokens","parsed","next","token","parseTaskFlags","pathspecs","current","isPathSpec","toPaths","j","t","detectVulnerableConfigWrites","write","helper","preventUnsafeConfig","vulnerability","preventConfigBuilder","category","message","regex","preventExpandedConfigBuilder","detectVulnerableFlags","preventUnsafeFlags","preventFlagBuilder","currentTask","flagName","vulnerabilityAnalysis","parseArgv","taskIndex","taskTokens","toParsedFlag","value","GitEnvKeys","collectConfigByCount","env","count","index","collectConfigVulnerabilities","isGitEnvKey","prepareEnv","gitEnv","envKey","parseEnv","vulnerabilities","vulnerabilityCheck"],"mappings":"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"}

@@ -0,3 +1,3 @@

import type { ParsedConfigActivity } from '../args/parse-argv.types';
import { type Flag } from '../flags/flags.helpers';
import type { ParsedConfigActivity } from '../parse-argv.types';
export declare function collectConfigAccess(task: string | null, flags: Flag[], positionals: string[]): ParsedConfigActivity;

@@ -0,3 +1,3 @@

import type { ConfigScope } from '../args/parse-argv.types';
import { type Flag } from '../flags/flags.helpers';
import type { ConfigScope } from '../parse-argv.types';
import type { ConfigOperation } from './config.types';

@@ -4,0 +4,0 @@ export declare function detectConfigAction(flags: Flag[], positionals: string[]): ConfigOperation | null;

@@ -0,4 +1,4 @@

import type { ParsedConfigActivity } from '../args/parse-argv.types';
import type { Flag } from '../flags/flags.helpers';
import type { ParsedConfigActivity } from '../parse-argv.types';
import type { ParsedVulnerabilities } from './vulnerability.types';
export declare function vulnerabilityAnalysis(task: null | string, flags: Flag[], config: ParsedConfigActivity): ParsedVulnerabilities;
import type { Vulnerability } from './vulnerability.types';
export declare function vulnerabilityAnalysis(task: null | string, flags: Flag[], config: ParsedConfigActivity): Vulnerability[];

@@ -1,2 +0,2 @@

export type VulnerabilityCategory = 'allowUnsafeDiffExternal' | 'allowUnsafeFsMonitor' | 'allowUnsafeGitProxy' | 'allowUnsafeHooksPath' | 'allowUnsafePack' | 'allowUnsafeProtocolOverride' | 'allowUnsafeSshCommand';
export type VulnerabilityCategory = keyof VulnerabilityCategoryFlags;
export interface Vulnerability {

@@ -6,5 +6,100 @@ category: VulnerabilityCategory;

}
export interface ParsedVulnerabilities {
categories: Set<VulnerabilityCategory>;
vulnerabilities: Vulnerability[];
export interface VulnerabilityCategoryFlags {
/**
* Use of the `alias.*` configuration settings in simple-git tasks
*/
allowUnsafeAlias: boolean;
/**
* Use of the `core.askPass` configuration setting and environment variables in simple-git tasks
*/
allowUnsafeAskPass: boolean;
/**
* Allows using environment variables to set configuration paths in simple-git tasks
*/
allowUnsafeConfigPaths: boolean;
/**
* Allows setting configuration fields from environment variables in simple-git tasks. Any
* configuration set in this way will still be subject to the same block-listing checks and
* may require other unsafe flags to be enabled for use.
*/
allowUnsafeConfigEnvCount: boolean;
/**
* Allows setting credential helper in simple-git tasks
*/
allowUnsafeCredentialHelper: boolean;
/**
* Allows setting path to the text editor utility in simple-git tasks
*/
allowUnsafeEditor: boolean;
/**
* Allows use of setting paths for merge tools in simple-git tasks
*/
allowUnsafeMergeDriver: boolean;
/**
* Allows setting path to the pager utility in simple-git tasks
*/
allowUnsafePager: boolean;
/**
* By default, `simple-git` prevents the use of inline configuration
* options to override the protocols available for the `git` child
* process to prevent accidental security vulnerabilities when
* unsanitised user data is passed directly into operations such as
* `git.addRemote`, `git.clone` or `git.raw`.
*
* Enable this override to use the `ext::` protocol (see examples on
* [git-scm.com](https://git-scm.com/docs/git-remote-ext#_examples)).
*/
allowUnsafeProtocolOverride: boolean;
/**
* Given the possibility of using `--upload-pack` and `--receive-pack` as
* attack vectors, the use of these in any command (or the shorthand
* `-u` option in a `clone` operation) are blocked by default.
*
* Enable this override to permit the use of these arguments.
*/
allowUnsafePack: boolean;
/**
* Using a `-c` switch to enable custom SSH commands opens up a potential
* attack vector for running arbitrary commands.
*/
allowUnsafeSshCommand: boolean;
/**
* Using a `-c` switch to enable custom proxy command for the `git://` transport
* exposes and attack vector for running arbitrary commands.
*/
allowUnsafeGitProxy: boolean;
/**
* Using a `-c` switch to enable custom hooks path commands to be run automatically
* exposes and attack vector for running arbitrary commands.
*/
allowUnsafeHooksPath: boolean;
/**
* Using a `-c` switch to enable setting binary for processing diffs
* exposes and attack vector for running arbitrary commands.
*/
allowUnsafeDiffExternal: boolean;
/**
* Using a `-c` switch to enable setting binary for retrieving text content of a file
*/
allowUnsafeDiffTextConv: boolean;
/**
* Using a `-c` switch to enable setting binary for `smudge` and `clean` operations
* which can add and remove content to a file during checkout and commit.
*/
allowUnsafeFilter: boolean;
/**
* Using a `-c` switch to enable setting the binary to which `git` will delegate
* file content change detection.
*/
allowUnsafeFsMonitor: boolean;
/**
* Using a `-c` switch to configure the GPG signing program (`gpg.program`) or a
* per-format variant (`gpg.ssh.program`, `gpg.x509.program`). Controlling the signing
* binary allows an attacker to run arbitrary code whenever a commit or tag is signed.
*/
allowUnsafeGpgProgram: boolean;
/**
* Allows overriding template directory either by environment variable or configuration in simple-git tasks
*/
allowUnsafeTemplateDir: boolean;
}
{
"name": "@simple-git/argv-parser",
"version": "1.0.3",
"version": "1.1.0",
"main": "dist/index.cjs",

@@ -34,4 +34,4 @@ "files": [

"dependencies": {
"@simple-git/args-pathspec": "^1.0.2"
"@simple-git/args-pathspec": "^1.0.3"
}
}
import type { ParsedArgv } from './parse-argv.types';
/**
* Parse the tokens that would be forwarded to a `git` child-process and
* return a structured summary of what the invocation does.
*/
export declare function parseArgv(...tokens: readonly unknown[]): ParsedArgv;
import type { ParsedVulnerabilities } from './vulnerabilities/vulnerability.types';
/** Where a config value originates / which scope it targets. */
export type ConfigScope = 'inline' | 'env' | 'local' | 'global' | 'system' | 'worktree' | 'file';
/** A single flag or option found in the token list. */
export interface ParsedFlag {
/** Canonical name: e.g. `'-m'`, `'--amend'`, `'--no-verify'`. */
name: string;
/** Value consumed by this flag, when applicable. */
value?: string;
}
/** A config key that this invocation reads via `git config`. */
export interface ConfigRead {
/** Lower-cased dotted key, e.g. `'user.name'`. */
key: string;
scope: ConfigScope;
}
/** A config key that this invocation writes. */
export interface ConfigWrite extends ConfigRead {
/**
* The value being written.
* Absent for delete-style operations (`--unset`, `--remove-section`).
* For `scope: 'env'` this is the environment-variable *name*, not the
* resolved config value.
*/
value?: string;
}
export interface ParsedConfigActivity {
/** Config keys read by a `git config` read operation. */
read: ConfigRead[];
/** Config keys written by this invocation (inline overrides and `git config` writes). */
write: ConfigWrite[];
}
/**
* Fully parsed representation of a set of varargs to be passed into the `git` child process.
*/
export interface ParsedArgv {
/**
* The git sub-command, e.g. `'commit'`, `'push'`.
* `null` when the list contains only global flags (`['--version']`, `[]`).
*/
task: string | null;
/**
* Every flag and option in the tokens (global + command-level), with
* combined short clusters expanded: `-uc` → `[{name:'-u'}, {name:'-c'}]`.
*/
flags: ParsedFlag[];
/**
* File-system paths: tokens after `--`, or `pathspec()` wrapper objects.
* */
paths: string[];
/**
* Activities being requested for the `git` config
*/
config: ParsedConfigActivity;
/**
* Attack vectors discovered in the arguments
*/
vulnerabilities: ParsedVulnerabilities;
}
import type { ParsedConfigActivity } from '../parse-argv.types';
import type { Vulnerability } from './vulnerability.types';
export declare function detectConfigWrites({ write }: ParsedConfigActivity): Generator<Vulnerability>;
import type { Flag } from '../flags/flags.helpers';
import type { Vulnerability } from './vulnerability.types';
export declare function detectUploadPack(task: null | string, flags: Flag[]): Generator<Vulnerability>;