diff --git a/src/index.ts b/src/index.ts index 959b832..0a7801b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -34,7 +34,12 @@ export function parse(string: string): Credentials | undefined { if (!match) return undefined; // decode user pass - const userPass = base64.decode(match[1]); + let userPass: string; + try { + userPass = base64.decode(match[1]); + } catch { + return undefined; + } const colonIndex = userPass.indexOf(':'); if (colonIndex === -1) return undefined; diff --git a/src/parse-browser.spec.ts b/src/parse-browser.spec.ts new file mode 100644 index 0000000..a302bc8 --- /dev/null +++ b/src/parse-browser.spec.ts @@ -0,0 +1,32 @@ +import { afterAll, assert, beforeAll, describe, it, vi } from 'vitest'; + +describe.skipIf(!Uint8Array.fromBase64)('parse without Buffer', () => { + let parse: typeof import('./index.js').parse; + + beforeAll(async () => { + vi.stubGlobal('Buffer', undefined); + vi.resetModules(); + ({ parse } = await import('./index.js')); + }); + + afterAll(() => { + vi.unstubAllGlobals(); + vi.resetModules(); + }); + + it('should return undefined for invalid base64 characters', () => { + assert.strictEqual(parse('Basic .'), undefined); + assert.strictEqual(parse('Basic ~'), undefined); + }); + + it('should return undefined for incomplete base64', () => { + assert.strictEqual(parse('Basic Y'), undefined); + }); + + it('should parse valid credentials', () => { + assert.deepEqual(parse('Basic Zm9vOmJhcg=='), { + name: 'foo', + pass: 'bar', + }); + }); +});