Optimize util.removeTrailingSpaces (#848)

Backtracking regexes have pathological worst-case performance when
a long line contains a large amount of whitespace not followed by
a newline, since the regex engine will attempt to match the regex
at each whitespace character, read ahead to the non-whitespace non-
newline, declare no match, and try again at the next whitespace.

E.g. try running

    util.removeTrailingSpaces(new Array(1e6).join(' ') + 'a').length

which would hang V8.
This commit is contained in:
Daniel Huigens
2019-01-27 01:22:47 +01:00
committed by Sanjana Rajan
parent f018f60b9c
commit d91b064e14
5 changed files with 20 additions and 16 deletions

View File

@@ -243,7 +243,7 @@ function dearmor(input) {
throw new Error('Misformed armored text');
}
// remove trailing whitespace at end of lines
line = line.replace(/[\t\r\n ]+$/, '');
line = util.removeTrailingSpaces(line.replace(/[\r\n]/g, ''));
if (!type) {
if (reSplit.test(line)) {
type = getType(line);
@@ -294,7 +294,7 @@ function dearmor(input) {
let remainder = await reader.readToEnd();
if (!remainder.length) remainder = '';
remainder = line + remainder;
remainder = remainder.replace(/[\t\r ]+$/mg, '');
remainder = util.removeTrailingSpaces(remainder.replace(/\r/g, ''));
const parts = remainder.split(reSplit);
if (parts.length === 1) {
throw new Error('Misformed armored text');