Skip to content

Commit 3bfd6c6

Browse files
committed
fix to work properly even if Object.prototype has been extended (thanks to Max Al-Shawabkeh!)
1 parent c1b4ec3 commit 3bfd6c6

File tree

1 file changed

+93
-81
lines changed

1 file changed

+93
-81
lines changed

difflib.js

100644100755
Lines changed: 93 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,38 @@
1-
/*
2-
This is part of jsdifflib v1.0. <http://github.com/cemerick/jsdifflib>
1+
/***
2+
This is part of jsdifflib v1.0. <http://snowtide.com/jsdifflib>
33
4-
Copyright 2007 - 2011 Chas Emerick <[email protected]>. All rights reserved.
4+
Copyright (c) 2007, Snowtide Informatics Systems, Inc.
5+
All rights reserved.
56
6-
Redistribution and use in source and binary forms, with or without modification, are
7-
permitted provided that the following conditions are met:
7+
Redistribution and use in source and binary forms, with or without modification,
8+
are permitted provided that the following conditions are met:
89
9-
1. Redistributions of source code must retain the above copyright notice, this list of
10-
conditions and the following disclaimer.
10+
* Redistributions of source code must retain the above copyright notice, this
11+
list of conditions and the following disclaimer.
12+
* Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
* Neither the name of the Snowtide Informatics Systems nor the names of its
16+
contributors may be used to endorse or promote products derived from this
17+
software without specific prior written permission.
1118
12-
2. Redistributions in binary form must reproduce the above copyright notice, this list
13-
of conditions and the following disclaimer in the documentation and/or other materials
14-
provided with the distribution.
15-
16-
THIS SOFTWARE IS PROVIDED BY Chas Emerick ``AS IS'' AND ANY EXPRESS OR IMPLIED
17-
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18-
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Chas Emerick OR
19-
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20-
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22-
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24-
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25-
26-
The views and conclusions contained in the software and documentation are those of the
27-
authors and should not be interpreted as representing official policies, either expressed
28-
or implied, of Chas Emerick.
29-
*/
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21+
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22+
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24+
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25+
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27+
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
28+
DAMAGE.
29+
***/
30+
/* Author: Chas Emerick <[email protected]> */
3031
__whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true};
3132

3233
difflib = {
3334
defaultJunkFunction: function (c) {
34-
return c in __whitespace;
35+
return __whitespace.hasOwnProperty(c);
3536
},
3637

3738
stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); },
@@ -87,12 +88,12 @@ difflib = {
8788
// is in the dict (js object) provided to this function; replaces being able to
8889
// carry around dict.has_key in python...
8990
__isindict: function (dict) {
90-
return function (key) { return key in dict; };
91+
return function (key) { return dict.hasOwnProperty(key); };
9192
},
9293

9394
// replacement for python's dict.get function -- need easy default values
9495
__dictget: function (dict, key, defaultValue) {
95-
return key in dict ? dict[key] : defaultValue;
96+
return dict.hasOwnProperty(key) ? dict[key] : defaultValue;
9697
},
9798

9899
SequenceMatcher: function (a, b, isjunk) {
@@ -121,7 +122,7 @@ difflib = {
121122
var populardict = {};
122123
for (var i = 0; i < b.length; i++) {
123124
var elt = b[i];
124-
if (elt in b2j) {
125+
if (b2j.hasOwnProperty(elt)) {
125126
var indices = b2j[elt];
126127
if (n >= 200 && indices.length * 100 > n) {
127128
populardict[elt] = 1;
@@ -134,20 +135,23 @@ difflib = {
134135
}
135136
}
136137

137-
for (var elt in populardict)
138-
delete b2j[elt];
138+
for (var elt in populardict) {
139+
if (populardict.hasOwnProperty(elt)) {
140+
delete b2j[elt];
141+
}
142+
}
139143

140144
var isjunk = this.isjunk;
141145
var junkdict = {};
142146
if (isjunk) {
143147
for (var elt in populardict) {
144-
if (isjunk(elt)) {
148+
if (populardict.hasOwnProperty(elt) && isjunk(elt)) {
145149
junkdict[elt] = 1;
146150
delete populardict[elt];
147151
}
148152
}
149153
for (var elt in b2j) {
150-
if (isjunk(elt)) {
154+
if (b2j.hasOwnProperty(elt) && isjunk(elt)) {
151155
junkdict[elt] = 1;
152156
delete b2j[elt];
153157
}
@@ -174,14 +178,16 @@ difflib = {
174178
var newj2len = {};
175179
var jdict = difflib.__dictget(b2j, a[i], nothing);
176180
for (var jkey in jdict) {
177-
j = jdict[jkey];
178-
if (j < blo) continue;
179-
if (j >= bhi) break;
180-
newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1;
181-
if (k > bestsize) {
182-
besti = i - k + 1;
183-
bestj = j - k + 1;
184-
bestsize = k;
181+
if (jdict.hasOwnProperty(jkey)) {
182+
j = jdict[jkey];
183+
if (j < blo) continue;
184+
if (j >= bhi) break;
185+
newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1;
186+
if (k > bestsize) {
187+
besti = i - k + 1;
188+
bestj = j - k + 1;
189+
bestsize = k;
190+
}
185191
}
186192
}
187193
j2len = newj2len;
@@ -206,7 +212,7 @@ difflib = {
206212
}
207213

208214
while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) &&
209-
a[besti + bestsize] == b[bestj + bestsize]) {
215+
a[besti + bestsize] == b[bestj + bestsize]) {
210216
bestsize++;
211217
}
212218

@@ -246,17 +252,19 @@ difflib = {
246252
var i1 = j1 = k1 = block = 0;
247253
var non_adjacent = [];
248254
for (var idx in matching_blocks) {
249-
block = matching_blocks[idx];
250-
i2 = block[0];
251-
j2 = block[1];
252-
k2 = block[2];
253-
if (i1 + k1 == i2 && j1 + k1 == j2) {
254-
k1 += k2;
255-
} else {
256-
if (k1) non_adjacent.push([i1, j1, k1]);
257-
i1 = i2;
258-
j1 = j2;
259-
k1 = k2;
255+
if (matching_blocks.hasOwnProperty(idx)) {
256+
block = matching_blocks[idx];
257+
i2 = block[0];
258+
j2 = block[1];
259+
k2 = block[2];
260+
if (i1 + k1 == i2 && j1 + k1 == j2) {
261+
k1 += k2;
262+
} else {
263+
if (k1) non_adjacent.push([i1, j1, k1]);
264+
i1 = i2;
265+
j1 = j2;
266+
k1 = k2;
267+
}
260268
}
261269
}
262270

@@ -276,23 +284,25 @@ difflib = {
276284
var block, ai, bj, size, tag;
277285
var blocks = this.get_matching_blocks();
278286
for (var idx in blocks) {
279-
block = blocks[idx];
280-
ai = block[0];
281-
bj = block[1];
282-
size = block[2];
283-
tag = '';
284-
if (i < ai && j < bj) {
285-
tag = 'replace';
286-
} else if (i < ai) {
287-
tag = 'delete';
288-
} else if (j < bj) {
289-
tag = 'insert';
287+
if (blocks.hasOwnProperty(idx)) {
288+
block = blocks[idx];
289+
ai = block[0];
290+
bj = block[1];
291+
size = block[2];
292+
tag = '';
293+
if (i < ai && j < bj) {
294+
tag = 'replace';
295+
} else if (i < ai) {
296+
tag = 'delete';
297+
} else if (j < bj) {
298+
tag = 'insert';
299+
}
300+
if (tag) answer.push([tag, i, ai, j, bj]);
301+
i = ai + size;
302+
j = bj + size;
303+
304+
if (size) answer.push(['equal', ai, i, bj, j]);
290305
}
291-
if (tag) answer.push([tag, i, ai, j, bj]);
292-
i = ai + size;
293-
j = bj + size;
294-
295-
if (size) answer.push(['equal', ai, i, bj, j]);
296306
}
297307

298308
return answer;
@@ -327,19 +337,21 @@ difflib = {
327337
var nn = n + n;
328338
var groups = [];
329339
for (var idx in codes) {
330-
code = codes[idx];
331-
tag = code[0];
332-
i1 = code[1];
333-
i2 = code[2];
334-
j1 = code[3];
335-
j2 = code[4];
336-
if (tag == 'equal' && i2 - i1 > nn) {
337-
groups.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]);
338-
i1 = Math.max(i1, i2-n);
339-
j1 = Math.max(j1, j2-n);
340+
if (codes.hasOwnProperty(idx)) {
341+
code = codes[idx];
342+
tag = code[0];
343+
i1 = code[1];
344+
i2 = code[2];
345+
j1 = code[3];
346+
j2 = code[4];
347+
if (tag == 'equal' && i2 - i1 > nn) {
348+
groups.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]);
349+
i1 = Math.max(i1, i2-n);
350+
j1 = Math.max(j1, j2-n);
351+
}
352+
353+
groups.push([tag, i1, i2, j1, j2]);
340354
}
341-
342-
groups.push([tag, i1, i2, j1, j2]);
343355
}
344356

345357
if (groups && groups[groups.length - 1][0] == 'equal') groups.pop();

0 commit comments

Comments
 (0)