import { expect } from 'chai'; import { parseCommaSeparatedKeyValue, parseFeatures } from '../lib/browser/parse-features-string'; describe('feature-string parsing', () => { it('is indifferent to whitespace around keys and values', () => { const checkParse = (string: string, parsed: Record) => { const features = parseCommaSeparatedKeyValue(string); expect(features).to.deep.equal(parsed); }; checkParse('a=yes,c=d', { a: true, c: 'd' }); checkParse('a=yes ,c=d', { a: true, c: 'd' }); checkParse('a=yes, c=d', { a: true, c: 'd' }); checkParse('a=yes , c=d', { a: true, c: 'd' }); checkParse(' a=yes , c=d', { a: true, c: 'd' }); checkParse(' a= yes , c=d', { a: true, c: 'd' }); checkParse(' a = yes , c=d', { a: true, c: 'd' }); checkParse(' a = yes , c =d', { a: true, c: 'd' }); checkParse(' a = yes , c = d', { a: true, c: 'd' }); checkParse(' a = yes , c = d ', { a: true, c: 'd' }); }); describe('parseFeatures allowlist', () => { it('passes through allowlisted presentational options', () => { const { options } = parseFeatures('width=400,height=300,show=no,frame=no,title=hi,backgroundColor=#fff,left=10,top=20'); expect(options).to.deep.equal({ width: 400, height: 300, show: false, frame: false, title: 'hi', backgroundColor: '#fff', left: 10, top: 20, x: 10, y: 20 }); }); it('drops non-allowlisted options that would be unsafe to pass to BrowserWindow', () => { const { options } = parseFeatures('icon=/etc/passwd,width=400'); expect(options).to.deep.equal({ width: 400 }); expect(options).to.not.have.property('icon'); }); it('drops non-allowlisted options even when paired with UNC paths', () => { const { options } = parseFeatures('icon=\\\\attacker.example\\share\\x.png,show=no'); expect(options).to.deep.equal({ show: false }); expect(options).to.not.have.property('icon'); }); it('drops unknown options', () => { const { options } = parseFeatures('something-unknown=foo,width=400'); expect(options).to.deep.equal({ width: 400 }); expect(options).to.not.have.property('something-unknown'); }); it('still extracts allowlisted webPreferences', () => { const { options, webPreferences } = parseFeatures('icon=/etc/passwd,nodeIntegration=no,width=400'); expect(options).to.deep.equal({ width: 400 }); expect(webPreferences).to.deep.equal({ nodeIntegration: false }); }); }); });