• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

for-in loop bug

Guest
Jun 17, 2015 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

199

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
community guidelines
no replies

Have something to add?

Join the conversation
Resources
Documentation