For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

hoolio's avatar
hoolio
Icon for Cirrostratus rankCirrostratus
Jun 29, 2010

Unexpected result from foreach loop on 10.2

While testing a simple iRule to print out the contents of an array, I found a weird result when using "foreach {name value} [array get myarray]" on 10.2.0. The unexpected output is bolded below for the 10.2.0 test output. Basically, it looks like the varlist assignment isn't happening correcting when using more than one variable. I tried testing in RULE_INIT and CLIENT_ACCEPTED to see if the issue involved global variables, but saw the bad result in both tests.

Does anyone have a suggestion for what might be causing this? I'll open a case but figured I'd check here as well.

Thanks, Aaron

I tested with an example from the TCL wiki page for arrays:


 From http://www.tcl.tk/man/tcl8.4/TclCmd/array.htmM8
array set colorcount {
    red   1
    green 5
    blue  4
    white 9
}
foreach {color count} [array get colorcount] {
   puts "Color: $color Count: $count" 
}
 => Color: blue Count: 4
    Color: white Count: 9
    Color: green Count: 5
    Color: red Count: 1
foreach color [array names colorcount] {
   puts "Color: $color Count: $colorcount($color)" 
}
 => Color: blue Count: 4
    Color: white Count: 9
    Color: green Count: 5
    Color: red Count: 1

Testing this on tclsh.exe and 9.4.4 return expected results as listed below. However, on 10.2.0, "foreach {color count} [array get colorcount]" returns unexpected results for $color and $count.


when RULE_INIT {
   
   array set colorcount {
      red    1
      green    5
      blue    4
      white    9
   }
   log local0. "\[array size colorcount\]: [array size colorcount]"
   log local0. "\[array get colorcount\]: [array get colorcount]"
   log local0. ""
   log local0. "foreach {color count} \[array get colorcount\]:"
   foreach {color count} [array get colorcount] {
      log local0. "Color: $color Count: $count"
   }
   log local0. ""
   log local0. "foreach color \[array names colorcount\]:"
   foreach color [array names colorcount] {
      log local0. "Color: $color Count: $colorcount($color)" 
   }
}

Output on 10.2.0:

< RULE_INIT >: [array size colorcount]: 4

< RULE_INIT >: [array get colorcount]: blue 4 white 9 green 5 red 1

< RULE_INIT >:

< RULE_INIT >: foreach {color count} [array get colorcount]:

 

< RULE_INIT >: Color: blue Count: blue

 

< RULE_INIT >: Color: 4 Count: 4

 

< RULE_INIT >: Color: white Count: white

 

< RULE_INIT >: Color: 9 Count: 9

< RULE_INIT >:

< RULE_INIT >: foreach color [array names colorcount]:

< RULE_INIT >: Color: blue Count: 4

< RULE_INIT >: Color: white Count: 9

< RULE_INIT >: Color: green Count: 5

< RULE_INIT >: Color: red Count: 1

Output on 9.4.4:

Rule : [array size colorcount]: 4

Rule : [array get colorcount]: blue 4 white 9 green 5 red 1

Rule :

Rule : foreach {color count} [array get colorcount]:

Rule : Color: blue Count: 4

Rule : Color: white Count: 9

Rule : Color: green Count: 5

Rule : Color: red Count: 1

Rule :

Rule : foreach color [array names colorcount]:

Rule : Color: blue Count: 4

Rule : Color: white Count: 9

Rule : Color: green Count: 5

Rule : Color: red Count: 1

Output from Cygwin tclsh.exe:

% array set colorcount {

red 1

green 5

blue 4

white 9

}

% array size colorcount

4

% foreach {color count} [array get colorcount] {

puts "Color: $color Count: $count"

}

Color: blue Count: 4

Color: white Count: 9

Color: green Count: 5

Color: red Count: 1

% foreach color [array names colorcount] {

puts "Color: $color Count: $colorcount($color)"

}

Color: blue Count: 4

Color: white Count: 9

Color: green Count: 5

Color: red Count: 1

The iRule is the exact same on 9.4.4 and 10.2.0:

[hooleya@ltm.9.4.4:Active] log b version|grep Version

BIG-IP Version 9.4.4 94.0

[hooleya@ltm.9.4.4:Active] log b rule hooleya_array_rule list|md5sum

4cda0e55694c49036ac7274a6ec3763f -

[hooleya@ltm.10.2.0:Active] log b version|grep Version

BIG-IP Version 10.2.0 1707.0

[hooleya@ltm.10.2.0:Active] log b rule hooleya_array_rule list|md5sum

4cda0e55694c49036ac7274a6ec3763f -

5 Replies

  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    This is CR140814, affecting 10.1 and 10.2. I do not believe that it is currently fixed in any hotfix.
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Thanks Spark. That was an odd one to run into.

     

     

    Aaron
  • This explains why my code broke and was reporting just as you say.

     

    i changed the references to the second form (requiring another line of code) and it now works.

     

    almost... so i have a side question...

     

     

    for V10 CMP the $:: syntax is supposed to be eliminated, correct?

     

    i can't figure out what the replacement syntax is to make this work. if i just remove the $ it doesn't provide the value of the array element.... code:

     

     

    earlier the array "active_clients" was defined:

     

    when RULE_INIT {

     

    array set ::active_clients { }

     

    }

     

     

    then the routine to display the contents of this array is:

     

     

    foreach key [array names ::active_clients] {

     

    set value $::active_clients($key)

     

    append rpt "$key$value\n"

     

    }

     

     

    how do i do this in the "CMP compatible" form?

     

    thanks so much.
  • use the static namespace. Nat has a good example here: http://devcentral.f5.com/weblogs/jason/archive/2009/05/20/optimize-this-contest-1.aspx Click Here
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Hi Brad,

     

     

    Your post became corrupted. Can you repost the iRule in [ code ] [/ code ] blocks?

     

     

    Also, the static namespace wouldn't allow you to modify the values after the RULE_INIT event and have those changes sync'ed across multiple TMM instances. If you need to use a globally available array, you can still use $::my_array--it just won't be CMP compatible. You could use the table commands instead for similar functionality that is CMP compatible:

     

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/table

     

     

    Aaron