Skip to content

Commit

Permalink
fix: guard select choices from reserved values
Browse files Browse the repository at this point in the history
  • Loading branch information
3cp committed May 22, 2019
1 parent 8221bb6 commit fe8cc7a
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
9 changes: 8 additions & 1 deletion lib/run-questionnaire.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,19 @@ async function textPrompt(question, {predefinedProperties, unattended, _debug})
return answer;
}

const RESERVED_VALUES = ['and', 'or', 'not', 'true', 'false'];

async function selectPrompt(question, pickedFeatures, {preselectedFeatures, unattended, _debug}) {
let {choices, multiple} = question;

choices.forEach(c => {
if (c.value && (typeof c.value !== 'string' || !c.value.match(/^[a-zA-Z1-9-]*$/))) {
throw new Error(`Value ${JSON.stringify(c.value)} is invalid. Only accept letters, numbers, and dash(-).` +
throw new Error(`Value ${JSON.stringify(c.value)} is invalid. Only accept letters, numbers, and dash(-).\n` +
'In question:\n' + JSON.stringify(question, null, 2) + '\n\n');
}

if (RESERVED_VALUES.includes(c.value)) {
throw new Error(`Value ${JSON.stringify(c.value)} is rejected, because it's one of reserved strings ${JSON.stringify(RESERVED_VALUES)}.\n` +
'In question:\n' + JSON.stringify(question, null, 2) + '\n\n');
}
});
Expand Down
5 changes: 5 additions & 0 deletions test/run-questionnaire.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ test('textPrompt validates user input', async t => {
test('selectPrompt rejects invalid choice value', async t => {
await t.throwsAsync(async () => selectPrompt({choices:[{value:'a&b'}]}, [], {preselectedFeatures: []}));
await t.throwsAsync(async () => selectPrompt({choices:[{value:'a b'}]}, [], {preselectedFeatures: []}));
await t.throwsAsync(async () => selectPrompt({choices:[{value:'and'}]}, [], {preselectedFeatures: []}));
await t.throwsAsync(async () => selectPrompt({choices:[{value:'or'}]}, [], {preselectedFeatures: []}));
await t.throwsAsync(async () => selectPrompt({choices:[{value:'not'}]}, [], {preselectedFeatures: []}));
await t.throwsAsync(async () => selectPrompt({choices:[{value:'true'}]}, [], {preselectedFeatures: []}));
await t.throwsAsync(async () => selectPrompt({choices:[{value:'false'}]}, [], {preselectedFeatures: []}));
});

test('selectPrompt returns value of the only choice without prompting', async t => {
Expand Down

0 comments on commit fe8cc7a

Please sign in to comment.