Skip to content

Commit

Permalink
Allow early termination to limit execution time with degenerate cases (
Browse files Browse the repository at this point in the history
…#365)

Co-authored-by: Tony Spataro <anthony.spataro@appfolio.com>
  • Loading branch information
Tony Spataro and Tony Spataro authored May 6, 2022
1 parent fffd8a7 commit f4cc58c
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 3 deletions.
9 changes: 6 additions & 3 deletions src/diff/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ Diff.prototype = {
let newLen = newString.length, oldLen = oldString.length;
let editLength = 1;
let maxEditLength = newLen + oldLen;
if(options.maxEditLength) {
maxEditLength = Math.min(maxEditLength, options.maxEditLength);
}

let bestPath = [{ newPos: -1, components: [] }];

// Seed editLength = 0, i.e. the content starts with the same values
Expand Down Expand Up @@ -87,12 +91,11 @@ Diff.prototype = {

// Performs the length of edit iteration. Is a bit fugly as this has to support the
// sync and async mode which is never fun. Loops over execEditLength until a value
// is produced.
// is produced, or until the edit length exceeds options.maxEditLength (if given),
// in which case it will return undefined.
if (callback) {
(function exec() {
setTimeout(function() {
// This should not happen, but we want to be safe.
/* istanbul ignore next */
if (editLength > maxEditLength) {
return callback();
}
Expand Down
4 changes: 4 additions & 0 deletions src/patch/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHea
}

const diff = diffLines(oldStr, newStr, options);
if(!diff) {
return;
}

diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier

function contextLines(lines) {
Expand Down
18 changes: 18 additions & 0 deletions test/diff/line.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,24 @@ describe('diff/line', function() {
'');
expect(convertChangesToXML(diffResult)).to.equal('<del>line\n\nold value \n\nline</del>');
});

describe('given options.maxEditLength', function() {
it('terminates early', function() {
const diffResult = diffLines(
'line\nold value\nline',
'line\nnew value\nline', { maxEditLength: 1 });
expect(diffResult).to.be.undefined;
});
it('terminates early - async', function(done) {
function callback(diffResult) {
expect(diffResult).to.be.undefined;
done();
}
diffLines(
'line\nold value\nline',
'line\nnew value\nline', { callback, maxEditLength: 1 });
});
});
});

// Trimmed Line Diff
Expand Down
13 changes: 13 additions & 0 deletions test/patch/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,19 @@ describe('patch/create', function() {
}]
});
});

describe('given options.maxEditLength', function() {
const options = { maxEditLength: 1 };

it('terminates early', function() {
const res = structuredPatch(
'oldfile', 'newfile',
'line2\nline3\nline4\n', 'line2\nline3\nline5',
'header1', 'header2', options
);
expect(res).to.be.undefined;
});
});
});

describe('#formatPatch', function() {
Expand Down

0 comments on commit f4cc58c

Please sign in to comment.