1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-22 19:07:54 +01:00

feat: stop regexes with whitespace (#4681)

This PR stops regexes with whitespace from being added as feature naming
patterns.
This commit is contained in:
Thomas Heartman 2023-09-14 09:56:23 +02:00 committed by GitHub
parent bf451f6549
commit 9bdee12ad9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 21 deletions

View File

@ -210,14 +210,31 @@ const ProjectForm: React.FC<IProjectForm> = ({
};
const onSetFeatureNamingPattern = (regex: string) => {
try {
new RegExp(regex);
setFeatureNamingPattern && setFeatureNamingPattern(regex);
delete errors.featureNamingPattern;
} catch (e) {
errors.featureNamingPattern = 'Invalid regular expression';
setFeatureNamingPattern && setFeatureNamingPattern(regex);
const disallowedStrings = [
' ',
'\\t',
'\\s',
'\\n',
'\\r',
'\\f',
'\\v',
];
if (
disallowedStrings.some(blockedString =>
regex.includes(blockedString)
)
) {
errors.featureNamingPattern =
'Whitespace is not allowed in the expression';
} else {
try {
new RegExp(regex);
delete errors.featureNamingPattern;
} catch (e) {
errors.featureNamingPattern = 'Invalid regular expression';
}
}
setFeatureNamingPattern && setFeatureNamingPattern(regex);
updateNamingExampleError({
pattern: regex,
example: featureNamingExample || '',

View File

@ -61,6 +61,19 @@ describe('validate incoming feature naming data', () => {
}
});
test.each([' ', '\\t', '\\n'])(
'patterns with illegal characters (%s) are invalid',
(string) => {
const pattern = `-${string}[0-9]+`;
expect(
checkFeatureNamingData({
pattern,
}),
).toMatchObject({ state: 'invalid' });
},
);
test('feature naming data with a non-empty example but an empty pattern is invalid', () => {
expect(
checkFeatureNamingData({
@ -78,6 +91,19 @@ describe('validate incoming feature naming data', () => {
}),
).toMatchObject({ state: 'invalid' });
});
test('if the pattern contains disallowed characters, a match is not attempted against the example', () => {
const result = checkFeatureNamingData({
pattern: 'a. [0-9]+',
example: 'obviously-not-a-match',
});
if (result.state === 'valid') {
fail('Expected invalid result');
}
expect(result.reasons.length).toBe(1);
});
});
describe('validate feature flag names against a pattern', () => {

View File

@ -10,22 +10,38 @@ export const checkFeatureNamingData = (
if (featureNaming) {
const { pattern, example, description } = featureNaming;
const errors: string[] = [];
if (pattern && example && !example.match(compileRegex(pattern))) {
errors.push(
`You've provided a feature flag naming example ("${example}") that doesn't match your feature flag naming pattern ("${pattern}"). Please provide an example that matches your supplied pattern. Bear in mind that the pattern must match the whole example, as if it were surrounded by '^' and "$".`,
);
}
const disallowedStrings = [
' ',
'\\t',
'\\s',
'\\n',
'\\r',
'\\f',
'\\v',
];
if (!pattern && example) {
errors.push(
"You've provided a feature flag naming example, but no feature flag naming pattern. You must specify a pattern to use an example.",
);
}
if (pattern) {
if (disallowedStrings.some((str) => pattern.includes(str))) {
errors.push(
`Feature flag names can not contain whitespace. You've provided a feature flag naming pattern that contains a whitespace character: "${pattern}". Remove any whitespace characters from your pattern.`,
);
} else if (example && !example.match(compileRegex(pattern))) {
errors.push(
`You've provided a feature flag naming example ("${example}") that doesn't match your feature flag naming pattern ("${pattern}"). Please provide an example that matches your supplied pattern. Bear in mind that the pattern must match the whole example, as if it were surrounded by '^' and "$".`,
);
}
} else {
if (example) {
errors.push(
"You've provided a feature flag naming example, but no feature flag naming pattern. You must specify a pattern to use an example.",
);
}
if (!pattern && description) {
errors.push(
"You've provided a feature flag naming pattern description, but no feature flag naming pattern. You must have a pattern to use a description.",
);
if (description) {
errors.push(
"You've provided a feature flag naming pattern description, but no feature flag naming pattern. You must have a pattern to use a description.",
);
}
}
const [first, ...rest] = errors;