FarCry 7.2.12/p740: Handling of ExpandPath() exceptions missing

#1

According to the CF documentation, the ExpandPath() function is unreliable when it comes to extending a relative path. The function returns the first path which matches the provided relative path.

In a Shared Hosting environment, this may lead to the situation that the absolute path returned does not belong to your web space/sandbox. Since further access to the retrieved path is denied, the coapi CFC will throw an exception which will be masked by an HTTP 500 server error.

If the ExpandPath() function will not be able to resolve the relative path, it throws an exception (which, again, will be masked with an HTTP 500 server error).

Thus, I think that each ExpandPath() function call should be equipped with cftry/cfcatch tags. I did this in the coapiadmin.cfc file for the methods getWebskinPath() and initializeIncludes(), see teh example below:

		<cfelseif structKeyExists(application, "plugins") and listLen(application.plugins)>
			<cfloop list="#application.plugins#" index="plugin">					
				<!--- 2017.10.13/proc -- function ExpandPath() throws an error if the relative 
										 or absolute path do not exist --->
				<cftry>
					<cfif fileExists(ExpandPath("/farcry/plugins/#plugin#/webskin/#arguments.typename#/#arguments.template#.cfm"))>					
						<cfset webskinPath = "/farcry/plugins/#plugin#/webskin/#arguments.typename#/#arguments.template#.cfm" />
					</cfif>	

					<!--- catch any errors here --->
					<cfcatch type="any">
						<!--- nothing to do: continue with script processing --->
					</cfcatch>
				</cftry>
			</cfloop>				
		</cfif>

The same applies to the method getDBTypes() in the lib/db.cfc file for both setting the local variable locations and the application.plugins loop.

And since the tags/farcry/_InitApplication.cfm script hasn’t been cleaned up yet, it surely won’t hurt to catch any exceptions in the — albeit depreciated — Apps.cfm processing (around line 260).

The overall question, however, remains as what shall be done in case of an exception: Do we want the results to be written to any logs (and if so, which ones)? Or do we prefer to send an email to the administrator, providing him with the cfcatch information? In any case, the solution needs to work also on remote production systems.

#2

Could you point me to the docs that say that expandPath() is unreliable with relative paths / shared hosting?

Is the problem that /farcry might be mapped for another sandbox and gets incorrectly matched during a call to expandPath? It would seem like a straight up Adobe ColdFusion bug to me if that’s the case. An empty catch probably wouldn’t help with working around the problem if we need to use the correct result from the call to expandPath?

#3

The description for Adobe ColdFusion‘s ExpandPath() function can be found here: https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-e-g/expandpath.html

The issue may — at least to some extent — result from (a) a bug ob Adobe‘s site, (b) some misconfiguration at the provider‘s end, or © even be platform-specific (depending on the underlying Java versions).

Any cfcatch would need to clearly point out the reason of the exception (because only then you will be able to do something about it). Whatever we decide to do, only returning an HTTP 500 server error will not help you to find the actual cause. (Last time, it took me almost a week to investigate the issue and finally get around it.)

#4

The docs say;

History

ColdFusion MX: Changed behavior for the relative_path parameter: this function can now accept an absolute or relative path in the relative_path parameter. To resolve a path, this function uses virtual mappings that are defined in the ColdFusion Administrator. This function does not reliably use virtual mappings that are defined in IIS, Apache, or other web servers.

The note is related to ColdFusion MX (i.e. CF6). Back in the CF6 days this would have been using JRun and the JRun Connector, and that changed with ColdFusion 10 which switched to Tomcat and a different Tomcat connector. That said I have never seen expandPath fail to work in this regard since CF7 (which was still on JRun), and expandPath is called all over the place without issue for as long as I can remember…

Can you be more specific about your problem again? Are you on a shared host where there is a global /farcry mapping that is pointing to someone else’s webroot and it’s causing errors in your application? If so, that would seem like a configuration issue that your hosting provider might need to solve, I’m not sure there’s any code change we can make to work around that?

#5

English is not my mother tongue, but to me the description is ambiguous and does not clearly state that the issues has been resolved. Anyway, there is a discussion on StackOverflow which refers to CF11 and may contain a workaround. Perhaps omitting the trailing “/” (as also discussed in the article) will help to resolve the issue.

What I experienced (back then on CF11) is that the ExpandPath() function expanded the given path to an absolute path referring to another sandbox on the same server. Or, when the /farcry/plugins/#plugin# directory did not exist, the ExpandPath() function threw an exception.

I would like to see the FarCry CMS to be that stable that errors like these are caught appropriately. We (as developers) should receive detailed information of what went wrong where, no matter if we run the software in-house, at a customer site or at a provider in a Shared Hosting environment without the need to investigate issues like those for days. I also found that the environment matters. There are subtle differences in the CF behavior between macOS and Windows.

Since I didn’t use the plugins directories, I came away with the <cftry> <cfcatch> sequence. However, I would prefer that the FarCry CMS throws an exception which I may work on. Keeping the <cfcatch> information and redirecting it up to the Application.cfc's OnError() method seems to be a viable solution to me.

If you will be able to point me to an example of how you folks caught exceptions and processed them via the OnError() method, I might give it a try in the days to come.

Just for the records: Back in the ol’ FarCry 4.X times, I ran an installation on a Shared Host where I had to rename the /farcry directory/mapping with something else. It’s a bit of a hassle but doable.

#6

The p740 branch is “beta” and the issues you’ve found are with Adobe ColdFusion incompatibility with Lucee. It’s not a stable branch and it hadn’t been previously tested on ACF until you raised these issues :slight_smile: That said, I think we’ve resolved these issues now.

As I mentioned in the other thread I’m still not clear on how/why expandPath is failing for you, I’ve not seen this happen in 13+ years of using ACF. If a server is misconfigured then I think the configuration problem needs to be fixed, but if it’s something that I can work around without creating other problems or a performance hit then I’m happy to do it!

#7

That’s how Core’s friendly error pages work; any exception that is not caught will be processed by Application.cfc’s onError method and the friendly 500 error page will be shows and the details are logged to the exception.log as normal.

The other errors you were getting before were happning in the pseudo-constructor before the application had initialised, and because of that it was too early for the friendly error page to be shown. I made another tweak last week in p740 branch that might allow the friendly error page to work (the utils lib had not been initialised which is why an additional error was being thrown).