Skip to content

Commit f5fff49

Browse files
committed
bughunt npm probe: alias + linked strategy
1 parent f6b7fb9 commit f5fff49

1 file changed

Lines changed: 68 additions & 0 deletions

File tree

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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.4', '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+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
22+
with:
23+
node-version: '22'
24+
- name: Build CLI
25+
run: cargo build --release -p socket-patch-cli
26+
- name: Install npm
27+
run: npm install -g npm@${{ matrix.npm }} && npm --version
28+
- name: Probe
29+
run: |
30+
BIN="$PWD/target/release/socket-patch"
31+
[ -f "$BIN.exe" ] && BIN="$BIN.exe"
32+
W="$RUNNER_TEMP/probe"; mkdir -p "$W"
33+
cat > "$W/stage.js" <<'JS'
34+
const fs=require('fs'),path=require('path'),crypto=require('crypto');
35+
const [proj,purl,pkgdir]=process.argv.slice(2);
36+
const before=fs.readFileSync(path.join(pkgdir,'index.js'));
37+
const after=Buffer.concat([Buffer.from('/* SOCKET-PATCHED */\n'),before]);
38+
const gh=b=>crypto.createHash('sha256').update(Buffer.concat([Buffer.from('blob '+b.length+'\0'),b])).digest('hex');
39+
fs.mkdirSync(path.join(proj,'.socket','blobs'),{recursive:true});
40+
const m={patches:{[purl]:{uuid:'1a2b3c4d-5e6f-4a1b-8c2d-0123456789ab',exportedAt:'2026-01-01T00:00:00Z',
41+
files:{'package/index.js':{beforeHash:gh(before),afterHash:gh(after)}},
42+
vulnerabilities:{'GHSA-xxxx-yyyy-zzzz':{cves:['CVE-2024-99999'],summary:'s',severity:'high',description:'d'}},
43+
description:'m',license:'MIT',tier:'free'}},setup:{manual:['npm']}};
44+
fs.writeFileSync(path.join(proj,'.socket','manifest.json'),JSON.stringify(m,null,2));
45+
fs.writeFileSync(path.join(proj,'.socket','blobs',gh(after)),after);
46+
fs.writeFileSync(path.join(proj,'.socket','blobs',gh(before)),before);
47+
JS
48+
head20() { node -e "process.stdout.write(require('fs').readFileSync(process.argv[1],'utf8').slice(0,20).replace(/\n/g,' '))" "$1"; }
49+
echo "::group::alias (issue 356)"
50+
A="$W/alias"; mkdir -p "$A"; cd "$A"
51+
echo '{"name":"app","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0","lp":"npm:left-pad@1.3.0"}}' > package.json
52+
npm install --no-audit --no-fund >/dev/null 2>&1
53+
node "$W/stage.js" . pkg:npm/left-pad@1.3.0 node_modules/left-pad
54+
"$BIN" apply --json --offline > apply.json; echo "apply exit $?"
55+
"$BIN" vex --output v.json --json --offline > vex.json; echo "vex exit $?"
56+
echo "RESULT alias ${{ matrix.os }} npm ${{ matrix.npm }}: left-pad=[$(head20 node_modules/left-pad/index.js)] lp=[$(head20 node_modules/lp/index.js)] vex=$(node -e "const d=require('./v.json');console.log(d.statements.map(s=>s.status).join(','))")"
57+
echo "::endgroup::"
58+
echo "::group::linked (issue 359)"
59+
L="$W/linked"; mkdir -p "$L"; cd "$L"
60+
echo '{"name":"app","version":"1.0.0","private":true,"dependencies":{"is-odd":"3.0.1"}}' > package.json
61+
echo 'install-strategy=linked' > .npmrc
62+
npm install --no-audit --no-fund >/dev/null 2>&1
63+
ls -la node_modules node_modules/.store || true
64+
P=$(ls -d node_modules/.store/is-number@6.0.0-*/node_modules/is-number)
65+
node "$W/stage.js" . pkg:npm/is-number@6.0.0 "$P"
66+
"$BIN" apply --offline; RC=$?
67+
echo "RESULT linked ${{ matrix.os }} npm ${{ matrix.npm }}: apply exit $RC is-number=[$(head20 "$P/index.js")]"
68+
echo "::endgroup::"

0 commit comments

Comments
 (0)