Highlighted

for-in loop bug

New Here ,
Jun 17, 2015

Copy link to clipboard

Copied

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.

Views

148

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

for-in loop bug

New Here ,
Jun 17, 2015

Copy link to clipboard

Copied

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.

Views

149

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Jun 17, 2015 0

Have something to add?

Join the conversation