Skip to content

Commit c7b477e

Browse files
committed
bughunt probe: npm autocrlf/unicode/deep paths
1 parent f6b7fb9 commit c7b477e

1 file changed

Lines changed: 106 additions & 0 deletions

File tree

‎.github/workflows/bughunt-npm.yml‎

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: bughunt npm probe
2+
on:
3+
push:
4+
branches: ['bughunt/npm/**']
5+
permissions:
6+
contents: read
7+
jobs:
8+
probe:
9+
strategy:
10+
fail-fast: false
11+
matrix:
12+
os: [ubuntu-latest, macos-latest, windows-latest]
13+
npm: ['10.9.7', '12.1.0']
14+
runs-on: ${{ matrix.os }}
15+
timeout-minutes: 45
16+
defaults:
17+
run:
18+
shell: bash
19+
steps:
20+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
21+
with:
22+
persist-credentials: false
23+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
24+
with:
25+
node-version: '24.15.0'
26+
- name: Build CLI
27+
run: cargo build --release -p socket-patch-cli
28+
- name: Install npm
29+
run: npm install -g npm@${{ matrix.npm }} && npm --version
30+
- name: Probe
31+
env:
32+
SOCKET_NO_UPDATE_CHECK: '1'
33+
SOCKET_NO_CONFIG: '1'
34+
run: |
35+
set +e
36+
BIN="$PWD/target/release/socket-patch"
37+
[ -f "$BIN.exe" ] && BIN="$BIN.exe"
38+
git config --global user.email probe@example.com; git config --global user.name probe
39+
git config --global init.defaultBranch main
40+
W="$RUNNER_TEMP/pr obé ü"; mkdir -p "$W"
41+
cat > "$W/stage.js" <<'JS'
42+
const fs=require('fs'),path=require('path'),crypto=require('crypto');
43+
const [proj,purl,pkgdir]=process.argv.slice(2);
44+
const before=fs.readFileSync(path.join(pkgdir,'index.js'));
45+
const after=Buffer.concat([Buffer.from('/* SOCKET-PATCHED */\n'),before]);
46+
const gh=b=>crypto.createHash('sha256').update(Buffer.concat([Buffer.from('blob '+b.length+'\0'),b])).digest('hex');
47+
fs.mkdirSync(path.join(proj,'.socket','blobs'),{recursive:true});
48+
const m={patches:{[purl]:{uuid:'1a2b3c4d-5e6f-4a1b-8c2d-0123456789ab',exportedAt:'2026-01-01T00:00:00Z',
49+
files:{'package/index.js':{beforeHash:gh(before),afterHash:gh(after)}},
50+
vulnerabilities:{'GHSA-xxxx-yyyy-zzzz':{cves:['CVE-2024-99999'],summary:'s',severity:'high',description:'d'}},
51+
description:'m',license:'MIT',tier:'free'}}};
52+
fs.writeFileSync(path.join(proj,'.socket','manifest.json'),JSON.stringify(m,null,2)+'\n');
53+
fs.writeFileSync(path.join(proj,'.socket','blobs',gh(after)),after);
54+
fs.writeFileSync(path.join(proj,'.socket','blobs',gh(before)),before);
55+
JS
56+
head20() { node -e "process.stdout.write(require('fs').readFileSync(process.argv[1],'utf8').slice(0,20).replace(/\r?\n/g,' '))" "$1" 2>/dev/null || echo MISSING; }
57+
vexst() { node -e "try{const d=require(process.argv[1]);console.log((d.statements||[]).map(s=>s.status).join(',')||'none')}catch(e){console.log('nodoc')}" "$1"; }
58+
T="${{ matrix.os }} npm ${{ matrix.npm }}"
59+
60+
echo "::group::vendored on LF, fresh clone with core.autocrlf=true"
61+
V="$W/vend src"; mkdir -p "$V"; cd "$V"
62+
echo '{"name":"app","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0","is-odd":"3.0.1","is-number":"7.0.0"}}' > package.json
63+
printf 'node_modules\n' > .gitignore
64+
npm install --no-audit --no-fund >/dev/null 2>&1
65+
node "$W/stage.js" . pkg:npm/left-pad@1.3.0 node_modules/left-pad
66+
"$BIN" vendor --offline --json > "$W/vendor1.json"; echo "vendor exit $?"
67+
git init -q . && git add -A && git commit -qm vendored
68+
C="$W/vend clone"; git -c core.autocrlf=true clone -q "$V" "$C"; cd "$C"
69+
echo "lock has CRLF: $(grep -c $'\r' package-lock.json) state.json CRLF: $(grep -c $'\r' .socket/vendor/state.json 2>/dev/null)"
70+
npm ci --no-audit --no-fund > "$W/ci.log" 2>&1; CI=$?
71+
"$BIN" vex --output "$W/v1.json" --json > "$W/vex1.json" 2>&1; VX=$?
72+
echo "RESULT autocrlf-ci $T: ci=$CI left-pad=[$(head20 node_modules/left-pad/index.js)] vex_exit=$VX vex=$(vexst "$W/v1.json")"
73+
cat "$W/vex1.json" | head -c 1500; echo
74+
"$BIN" vendor --offline --json > "$W/vendor2.json" 2>&1; R2=$?
75+
echo "RESULT autocrlf-revendor $T: exit=$R2 status=$(node -e "console.log(require(process.argv[1]).status)" "$W/vendor2.json") gitdiff=[$(git status --short | tr '\n' ' ')]"
76+
head -c 1500 "$W/vendor2.json"; echo
77+
"$BIN" vendor --revert --json > "$W/revert.json" 2>&1; RV=$?
78+
echo "RESULT autocrlf-revert $T: exit=$RV gitstatus=[$(git status --short | tr '\n' ' ')] diffstat=[$(git diff --stat HEAD~0 | tail -1)]"
79+
head -c 1500 "$W/revert.json"; echo
80+
echo "::endgroup::"
81+
82+
echo "::group::agent mode, CRLF manifest + unicode/space path"
83+
AG="$W/agent é"; mkdir -p "$AG"; cd "$AG"
84+
echo '{"name":"app","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0"}}' > package.json
85+
npm install --no-audit --no-fund >/dev/null 2>&1
86+
node "$W/stage.js" . pkg:npm/left-pad@1.3.0 node_modules/left-pad
87+
node -e "const f='.socket/manifest.json';const fs=require('fs');fs.writeFileSync(f,fs.readFileSync(f,'utf8').replace(/\n/g,'\r\n'))"
88+
"$BIN" apply --offline --json > "$W/ap.json" 2>&1; AP=$?
89+
"$BIN" vex --offline --output "$W/v2.json" --json > /dev/null 2>&1; VX2=$?
90+
"$BIN" rollback --offline --json > "$W/rb.json" 2>&1; RB=$?
91+
echo "RESULT agent-crlf $T: apply=$AP vex=$VX2/$(vexst "$W/v2.json") rollback=$RB after_rb=[$(head20 node_modules/left-pad/index.js)]"
92+
head -c 800 "$W/ap.json"; echo
93+
echo "::endgroup::"
94+
95+
echo "::group::agent mode --cwd from elsewhere with deep path"
96+
D="$W/$(printf 'd%.0s' {1..60})/$(printf 'e%.0s' {1..60})/$(printf 'f%.0s' {1..60})/$(printf 'g%.0s' {1..60})"; mkdir -p "$D"; cd "$D"
97+
echo '{"name":"app","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0"}}' > package.json
98+
npm install --no-audit --no-fund >/dev/null 2>&1; NI=$?
99+
node "$W/stage.js" . pkg:npm/left-pad@1.3.0 node_modules/left-pad
100+
cd "$W"
101+
"$BIN" vendor --offline --json --cwd "$D" > "$W/vd.json" 2>&1; VD=$?
102+
cd "$D"; rm -rf node_modules; npm ci --no-audit --no-fund >/dev/null 2>&1; CI2=$?
103+
echo "RESULT deep-vendor $T: pathlen=${#D} install=$NI vendor=$VD ci=$CI2 left-pad=[$(head20 node_modules/left-pad/index.js)]"
104+
head -c 800 "$W/vd.json"; echo
105+
echo "::endgroup::"
106+
exit 0

0 commit comments

Comments
 (0)