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

Application.cfc searchImplicitScopes Setting Ignored

Enthusiast ,
Jul 12, 2024 Jul 12, 2024

Copy link to clipboard

Copied

I've recently upgraded a server to CF2023, which has many legacy apps that currently rely on implicit variable scoping. I've temporarily added the Dcoldfusion.searchimplicitscopes=true Java flag for the server, and was hoping to work through the individual apps and test them by overriding that in application.cfc with this.searchImplicitScopes = false.


The application property does not appear to be working though. With this.searchImplicitScopes set to false, it's still searching scopes for undefined variables. If I add a new .cfm to the app, with only:
 
<cfoutput>#testvar#</cfoutput>
 
I get an undefined variable error as expected, unless I append ?testvar=whatever to the URL, then it pulls it from URL.
 
Similarly, an empty page with just <cfoutput>#script_name#</cfoutput> finds the value from cgi.script_name.
 
Does the application property not override the server Java flag? If I cfdump  <cfdump var="#this#"> from the same empty test file, it shows searchImplicitScopes = false.
TOPICS
Security

Views

536

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

correct answers 1 Correct answer

Enthusiast , Jul 15, 2024 Jul 15, 2024

Thanks, Charlie, for the detailed response. In my case, this.searchImplicitScopes was being set in the right place before the functions, but your link to the getApplicationMetadata() function got me to the answer. The function result was an empty struct because this.applicationTimeout was set to 0, forcing the application to update for debug/testing (but apparently also clearing any settings before they could take effect). After setting a non-zero value for applicationTimeout, the searchImplicit

...

Votes

Translate

Translate
Community Expert ,
Jul 13, 2024 Jul 13, 2024

Copy link to clipboard

Copied

I Start with a minor point. There is a typing error in the flag you wrote, "Dcoldfusion.searchimplicitscopes=true". It should start with a minus sign, thus

 

-Dcoldfusion.searchimplicitscopes=true

 

Not that that is relevant to your question. As ColdFusion would not even have started without the minus sign.

 

To answer your question, yes, the searchImplicitScopes setting in Application.cfc overrides the one in jvm.config. The following test will show that:

 

  1.  Create a CFM page containing the following code:
    <cfset url.Testvar=1>
    
    <cfoutput>
    TestVar: #TestVar# <br>
    Script_Name: #script_name# 	
    </cfoutput>
  2.  Create a minimal Application.cfc file in the same directory as the CFM page;
  3.  Include the flag -Dcoldfusion.searchimplicitscopes=true in java.args in jvm.config (the server-wide setting); 
  4.  Launch the CFM file.
         When this runs, ColdFusion will implicitly search though the scopes.
         The result will therefore be:
         
    TestVar: 1
    Script_Name: /path/to/the/cfm/file
  5.   Add the setting this.searchImplicitScopes=false; to Application.cfc.
         The question now is whether this will override the server-wide setting;

6.  Relaunch the CFM file;

     You will get the error message "Variable TESTVAR is undefined.".
     This confirms that the Application.cfc setting has overriden the server-wide setting.

 

 

Votes

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
Community Expert ,
Jul 13, 2024 Jul 13, 2024

Copy link to clipboard

Copied

Nate, you ABSOLUTELY can override the jvm arg at the app level. I've confirmed it. But I have a guess at why your attempt to override it in your application.cfc is not working. At least this could happen to others.

 

Are you putting the this.searchimplicscopes=false inside your onapplicationstart, or perhaps onrequest or onrequeststart? If so, that's the problem. Instead, put the setting OUTSIDE those methods, which as some may know has been referred to traditionally in CFML as the "pseudo-constructor" of a CFC.

 

You can prove this yourself by dumping the getApplicationMetadata() function, which shows what is or is NOT set for such settings as can be set at the application level (and so yes, this issue applies to ANY such application settings).

 

You can even see this indicated in the docs talking about using application.cfc, though they don't make a point of stressing it. They just show DOING it. As for the docs on the various application settings you can set, those do at least say at the top, "You set the values of these variables in the CFC initialization code, before you define the CFC methods."

 

Sadly, neither of those doc pages propose the idea of using getApplicationMetadata(), which is the best way to confirm where things stand regarding such settings. And I'll note that if instead one were to dump the THIS scope, you WILL see the change you'd made via the "this." scope even within those methods. But the problem is that that is NOT going to matter, if you don't see it reflected in the dump of getApplicationMetadata().

 

FWIW, you would not be the first to experience that "changing settings in application.cfc is not working". Of course, those who use application.cfm don't experience this, as they just set the settings on cfapplication instead, which is a more straightforward runtime directive.

 

Here also is some code you can use to "play with" things:

 

component {
    // this code demonstrates how to correctly and incorrectly) set application-level settings like searchimplicitscopes in application.cfc
    // it presumes that the default setting in CF is set to true, and that one wants to set it false for this given app (as discussed in this forum thread)

    // to test some changes, you'll want to re-initalize the app. 
    // while you could call applicationstop(), you could also just change the value of this.name to create a "new" app

    this.name="test";
    // this line sets the setting correctly, as it's outside any method 
    this.searchimplicitscopes=false;

    writedump(var=this,label="this, in pseudo-constructor")
    writedump(var=getApplicationMetadata(),label="getappmetadata, in pseudo-constructor");

    function onapplicationstart() {
        // this line will NOT set the setting to true, because it's inside onapplicationstart
        this.searchimplicitscopes=true;
        writedump(var=getApplicationMetadata(),label="getappmetadata, in onapplicationstart");
        writedump(var=this,label="this, in onapplicationstart");
    }

    function onrequeststart() {
        // this line will also NOT change the setting. Note you can even set it to an incorrect value without any error, 
        // which would fail if done on the correct line above (with 'cannot convert the value "xx" to a boolean')
        this.searchimplicitscopes="xyz";
        writedump(var=getApplicationMetadata(),label="getappmetadata, in onrequeststart");
        writedump(var=this,label="this, in onrequeststart");
    }

}

 

You can also add a dump of the scope in a cfm page (such as even a a new test.cfm you may create) in the folder controlled by this application.cfc:

 

<cfdump var="#getapplicationmetadata()#" label="getappmetadata, in #cgi.script_name#">

 

Finally, if you may want some code to detect and show if the new JVM arg for searchimplicistscopes is set, this will do it:

// code to detect and show if JVM arg for coldfusion.searchimplicitscopes is set
writeoutput("jvm arg -Dcoldfusion.searchimplicitscopes ");
if (structkeyexists(server.system.properties,"coldfusion.searchimplicitscopes")) {
    writeoutput("set to " & server.system.properties["coldfusion.searchimplicitscopes"] & "<br>");
} else {
    writeoutput("is not set <br>");
}

I've been meaning to do a blog post on this matter (of how one might mistakenly set the setting), and in answering you here it has helped me gather the thoughts. I'l look forward to hearing what you or others may say, in case there's anything I'm missing.


/Charlie (troubleshooter, carehart.org)

Votes

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
Enthusiast ,
Jul 15, 2024 Jul 15, 2024

Copy link to clipboard

Copied

Thanks, Charlie, for the detailed response. In my case, this.searchImplicitScopes was being set in the right place before the functions, but your link to the getApplicationMetadata() function got me to the answer. The function result was an empty struct because this.applicationTimeout was set to 0, forcing the application to update for debug/testing (but apparently also clearing any settings before they could take effect). After setting a non-zero value for applicationTimeout, the searchImplicitScopes setting worked as expected.

Votes

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
Community Expert ,
Jul 15, 2024 Jul 15, 2024

Copy link to clipboard

Copied

Wow, there you go and glad that helped. That's why I LOVE showing ways to DIAGNOSE problems, while often we try to guess at causes/solutions.

 

And TBH I don't think I've ever heard of one setting the app timeout to zero, but it just goes to show that the strangest things can happen and explain a knotty problem. 🙂

 

And perhaps the rest of what I shared will yet help someone else, now or in the future, in their finding some setting "fails to take effect".

 

I'll mark your reply as the "answer" for this thread. (Though you could have done it yourself, you might not have thought of it). 


/Charlie (troubleshooter, carehart.org)

Votes

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
Community Expert ,
Jul 16, 2024 Jul 16, 2024

Copy link to clipboard

Copied

LATEST

@NateBaldwin , thanks for sharing that. I am surprised that you could successfully launch a CFM with applicationTimeout set to 0. I expected ColdFusion to then give an exception.

 

So I did a test. As a result, I discovered an inconsistency in ColdFusion. It is this inconsistency that resulted in the issue that you observed.

 

The steps of the test:

  1.  Create a test file, testPage.cfm, containing the code <cfoutput>#now()#</cfoutput>.
  2.  Within the same directory, create a basic Application.cfc file, such as the one below.
  3.   In the Application.cfc file, apply the setting: this.applicationTimeout = "#createTimeSpan(0,0,0,30)#".
          (I chose 30 seconds arbitrarily. Any non-zero time value will do.)
  4.   Launch the CFM page, and confirm that it produces the current date-time, as expected.
  5.   Change the applicationTimeout setting to: this.applicationTimeout = "0".
  6.   Launch the CFM page. Confirm that, as before, it produces the current date-time.
  7.   With applicationTimeout still set to 0, restart ColdFusion.
  8.   Launch the CFM page. Confirm that ColdFusion now gives an error.

    The error is 'java.lang.NullPointerException: Cannot invoke "coldfusion.runtime.ApplicationSettings.getSessionCookieSamesite()" because the return value of "coldfusion.filter.FusionContext.getApplicationSettings()" is null. '

    This suggests that, in step (6), there were application settings still in force, that were remnants of the previous application state (when applicationtimeout was 30s).

    <!--- Applicstion.cfc used. The explicit presence of cookie settings might be relevant to the bug. --->
    
    <cfcomponent>
    
        <cfscript>
            this.name = "MyTestApp";
            this.applicationTimeout = "#createTimespan(0,0,0,0)#";
            this.loginStorage = "session";
            this.sessionManagement = "true";
            this.sessionTimeout = "#createTimeSpan(0,0,20,0)#";
            this.setClientCookies = "true";
            this.setDomainCookies = "false";
            this.scriptProtect = "all";
     	    this.enableNullSupport = false;	  		
        </cfscript>
    
        
    	<cffunction name="onApplicationStart" returntype="boolean">
    		
    	    <cfreturn true>
    	 </cffunction>
    
    	<cffunction name="onRequestStart" returntype="boolean">
    	 	<cfargument name = "targetPage" type="String" required="true"> 	
    
         	<cfreturn true>
    	</cffunction>
    
    </cfcomponent>​


    Bug reference: https://tracker.adobe.com/#/view/CF-4222886 

Votes

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
Resources
Documentation