This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to do a cfdump inside a cfscript tag?
I'm new to Coldfusion and wondered if anyone knew of a way to access function when inside a script block. I cant find way of calling it from there.
Why have Adobe removed it? Or have they just called it something else now?
Sorry - I know this is probably really basic question, but like I said I'm new.
The script equivalent of cfdump is writeDump().
The same pattern has been used for cfoutput and cflog, with writeOutput() and writeLog() functions.
writeDump()
Apparently in ColdFusion 9 it has been added as writeDump() so you should be able to use this from a cfscript block.
So if you have CF9, then you are fine.
If you using an older legacy system which does not support this newly introduced writeDump() function, as we are, you could write a wrapper for it and put it somewhere accessible to all your files.
This is the wrapper I have written, which for short term debugging use can be put on the cfc file you are working on (although remove it before you commit your code - otherwise it's just a mess), or you can put it somewhere global so you can call it from shared scopes.
Here is an example of a wrapper function you can use:
<cffunction name="dump" access="private" returntype="void" hint="dump wrapper">
<cfargument name="stuffToDump" type="any" required="true" hint="what you want to dump">
<cfargument name="abort" type="any" default="false" hint="abort after dump">
<cfargument name="expand" type="any" default="false" hint="expand output">
<cfdump var="#arguments.stuffToDump#" expand="#arguments.expand#">
<cfif #arguments.abort# EQ 1>
<cfabort>
</cfif>
</cffunction>
There are probably better ways around this problem, but this is what I currently use.
You can put it (temporarily) on the cfc file that you are currently working on, but obviously don't commit this to your code base as you don't want the dump function on all your files.
Or you could put it permanently onto a cfinclude file, and just include that (again - temporarily) to files you are debugging.
Another alternative I guess is to put it onto the Application.cfc. This file has a number of standard methods but you can also define your own additional methods to be included into it. Then you have your dump() function available in the APPLICATION scope.
There's a good info page on the Application.cfc file here. http://www.bennadel.com/blog/726-ColdFusion-Application-cfc-Tutorial-And-Application-cfc-Reference.htm
I have even seen it used in the Server scope, but this should never be done on production code. OK for debugging I guess as a last resort, just make sure you remember to remove it.
Personally I think both these options are probably far from ideal, and it's a great shame it took Adobe so long to provide a script alternative to the function. Would have saved a lot of pain.
But hopefully if you are using CF9 then all this will be irrelevent to you and you can just use the new writedump() function now they have finally added it in.
To be a little clearer and provide an example:
<cfscript>
SomeString = 'ABC';
writeDump(SomeString);
</cfscript>
Peter's answer is 100% correct.
Related
Ok, I have template files which I know will require to be between <cfoutput> tags, however placing a <cfoutput> tag around a <cfinclude> won't work, and anything with a <cfmodule> won't work as that doesn't allow me to manipulate the variables scope.
So, any ideas - no matter how complex - which would allow me to include such a template file and have it act as if it's between <cfoutput> tags?
Bit of context: It's for a 'framework' I am working on and requiring every template file to start and end with a <cfoutput> tag seems a real waste, especially because the less 'coldfusiony' the template files look, the better IMO.
I was going to suggest the render() option, with the caveat it's a bloody awful bit of functionality in OpenBDML (or whatever they want to call their version of CFML), and I think should be avoided. I can't see how it doesn't cause the CFML to be recompiled every request, which is a helluva overhead. I think you're better off modifying the mark-up when it gets saved/read to wrap/unwrap it in <cfoutput> tags, that way the resultant CFML will only be recompiled when the file actually changes. Which will be really a lot less often than it's read.
Prompted by your question, I did a bit of a write up on the CFML compile process, showing why having the <cfoutput> tags in a separate file doesn't work. Apologies it took so long to write & follow-up with here.
What we do in wheels is just wrap the cfinclude with a cfsavecontent tag
<cffunction name="renderInclude">
<cfargument name="template" value="string" required="true">
<cfset var myOutput = "">
<cfsavecontent variable="myOutput"><cfoutput><cfinclude template="#arguments.template#"></cfoutput></cfsavecontent>
<cfreturn trim(myOutput)>
</cffunction>
Found an OpenBD specific way to solve this problem. Apparently I wasn't the only one who encountered this problem and OpenBD contains a useful render() which takes care of evaluating cfml content. So I ended up with
<cfset cfml = fileRead(expandPath(...))>
...
<cfoutput>#render("<cfoutput>"&cfml&"</cfoutput>")#</cfoutput>
It's not a beautiful solution, as I destroy the per page compilation the engine would otherwise do, however as the cfml is relatively simple on these pages I assume this not to be too much of an issue. At least it should be less of a performance hit than actually writing the file to disk.
Here's a weird one. I haven't had any luck finding any information about this on Google, so I'm wondering if any of you have seen this before?
I've got a CFC in the request scope and then in the onRequestEnd event I grab that CFC out of the request scope and do some end-of-request stuff with it. The problem is I can't reference the variable in my onRequestEnd event because it produces an error that says it's not defined in the scope... but here's where it gets really weird and why I KNOW this is a bug (it's not just a suspicion)... If I DUMP the variable, the cfdump tag successfully displays the CFC and all its stuff... and then produces the same "is undefined in scope" error. Here's a screen-capture.
So... anybody seen this before? 'Cause I'm totally stumped. I've already installed the 9.0.1 updater and both of the cumulative hot fixes.
p.s. Yeah, I know it says OnRequestEnd.cfm, but this is actually inside the Application.cfc onRequestEnd method -- it's a legacy from the framework dating back originally to CF5, just go with it. ;P
EDIT: Okay, it's gotten weirder... I tried using evaluate() to set it to a local variable, which apparently works, because then I dump the local variable. The dump still works, even though it's on line 2 AFTER the line on which the error occurred?!!
EDIT 2: EDIT: Here's the code from the Application.cfc that includes the file where the error occurs:
<cffunction name="onRequestEnd" access="public" output="true">
<cfinclude template="OnRequestEnd.cfm">
</cffunction>
It appears to have something to do with the combination of the method and the include file.
It still fails if I execute the method in the onRequestStart like this:
<cffunction name="onRequestStart" access="public" output="true">
<cfset onRequestEnd() />
</cffunction>
But it works fine if I include the file in onRequestStart like this.
<cffunction name="onRequestStart" access="public" output="true">
<cfinclude template="OnRequestEnd.cfm">
</cffunction>
HOWEVER! There's obviously more to this because I can't create a simple test case. If I create a new project with a very simple application.cfc in it and replicate all these details, it works fine. So there's something else in the framework that's contributing to it beyond just the method names and file names.
And the file name doesn't seem to actually contribute, since it still fails in the same way if I change the name of the file like this:
<cffunction name="onRequestEnd" access="public" output="true">
<cfinclude template="reqend.cfm">
</cffunction>
EDIT 3: Okay it has nothing to do with the file... well it does, but not with the file name... At the bottom of the onRequestEnd.cfm is this code
<!--- this seems to help resolve a leaky-memory issue in CF/JRun --->
<cfset structClear(variables) />
<cfset structClear(request) />
<cfabort />
If I comment out those StructClear statements, then the error goes away, which told me that it was executing the OnRequestEnd.cfm twice... and I THINK that means that CF9 changed the behavior of the CFABORT tag and it now executes the onRequestEnd event when the tag is used... it didn't in previous versions of cf...
I didn't find documentation of this, but I did find this blog from Ben Nadel about this behavior with the CFLOCATION tag, so it seems to be more generally about the onRequestEnd event. It seems now in CF9, no matter how a page finishes executing, the onRequestEnd event is executed at the end... That's a change from all the previous versions and so it mucks with code I had created in order to actually cause this to happen on previous versions. Since I was causing execution of the onRequestEnd and then aborting the page early, CF now executes the onRequestEnd, aborts and then executes the onRequestEnd again because of the abort.
Luckily, this fairly simple bit of code at the top of the template seems to fix the problem:
<cfif structIsEmpty(request)>
<cfexit method="exittemplate" />
</cfif>
I decided to leave this question here (rather than deleting it) since it may help some other folks, though I found the source of the problem and a workaround while working with some of the comments and it wasn't what we thought. Ben Nadel also posted a blog about the change to CFABORT a while ago as well... and Adam Cameron tells me that although this change was added by-design in CF9 (without warning anyone apparently, since I saw no mention in the LiveDocs and added 2 comments about it), it was then removed in the (not yet released?) CF10. I think Adam might be in the beta, I'm not sure.
I have been tasked with researching the possibility of storing .cfm files outside of the web root as a further security measure. (I'm not talking about CFCs, but the files that will appear in the URL string.)
I figured that I could use the properties of OnRequest() in the Application.cfc to do this, but no luck.
I've tried this:
<cffunction name="OnRequest" access="public" returntype="void" output="true">
<cfargument name="TargetPage" type="string" required="true"/>
<cfinclude template="C:/test#arguments.TargetPage#"/>
<cfreturn/>
</cffunction>
I then put a test.cfm inside C:\test and attempted http://localhost/test.cfm. That gives me a "file not found" error.
So then I created a ColdFusion mapping to C:\test called "test" and changed my CFINCLUDE thusly:
<cfinclude template="/test#arguments.TargetPage#"/>
Unfortunately I got the same error.
So, is what I'm after even possible? (Windows Server 2008 and IIS in case it matters. ColdFusion 9.)
I know that I could put a CFINCLUDE in my index.cfm and pass around URLs like http://www.example.com/?file=test.cfm, but I'd prefer not to do that.
Well here's something: If I put an empty test.cfm in my web root then this works. Obviously I'd really rather not put empty stubs for every one of my files (which, for this project, will end up being in the hundreds).
Rather than spinning your wheels down this path, let me point you in a possible better direction which may solve the original issue, but from a more preferred/best practices standpoint:
ColdFusion Sourceless Deployment
Rather than trying to jimmy-rig the site to read files outside of root, you simply never put the source code out into the world.
I think you would have better luck using onMissingTemplate rather than onRequest. http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d2a.html
I have been asked to update an old project. When i went into the cfc file it had over 3000 lines of code and over 100 cffunctions. I was wondering if i could split the cfc into multiple files whose cffunctions are logically grouped without having to change the code in any other pages.
Run into a similar problem. I created the new cfcs and modified the original functions to call functions within the new cfcs.
For e.g
<cffunction name="GetStuff" access="remote" returntype="Struct">
<cfreturn createObject("component","myNewCFC").GetStuff(argumentCollection=arguments)/>
</cffunction>
Refactor, Refactor, refactor...
simplest way might be using cfinclude to inject functions (mixin's)
Question implies there's enough client code using this object that changing the calls elsewhere if the object's broken apart apart is burdensome. In this case treat the existing object as a Facade - that is an object that provides unified interface to an underlying class hierarchy.
The way to approach producing the hierarchy is identifying those functions that should go together. Whenever I come across this problem the functions usually do not share any state, rather they are like static java methods, but if there are functions that share state they are a good candidate for this grouping. Otherwise it's usually functions that share the same input parameters or tend to have the same verbiage in their name (i.e. saveMyData, loadMyData, etc...).
Given that example, copy these functions into a new CFC (e.g. MyData) - at this point you may change the function names to eliminate repetition or improve their clarity (e.g. MyData.load()). Back in the original object (i.e. BigCFC) remove these functions' implementation and instead delegate the call to the newly created CFC (you may consider making the new CFC part of the old's composition). So it would look something like this:
<cffunction name="loadMyData">
<cfargument name="id" type="numeric"/>
<cfreturn variables.myData.load(arguments.id)/>
</cffunction>
Where variables.myData would be setup as part of the CFC's initialization.
Taking this approach means your existing client code is unaffected by the change, but still breaks apart everything into logic groupings, and positions new code to use the more granular CFCs.
It's an old question and I just came across it randomly, but I thought I'd chime in here as it's something I've had to deal with on many occasions.
If the goal is simply to organise things better from a code management perspective (rather than say, to specifcially reduce the amount of methods in each CFC) then I'd advocate breaking the CFC down into multiple CFM pages and including them in the CFC. From a code management perspective, you can group several functions into a well named CFM file and it all becomes a lot easier to deal with. The calling code remains the same, as all the functions are still being instantiated in the CFC as before.
I have a bit of code I use in my init methods that automatically includes all the CFM files it finds in the same folder, and I house a single base.cfc in each folder along with the grouped functions.
e.g.
<cfscript>
// Set CFC name
Variables.sCFCName = 'appUtils';
// Set folder
Variables.sCFCFolder = GetDirectoryFromPath(GetCurrentTemplatePath());
// Get CFC files
Variables.qCFCFiles = directoryList(Variables.sCFCFolder, true, 'query');
</cfscript>
<!--- Init function --->
<cffunction name="init" access="public" returnType="any" output="false" hint="Constructor">
<cfargument name="DSN" type="string" default="" hint="Datasource" />
<!--- Set DSN --->
<cfset Variables.DSN = Arguments.DSN />
<cfreturn this />
</cffunction>
<!--- Include CFC files --->
<cfoutput query="Variables.qCFCFiles">
<cfif Variables.qCFCFiles.type EQ 'file' AND GetToken(Variables.qCFCFiles.name, 2, '.') EQ 'cfm'>
<cfinclude template="#Variables.qCFCFiles.Name#" />
</cfif>
</cfoutput>
I am working on redoing our company's code, and I want to have a clear, easy to read, and reasonably secure application.cfm.
And no, we are not using application.cfc. So let's not discuss that please.
Just want to know what scripts you would add for security.
I am using coldfusion 8 standard, sql 2008.
Here is one of the scripts I am currently using, but I want to hear from some other coldfusion programmers.
<cfset temp = cleanScopes('form,url') />
<!--- another method to clean url/form data from http://www.garyrgilbert.com/tools/coldfusion/cleanScopes.cfm.txt --->
<cffunction name="cleanScopes" access="public" returntype="void">
<cfargument name="scopesToClean" type="string" required="yes">
<cfargument name="charlist" type="string" required="no" default="">
<cfscript>
reTags ="<[^/>]*>|</.*>";
</cfscript>
<cfloop list="#scopestoClean#" index="scopeName">
<cfif not findnocase("multipart/form-data",cgi.CONTENT_TYPE)>
<cfscript>
s=Evaluate(scopeName);
for(field in s)
if (isSimpleValue(s[field])){
if(reTags neq '')
do { prev=s[field];
s[field]=REReplaceNoCase(s[field],reTags,"","ALL");
} while (prev NEQ s[field]);
structUpdate(s,field,prev);
if (charlist neq '')
s[field] = replacelist(s[field],charlist,'');
}
</cfscript>
</cfif>
</cfloop>
<cfreturn>
</cffunction>
Thank you for your time.
I would advise against attempting to catch everything in a global fashion. There will inevitably be a few things that slip through the cracks, no matter how complex and convoluted your global protection code gets.
Instead, the "correct" (for what it's worth) method is to sanitize all content being presented on a page (or in an email, etc) -- during output -- that began its life as user input.
That said, take a look at OWASP. They have excellent libraries for protecting from all kinds of attacks, including the various ones you mention (sqli, xss, crlf). A coworker of mine recently wrapped up some of those libraries into a CFC that we can use in our applications, and explained how to use it on our developers blog:
AntiSamy
If your application accepts user generated HTML, say blog comments for example, you need to make sure you sanitize your input to prevent XSS attacks. You wouldn’t want someone to be able to enter malicious code in your blog comments so you need some way to filter the input. Enter AntiSamy. AntiSamy allows you to easily filter user generated HTML according to what it terms policies. AntiSamy is a Java project, so I have packaged it into a CFC for easy use from ColdFusion.
The simplist way to use AntiSamy is to create an instance of the AntiSamy component (cfc.owasp.AntiSamy) and call the getCleanHTML() method on the input.
<cfset antisamy = CreateObject("component","cfc.owasp.antisamy") />
<cfset cleanHTML = antisamy.scan(form.someInput) />
This will run AntiSamy with the default (fairly permissive) policy file and return the clean HTML markup.
ESAPI Encoder
The next library I’ve brought over from the OWASP project is the ESAPI Encoder. Again this is a Java project which I have wrapped in a CFC for easier use. The encoder provides several methods for encoding beyond those included with ColdFusion. Some of the more useful methods include encodeForJavaScript(), encodeForHTMLAttribute(), and encodeForCSS(). Using the component is pretty straight forward, just instantiate it and call the appropriate method.
<cfset encoder = CreateObject("component","cfc.owasp.Encoder") />
<cfset html = encoder.encodeForHTML("<body onload=""alert('XSS')"">Test</body>") />
One very useful method this library provides is the canonicalize method. The documentation from the beta version of the ESAPI Encoder gives a good description of what this method does.
However, if you insist on a global solution, why reinvent the wheel? Why not try out something like FuseGuard. The price is probably less than the cost of the development-hours that would be spent cobbling together, debugging, and dealing with security problems that break through your home-grown system.
Personally, I'm not really sure this "global" approach is the best. I check all incoming data in all models that accept external data, with specific validation rules for each situation. So additional layer looks overkill.
Such scripts wont protect you from putting string into the numeric id passed into the URL -- you have to check it any way. You have to use HTMLEditFormat/XMLFormat in the views any way, and so on.
P.S. List loop for CFScript:
for (i=1; i LTE ListLen(scopestoClean); i++) {
scopeName = ListGetAt(scopestoClean,i);
//... following code
}