diff --git a/src/lib/isRgbColor.js b/src/lib/isRgbColor.js index e9fb60253..eb2a563ef 100644 --- a/src/lib/isRgbColor.js +++ b/src/lib/isRgbColor.js @@ -27,8 +27,11 @@ export default function isRgbColor(str, options) { if (!startsWithRgb.test(str)) { return false; } - // strip all whitespace - str = str.replace(/\s/g, ''); + // collapse whitespace runs, then drop only the whitespace adjacent to the + // parentheses and commas; whitespace inside a channel/alpha/percent token is + // kept so malformed values such as 'rgb(2 55,0,0)' or 'rgb(25 %,0%,0%)' are + // still rejected. Two linear passes avoid polynomial backtracking (#2885) + str = str.replace(/\s+/g, ' ').replace(/ ?([(),]) ?/g, '$1'); } if (!includePercentValues) { diff --git a/test/validators.test.js b/test/validators.test.js index 98d2a12ff..cd9eb9156 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -5309,11 +5309,15 @@ describe('Validators', () => { 'rgba(255, 255, 255, 0.1)', 'rgb(5% ,5% ,5%)', 'rgba(5%,5%,5%, .3)', + 'rgb( 255 , 0 , 0 )', ], invalid: [ 'r g b( 0, 251, 222 )', 'rgb(4,4,5%)', 'rgb(101%,101%,101%)', + 'rgb(2 55,0,0)', + 'rgba(0,0,0,0. 5)', + 'rgb(25 %,0%,0%)', ], });