I'm testing some ideas. I'm not sure if I'm on the right path or not, but thought I'd share.
I have some UDF & CFC libraries that we've built over the year and I have some checks to determine whether default application variables exist and use them to override default values. In order to avoid possible "Scope Injection" & errors (when scopes don't exist), I thought I'd attempt to write a function that uses "safe navigation" to verify scope classname, verify key (in the struct keylist) and return the value (w/optional fallback).
I've included a simple example where application.randomVarName_xxx
is injected into the URL
& FORM
scopes on a script that doesn't use an application CFC or CFM file. As a result, dumping the application value actually returns url.application.randomVarName_xxx
instead of a non-existent application-scoped value.
Another example is the retrieval of a server variable with a default value (if it doesn't exist).
Here's a little bit of my post-CFSummit2022 discussion of this on Twitter. https://twitter.com/gamesover/status/1578154242031767553
- Yeah... I tend to use structKeyExists (or struct.keyExists("keyname")) when the key names are dynamic/random... but yeah, isdefined does reach out to all other scopes if it can't find it. Too bad there's no option to limit searching to within a specific scope. - Me
- Short term that would be an easy UDF to write and share on GitHub. Longer term that would be a nice upgrade to IsDefined() they could implement ala updates to StructNew() - Nolan
Here's the source code proof-of-concept. Let me know your thoughts.
NOTE: I'd provide a direct link to TryCF.com, but I noticed that gists are permanently cached and never refresh. If you want to test it there, please copy-and-paste the code.
https://gist.github.com/JamoCA/7e544f1488a703d868cecc2b7ae5c2ed
Top comments (2)
So, just looking for clarity, does this only matter if the variable in question does not exist? Meaning, is the
url
scoped checked forapplication.foo
only ifapplication.foo
doesn't exist? Or does it have to do with scope precedence?Oh, actually I see in the article from Pete that you mentioned, that it only does this if the variable doesn't exist.
Even if the variable does exist, what if it's not from the exact scope that you are expecting it to be from? I've seen some lazy CFML and have helped some developers that weren't aware of what was happening since they tended to reuse the same variable names within multiple scopes. I've now found that it's best to "be explicit" and "trust, but verify". (I credit my "dotNet blood brother" for the "trust, but verify" mantra as he works in a var-typed environment and is constantly encountering issues like this from other developers that he manages.)