diff --git a/packages/conventional-commits-parser/lib/parser.js b/packages/conventional-commits-parser/lib/parser.js index 9cee0e2ce..fc9c94261 100644 --- a/packages/conventional-commits-parser/lib/parser.js +++ b/packages/conventional-commits-parser/lib/parser.js @@ -5,7 +5,16 @@ const CATCH_ALL = /()(.+)/gi const SCISSOR = '# ------------------------ >8 ------------------------' function trimOffNewlines (input) { - return input.replace(/^(?:\r|\n)+|(?:\r|\n)+$/g, '') + const result = input.match(/[^\r\n]/) + if (!result) { + return '' + } + const firstIndex = result.index + let lastIndex = input.length - 1 + while (input[lastIndex] === '\r' || input[lastIndex] === '\n') { + lastIndex-- + } + return input.substring(firstIndex, lastIndex + 1) } function append (src, line) { diff --git a/packages/conventional-commits-parser/test/parser.spec.js b/packages/conventional-commits-parser/test/parser.spec.js index eee5f5af0..76b885847 100644 --- a/packages/conventional-commits-parser/test/parser.spec.js +++ b/packages/conventional-commits-parser/test/parser.spec.js @@ -99,6 +99,15 @@ describe('parser', function () { }).to.throw('Expected regex') }) + it('should not be subject to ReDos', function () { + // This test will timeout if the bug is present. + expect(parser( + 'b' + '\r\n'.repeat(1000000) + 'b', + options, + reg + )) + }) + it('should trim extra newlines', function () { expect(parser( '\n\n\n\n\n\n\nfeat(scope): broadcast $destroy event on scope destruction\n\n\n' +