Skip to main content
February 29, 2008
Question

Uploaded filename, before CFFile

  • February 29, 2008
  • 13 replies
  • 7604 views
Hi,

I'm doing some form data validation and would like to add rules for files (size and type). Ideally I want to avoid CFFile as the validation shouldn't have anything to do with moving the file anywhere.

I know that when ColdFusion processes an upload, it stores it in a temporary directory and filename. This is stored in the form field (e.g. form.file = c:\sometempdirectory\blahxxx.tmp) and I can use that to do a GetFileInfo and find out the filesize. Awesome.... except it's called blahxxx.tmp :(

I want to know the real filename, not the temp filename but I can't find it anywhere. ColdFusion must know it, probably hidden along with its other darkest secrets, as it'll use it when we do a CFFile action="upload". So where is it being hidden? Any ideas?

I have seen suggestions of using an extra hidden field plus some javascript, but to be honest, I don't like trusting something like that as it's possible to abuse it. I've also gone hunting inside "getPageContext().getRequest()" but not being any good with Java I haven't a clue where to start.

Please help :)
Ta,
Dave

13 replies

Dani Szwarc
Inspiring
January 14, 2019

Hello Dave, have you been able to finally find the answer to this?

If someone still needs to get the filename of the uploaded file, please check this out:

Stillnet Studios » Blog Archive » Getting the client filename before using cffile

It works great.

March 11, 2008
> That is not where the confusion is. It is well-known that you can upload without using <cffile action="upload">.

I have had several replies here and elsewhere where people have thought CfFile action="upload" is responsible or they think I believe it is responsible. That's why I mentioned there appears to be some confusion, as I have kept having to explain what I wish to accomplish.

> What confuses me is why you don't just use <cffile action="upload" destination="#absolutePathToDirectoryYouSpecify#">

I have built a Validation CFC which is provided a set of multiple rules per form field. I already have it validating the file size (GetFileInfo(form.file)) but I didn't want the overhead of creating a copy of the upload (CfFile action="upload") and then removing it, just to find out it's file type. I also wanted the validation CFC to remain independent from any other code and portable between various applications, doing a CFFile action="upload" means I always have to remember that my validation cfc is copying the file somewhere.

Also, when I want to validation multiple file uploads, some possibly large files. There is the overhead of ColdFusion copying each one of these, just to find it's filename.

> Another point of confusion is that you use <cffile action="read">

The example code was based on some I was using for uploading, changing and then saving an RTF file. So I didn't want to open it as a binary, sorry if it appeared wrong.

BKBK
Community Expert
Community Expert
March 12, 2008
I didn't want the overhead of creating a copy of the upload (CfFile action="upload") and then removing it, just to find out it's file type.

There will always be the overhead of uploading the file to the server. I believe that that has more to do with HTML. It's the expected behaviour for <input type="File">. So, even without <cffile action="upload">, Coldfusion will upload the file to the temporary directory, giving it an arbitrary name like neotmp9381.tmp. That is default behaviour for Coldfusion.

A possible solution to your problem is to pass the client's file path, including file name, using cfinput's bind attribute. An example follows:

BKBK
Community Expert
Community Expert
March 10, 2008
Elpestybandito wrote:
Now for save.cfm, there seems to be some confusion that the upload doesn't happen until you do cffile action="upload".

That is not where the confusion is. It is well-known that you can upload without using <cffile action="upload">.

I can only speak for myself. What confuses me is why you don't just use <cffile action="upload" destination="#absolutePathToDirectoryYouSpecify#">. It will save the file by its real name, which is what you want, and in the directory you specify.

It might just be -- and I'm guessing -- that Coldfusion will only give you the real name when you use <cffile action="upload">. In any case, you will get more bang for your buck with the cffile structure than with GetFileInfo().

Another point of confusion is that you use <cffile action="read">, which applies mainly to text files. What do you do for images and executables, for example? Toggle between action="read" and action="readBinary"? Then what about MIME types? Permissions?

March 10, 2008
Thanks Azadi :)

That's exactly what I'm after, just can't find how to access it from ColdFusion. Like I've mention before, it must be there somewhere otherwise ColdFusion wouldn't be able to use the original filename at all.
BKBK
Community Expert
Community Expert
March 10, 2008
Elpestybandito wrote:
I know that when ColdFusion processes an upload, it stores it in a temporary directory and filename. This is stored in the form field (e.g. form.file = c:\sometempdirectory\blahxxx.tmp) and I can use that to do a GetFileInfo and find out the filesize. Awesome.... except it's called blahxxx.tmp :(

What you've described is not always the case. That is what happens if you don't specify a full path to a directory as the destination attribute, when you upload the file in the first place. (Or if you, for some bizarre reason, specify Coldfusion's system temp directory as the destination).

As an example, create the directory c:\my_uploaded_pics\. When you run the code below, Coldfusion will save the image, including its real name and extension, in your directory. Practically all the information you seek with getFileInfo is contained in the structure cffile.

March 10, 2008
Thanks everyone for taking the time to check this topic but I've given up on what I was really after. But I will try to explain it as everyone seems to be mis-understanding what actually happens and what I was after.

Firstly, I didn't want to rely on Client-side JavaScript because that's more open to abuse if not checked on the server-side.

Now imagine I have two files. Form.cfm and Save.cfm. Form.cfm contains just the form with a file upload box, this form submits to Save.cfm.

Now for save.cfm, there seems to be some confusion that the upload doesn't happen until you do cffile action="upload". This is not the case and I'll show this here.

Save.cfm

<cfdump var="#form.upload#" />
<!--- Will display the temporary location of the upload
The variable simple contains a string, nothing special
--->
<cfdump var="#GetFileInfo(form.upload)#" />
<!--- Will display file size and other details --->
<cffile action="read" file="#form.upload#" variable="file" />
<!--- File variable now contains the contents of the upload --->
<cfquery name="qInsertDoc" datasource="aDsn">
INSERT INTO tblDocs (upload)
VALUES (
<cfqueryparam cfsqltype="cf_sql_blob" value="#file#" />
)
</cfquery>

Now, please notice I didn't once use CFFile action="upload" but I still get the file and throw it into the database. More importantly the upload has already taken place and finished before save.cfm is executed. The only difference between doing it this way and doing it the cffile action="upload" way is I can't find out the original filename. All I ever wanted to know was where ColdFusion is hiding that name.

The reason I'm after that, without doing a CFFile action="upload", is this because I didn't want my validation component creating a copy of a file (which is all cffile action="upload" does) just to find out it's original name in order to validate it. And remember I don't want to rely on client-side JavaScript as that can be circumvented.

Thanks
Inspiring
March 10, 2008
Oh Yes, call the function with the onsubmit on the form
Inspiring
March 10, 2008
function getFileName(tf, tfn)
{
var f = document.getElementById(tf);
var fv = f.value
var s = fv.lastIndexOf("\\");
var n = fv.substring(s + 1);
document.getElementById(tfn).value = n;
return true;
}

In the above:
tf is the file field on the form
tfn is a hidden field that you save the file name in that you parsed from the file field
March 5, 2008
Thanks for the info c_wigginton, it's certainly true that there are still ways to get around any restrictions I try and place on the file type but I still like to do as much as I can server-side in the way of validation.

Azadi, thanks for the link, that's not a bad idea about the file checking that way.

In the end I've gone for the following example, I'm using CF8 so it doesn't seem to affect performance from what I can tell. I would be so much easier if I had the original filename another way but I guess this'll have to do.

<!--- Retrieve the file information by making a copy --->
<cffile action="upload" filefield="form.file" nameconflict="makeUnique" result="info" destination="#GetTempDirectory()#" />
<!--- Remove the temp copy --->
<cffile action="delete" file="#GetTempDirectory()#\#info.serverFile#" />

This way any code that wishes to do a CFFile action="upload" will still work and I get to validate the filename. Seems a bit much overhead but unless Adobe give up the secret of where the name is kept... ;)
Participating Frequently
March 4, 2008
I went down your same path awhile ago and couldn't find any alternatives other than client side when using CFFILE. CFFILE prior to CF8 is also memory intensive. You can look at is using something other than CF for the file upload. I've used JavaZoom's upload bean which uses JSP's and POJO's for the upload and works with JRun. The UploadBean provides the ability to obtain the uploaded file name.

http://www.javazoom.net/jzservlets/uploadbean/documentation/developerguide.html

Having said that, you really need to ask yourself is why are you completely afraid of client side? The key point is you don't have much control anyways from a client perspective on what is getting uploaded prior to the upload event. You can certainly apply filtering through a CFFILE accept attribute, but you can't guarantee the name of the file or what is in the file.

For example, you can use a simple copy command to combine a gif images with other file types, the below web link references combination with MP3. The uploaded file will still identify as a gif mime type even though there's hidden data in the file.

ref: http://www.raymond.cc/blog/archives/2006/06/26/hide-mp3-audio-inside-gif-picture/

So worrying about someone hacking the uploaded file name in a hidden field is moot since they could simply rename the file anything they wanted before selecting it in the browser.

As far as turning off JavaScript, you can force JavaScript being enabled by having the submit button being disabled and then enable the button when the document is loaded. jQuery is really nice for this.
Participating Frequently
March 4, 2008
The following script will capture the user's full path to the file in a hidden field. From there, you can extract out the filename on the form submission before you process the cffile.
March 4, 2008
Thanks c_wigginton, but my plan was to avoid anything client side. Since I didn't want someone to come along, disable JavaScript and enter something in the hidden field that's different from the existing field.