From cfedde0fa69398179ba0500db2ce0ea486a293ca Mon Sep 17 00:00:00 2001 From: le king fu Date: Sat, 2 May 2026 11:49:13 -0400 Subject: [PATCH] test(smoke): add non-regression smoke for uuid + package overrides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plain-node script invoked via `npm test`. Catches the buffer-bounds regression area from GHSA-w5hq-g745-h8pq (uuid v3/v5 with buffer arg) and validates package.json structure. No jest/Expo runtime needed — runs in seconds, suitable for the defenseur-auto chain to gate auto-PRs. --- package.json | 1 + tests/smoke.test.cjs | 85 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 tests/smoke.test.cjs diff --git a/package.json b/package.json index 37165bc..f41f48e 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "version": "1.6.2", "scripts": { "start": "expo start", + "test": "node tests/smoke.test.cjs", "android": "expo start --android", "ios": "expo start --ios", "web": "expo start --web" diff --git a/tests/smoke.test.cjs b/tests/smoke.test.cjs new file mode 100644 index 0000000..12e47ca --- /dev/null +++ b/tests/smoke.test.cjs @@ -0,0 +1,85 @@ +'use strict'; + +// Non-regression smoke tests for npm overrides + deps integrity. +// Runs on plain node (no jest, no Expo runtime). Catches the obvious +// breakage paths after `npm install` rewrites lock for an `overrides` bump. +// +// node tests/smoke.test.cjs +// +// Exit 0 if all checks pass, 1 if any fails. + +const assert = require('node:assert').strict; + +let failed = 0; +function check(name, fn) { + try { + fn(); + console.log(`OK ${name}`); + } catch (e) { + failed++; + console.error(`FAIL ${name}: ${e.message}`); + } +} + +const UUID_RE = + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/; +const NAMESPACE = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; + +check('package.json is valid JSON with name + deps', () => { + const pkg = require('../package.json'); + assert.ok(pkg.name, 'package.json missing name'); + assert.ok(pkg.dependencies, 'package.json missing dependencies'); +}); + +check('uuid v4 generates well-formed UUID', () => { + const { v4 } = require('uuid'); + for (let i = 0; i < 5; i++) { + assert.match(v4(), UUID_RE); + } +}); + +// The uuid <14.0.0 advisory (GHSA-w5hq-g745-h8pq) is specifically about +// missing buffer bounds checks in v3/v5/v6. After bumping to v14, these +// must still produce valid UUIDs from a name + namespace. +check('uuid v3 with namespace produces valid UUID', () => { + const { v3 } = require('uuid'); + const id = v3('test-name', NAMESPACE); + assert.match(id, UUID_RE); +}); + +check('uuid v5 with namespace produces valid UUID', () => { + const { v5 } = require('uuid'); + const id = v5('test-name', NAMESPACE); + assert.match(id, UUID_RE); +}); + +// Buffer-arg path is the actual vuln site — must not throw and must +// fill the buffer with the UUID bytes. +check('uuid v3 with buffer arg fills buffer (vuln site)', () => { + const { v3 } = require('uuid'); + const buf = Buffer.alloc(16); + v3('test-name', NAMESPACE, buf); + // After the call, buf must have at least one non-zero byte. + assert.ok( + buf.some((b) => b !== 0), + 'buffer was not filled by uuid v3' + ); +}); + +check('uuid v5 with buffer arg fills buffer (vuln site)', () => { + const { v5 } = require('uuid'); + const buf = Buffer.alloc(16); + v5('test-name', NAMESPACE, buf); + assert.ok( + buf.some((b) => b !== 0), + 'buffer was not filled by uuid v5' + ); +}); + +if (failed === 0) { + console.log('\nsmoke OK'); + process.exit(0); +} else { + console.error(`\nsmoke FAIL (${failed} failure${failed > 1 ? 's' : ''})`); + process.exit(1); +}