Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created August 13, 2019 11:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bennadel/a82cc558c7c09082f2f3e84b41d604d2 to your computer and use it in GitHub Desktop.
Save bennadel/a82cc558c7c09082f2f3e84b41d604d2 to your computer and use it in GitHub Desktop.
Unexpected Variable Assignment Using Function LocalMode Modern With Nested Closures In Lucee 5.3.2.77
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";
}
<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>
<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>
<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