Quantcast
Channel: Adobe Community : Popular Discussions - ColdFusion
Viewing all articles
Browse latest Browse all 14291

for-in loop bug

$
0
0

Hello,

 

I tried to add this as a bug to the Coldfusion Bug tracker (https://bugbase.adobe.com/) but ironically, I get a default Coldfusion error page when I log in.

 

I believe there is a serious bug with the for-in construct when used in a particular fashion. In particular, if the "in" expression is a function call, it appears that the function is invoked multiple times (to be precise, it always appears to be 5 times).

 

Clearly there are many situations where this could have serious consequences, not least if the function does any serious work.

 

Key points:

 

  • Tested on Coldfusion 10 update 16
  • Using a for-in construct where the "in" expression invokes a function results in that function being invoked multiple times.
  • It doesn't seem to matter what the function returns (e.g. struct, array, potentially other iterables)

 

Workaround:

 

  • Assign the result of the function call to a local variable outside the for-in construct

 

Severity:

 

This a serious issue as,

 

  • It is easy to cause using a common idiom
  • It is completed unexpected
  • The fact that it is happening is essentially invisible to the developer
  • The results are potentially very serious

 

Speculation:

 

I speculate that the code is pre-processed into a construct that does (in clause).size() (in clause).iterator(), etc

 

Test Case:

 

See below for some code which tests this:

 

component displayname="ForInTest" {  ForInTest function init() {    variables.count = 0;    return this;  }  void function test1() {    variables.count = 0;    for( var item in getArray() ) {      // do something interesting    }    if( variables.count==1 ) {      writeoutput( "getArray() was called once." );    }    else {      writeoutput( "getArray() was called multiple times! (" & variables.count & ")" );    }  }  void function test2() {    variables.count = 0;    var items = getArray();    for( var item in items ) {      // do something interesting    }    if( variables.count==1 ) {      writeoutput( "getArray() was called once." );    }    else {      writeoutput( "getArray() was called multiple times! (" & variables.count & ")" );    }  }  private array function getArray() {    variables.count++;    var data = [1,2,3];    return data;  }
}

 

var test = new ForInTest();
test.test1();
test.test2();

 

Output:

getArray() was called multiple times! (5)
getArray() was called once.

Viewing all articles
Browse latest Browse all 14291

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>