Fix #2047: Infinite loop possible when for loop with range uses variables (#4853)

* fix #2047

* Additional check for 'step'; tests

* Fix #4105 (#4855)

* Update output

* Throw warning for unsupported runtimes, e.g. Node < 6 (#4839)

* fix #1403 (#4854)

* Update output

* [Change]: Destructuring with non-final spread should still use rest syntax (#4517) (#4825)

* destructuring optimization

* refactor

* minor improvement, fix errors

* minor refactoring

* improvements

* Update output

* Update output

* Fix #4843: bad output when assigning to @prop in destructuring assignment with defaults (#4848)

* fix #4843

* improvements

* typo

* small fix

* Fix #3441: parentheses wrapping expression throw invalid error  (#4849)

* fix #3441

* improvements

* refactor

* Fix #1726: expression in property access causes unexpected results (#4851)

* fix #1726

* Explain what's happening, rather than just linking to an issue

* Updated output

* Optimization

* Update output

* remove casting to number

* cleanup tests
This commit is contained in:
zdenko
2018-02-01 04:51:43 +01:00
committed by Geoffrey Booth
parent fc5ab1afa3
commit 9e80f6fa67
4 changed files with 111 additions and 11 deletions

View File

@@ -2031,7 +2031,7 @@
// When compiled normally, the range returns the contents of the *for loop*
// needed to iterate over the values in the range. Used by comprehensions.
compileNode(o) {
var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart;
var cond, condPart, from, gt, idx, idxName, known, lowerBound, lt, namedIndex, stepCond, stepPart, to, upperBound, varPart;
if (!this.fromVar) {
this.compileVariables(o);
}
@@ -2052,7 +2052,15 @@
}
[lt, gt] = [`${idx} <${this.equals}`, `${idx} >${this.equals}`];
// Generate the condition.
condPart = this.stepNum != null ? this.stepNum > 0 ? `${lt} ${this.toVar}` : `${gt} ${this.toVar}` : known ? ([from, to] = [this.fromNum, this.toNum], from <= to ? `${lt} ${to}` : `${gt} ${to}`) : (cond = this.stepVar ? `${this.stepVar} > 0` : `${this.fromVar} <= ${this.toVar}`, `${cond} ? ${lt} ${this.toVar} : ${gt} ${this.toVar}`);
[from, to] = [this.fromNum, this.toNum];
// Always check if the `step` isn't zero to avoid the infinite loop.
stepCond = this.stepNum ? `${this.stepNum} !== 0` : `${this.stepVar} !== 0`;
condPart = known ? this.step == null ? from <= to ? `${lt} ${to}` : `${gt} ${ // from < to
to}` : (lowerBound = `${from} <= ${idx} && ${lt} ${// from > to
to}`, upperBound = `${from} >= ${idx} && ${gt} ${to}`, from <= to ? `${stepCond} && ${lowerBound}` : `${stepCond} && ${// from < to
upperBound}`) : (lowerBound = `${this.fromVar} <= ${idx} && ${lt} ${// from > to
this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `${stepCond} && (${this.fromVar} <= ${this.toVar} ? ${lowerBound} : ${upperBound})`);
cond = this.stepVar ? `${this.stepVar} > 0` : `${this.fromVar} <= ${this.toVar}`;
// Generate the step.
stepPart = this.stepVar ? `${idx} += ${this.stepVar}` : known ? namedIndex ? from <= to ? `++${idx}` : `--${idx}` : from <= to ? `${idx}++` : `${idx}--` : namedIndex ? `${cond} ? ++${idx} : --${idx}` : `${cond} ? ${idx}++ : ${idx}--`;
if (namedIndex) {

View File

@@ -218,7 +218,7 @@
indexOfTag(i, ...pattern) {
var fuzz, j, k, ref, ref1;
fuzz = 0;
for (j = k = 0, ref = pattern.length; 0 <= ref ? k < ref : k > ref; j = 0 <= ref ? ++k : --k) {
for (j = k = 0, ref = pattern.length; undefined !== 0 && (0 <= ref ? 0 <= k && k < ref : 0 >= k && k > ref); j = 0 <= ref ? ++k : --k) {
if (pattern[j] == null) {
continue;
}