Skip to content

Commit

Permalink
Prevent ReDoS
Browse files Browse the repository at this point in the history
To fix https://github.com/lodash/lodash/issues/3359, modified reHasUnicodeWord to remove an unnecessary comma which made the regex greedy, this is only a test regex and not a matching regex. Added unit tests, this now should run under 5 ms instead of over 1000 ms for huge 50k+ char words.
  • Loading branch information
manuel-jasso committed Aug 28, 2018
1 parent 2cc247d commit d8e16f6
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lodash.js
Expand Up @@ -277,7 +277,7 @@
var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');

/** Used to detect strings that need a more robust regexp to match words. */
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;

/** Used to assign default `context` object properties. */
var contextProps = [
Expand Down
16 changes: 16 additions & 0 deletions test/test.js
Expand Up @@ -25206,6 +25206,22 @@

assert.deepEqual(actual, [['a'], ['b'], ['c']]);
});

var maxMs = 5;
QUnit.test(`should take less than ${maxMs} ms to prevent ReDoS`, function(assert) {
assert.expect(3);

var hugeWordLen = 50000;
var hugeWord = 'A'.repeat(hugeWordLen);
var startTime = Date.now();
assert.deepEqual(_.words(hugeWord+'AeiouAreVowels'), [hugeWord, 'Aeiou', 'Are', 'Vowels']);
assert.deepEqual(_.words(hugeWord+'ÆiouAreVowels'), [hugeWord, 'Æiou', 'Are', 'Vowels']);
var endTime = Date.now();
var timeSpent = endTime - startTime;

assert.ok(timeSpent < maxMs, `operation took ${timeSpent} ms`);
});

}());

/*--------------------------------------------------------------------------*/
Expand Down

0 comments on commit d8e16f6

Please sign in to comment.