-
Notifications
You must be signed in to change notification settings - Fork 362
fix: Protect config files from declaring invalid keys #792
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/config.js
Outdated
type ApplyConfigToArgvParams = {| | ||
argv: Object, | ||
configObject: Object, | ||
configObject?: Object, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kumar303, this was an unintended error, I'll fix this in the next commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok (in reply to https://github.com/mozilla/web-ext/pull/792/files#r99653520)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great start! In addition to these change requests, the config function should also throw an error for non camel-cased options (because they won't end up being applied to the program). I saw your note that you couldn't think of a way to do it but there is a way. Start by adding a failing test and I can help you think through it.
src/config.js
Outdated
type ApplyConfigToArgvParams = {| | ||
argv: Object, | ||
configObject: Object, | ||
configObject?: Object, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok (in reply to https://github.com/mozilla/web-ext/pull/792/files#r99653520)
tests/unit/test.config.js
Outdated
}, | ||
}); | ||
const configObject = { | ||
foo: '/configured/foo', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same comment applies to this test. Change foo
to a valid option.
tests/unit/test.config.js
Outdated
}, | ||
}); | ||
const configObject = { | ||
foo: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same comment applies to this test. Change foo
to a valid option.
tests/unit/test.config.js
Outdated
}; | ||
assert.throws(() => { | ||
applyConfigToArgv({argv, configObject, defaultValues}); | ||
}, UsageError, /Please fix your config and try again/); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This regex should make sure that the option name was specified in the error message
tests/unit/test.config.js
Outdated
}, | ||
}); | ||
const configObject = { | ||
foo: '/configured/foo', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test should not throw an error because it's testing that default values are preserved. You can fix it by changing foo
to some kind of valid option. However, you will have to define a new option in addition to source-dir
to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the quick fixes, this is getting closer
src/config.js
Outdated
} | ||
if (!argv.hasOwnProperty(option)) { | ||
if (!argv.hasOwnProperty(option) && | ||
!argv.hasOwnProperty(decamelize(option, '-'))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't this just be if (!argv.hasOwnProperty(decamelize(option, '-'))) { ...
?
src/config.js
Outdated
'because this is an unknown option'); | ||
continue; | ||
throw new UsageError(`The option ${option} is invalid.` + | ||
' Please fix your config and try again.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error message should have the path to the config so that the user can find out which config they need to fix. This means applyConfigToArgv() will need to accept a filename argument.
src/config.js
Outdated
if (!argv.hasOwnProperty(option)) { | ||
if (!argv.hasOwnProperty(option) && | ||
!argv.hasOwnProperty(decamelize(option, '-'))) { | ||
log.debug(`Ignoring configuration: ${option}=${configObject[option]} ` + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this debug statement isn't necessary anymore because the developer will see an informative error about it.
src/config.js
Outdated
// this happening | ||
// of this happening | ||
if (camelCase(option) !== option) { | ||
throw new UsageError(`Please use camel case to specify ${option} ` + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since you have the function already you can just tell them what to do (which will help them fix it faster):
throw new UsageError(
`The config option "${option}" must be specified in camel case: "${camelCase(option)}"`
);
src/config.js
Outdated
'because this is an unknown option'); | ||
continue; | ||
throw new UsageError(`The option ${option} is invalid.` + | ||
' Please fix your config and try again.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than say "please fix [thing]," I think it's more useful to state exactly what the error was as a matter of fact. I would suggest something more like:
throw new UsageError(
`The config file at ${configFilename} specified an unknown option: "${option}"`
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, just some minor change requests
src/config.js
Outdated
argv: Object, | ||
configObject: Object, | ||
defaultValues: Object, | ||
configFileName?: string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a required argument. Why did you want it optional? For the tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if I don't make this optional, I'll have to add a file path to all the tests.
tests/unit/test.config.js
Outdated
'source-dir': 'fake/value/', | ||
}; | ||
assert.throws(() => { | ||
applyConfigToArgv({argv, configObject, defaultValues}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could make a shorter helper function just for testing to make it easier to omit defaults. Something like this:
const applyConf = (params) => applyConfigToArgv({
configFilename: 'some/path/to/config.js',
...params,
});
tests/unit/test.config.js
Outdated
}); | ||
const configFileName = 'fake/path/to/config'; | ||
const configObject = { | ||
artifacts: 'fake/value/', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the check for invalid options relies on the original hyphenated key, I think it would be good to make this artifactsDir
to cover that part of the logic.
@kumar303, could you review this again? Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great, thanks. I can resolve the package.json
conflict before merging.
Fixes #772