Created
August 13, 2019 11:29
Unexpected Variable Assignment Using Function LocalMode Modern With Nested Closures In Lucee 5.3.2.77
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
component | |
output = false | |
hint = "I define the application settings and event handlers." | |
{ | |
this.name = hash( getCurrentTemplatePath() ); | |
// By using "modern" localmode, any unscoped variable assignment will be applied to | |
// current Function's local scope (never to the Variable's scope). | |
this.localmode = "modern"; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfscript> | |
echo( "[A] Value: " & test() ); | |
// ------------------------------------------------------------------------------- // | |
// ------------------------------------------------------------------------------- // | |
public string function test() { | |
var value = "Original"; | |
(() => { | |
// CAUTION: Because the entire Application is running in localmode "modern", | |
// this "unscoped assignment" will be applied to the current Local scope, | |
// which traps it inside of this closure. | |
value = "Changed"; | |
})(); | |
return( value ); | |
} | |
</cfscript> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfscript> | |
echo( "[B] Value: " & test() ); | |
// ------------------------------------------------------------------------------- // | |
// ------------------------------------------------------------------------------- // | |
public string function test() { | |
var value = "Original"; | |
(function() localmode = "classic" { // <=== We are overriding LOCALMODE. | |
// Since the entire Application is running in localmode "modern", in order | |
// for this assignment to affect the local variable of the parent context, | |
// we have to override the LocalMode, setting it back to "classic". This | |
// will allow Lucee to apply the assignment to the "expected" variable. | |
value = "Changed"; | |
})(); | |
return( value ); | |
} | |
</cfscript> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfscript> | |
echo( "[C] Value: " & test() ); | |
// ------------------------------------------------------------------------------- // | |
// ------------------------------------------------------------------------------- // | |
public string function test() { | |
var value = "Original"; | |
// Create an "alias" for the Local scope of the current function. | |
var context = local; | |
(() => { | |
// By using the "alias" of the parent function to define the variable | |
// assignment, it allows us to "scope" the assignment. So, even though | |
// "context" is just a reference to the parent function's Local scope, it's | |
// enough to bypass "modern" mode. | |
context.value = "Changed"; | |
})(); | |
return( value ); | |
} | |
</cfscript> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment