PageRenderTime 20ms CodeModel.GetById 13ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/pigeoncms/Plugins/fckeditor/editor/filemanager/connectors/cfm/cf5_upload.cfm

http://pigeoncms.googlecode.com/
ColdFusion | 309 lines | 226 code | 38 blank | 45 comment | 8 complexity | d3ca4879b8865fead8ac9998c99f8c4e MD5 | raw file
  1<cfsetting enablecfoutputonly="Yes">
  2<!---
  3 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
  4 * Copyright (C) 2003-2009 Frederico Caldeira Knabben
  5 *
  6 * == BEGIN LICENSE ==
  7 *
  8 * Licensed under the terms of any of the following licenses at your
  9 * choice:
 10 *
 11 *  - GNU General Public License Version 2 or later (the "GPL")
 12 *    http://www.gnu.org/licenses/gpl.html
 13 *
 14 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 15 *    http://www.gnu.org/licenses/lgpl.html
 16 *
 17 *  - Mozilla Public License Version 1.1 or later (the "MPL")
 18 *    http://www.mozilla.org/MPL/MPL-1.1.html
 19 *
 20 * == END LICENSE ==
 21 *
 22 * This is the "File Uploader" for ColdFusion 5.
 23 * Based on connector.cfm by Mark Woods (mark@thickpaddy.com)
 24 *
 25 * Note:
 26 * FCKeditor requires that the connector responds with UTF-8 encoded XML.
 27 * As ColdFusion 5 does not fully support UTF-8 encoding, we force ASCII
 28 * file and folder names in this connector to allow CF5 send a UTF-8
 29 * encoded response - code points under 127 in UTF-8 are stored using a
 30 * single byte, using the same encoding as ASCII, which is damn handy.
 31 * This is all grand for the English speakers, like meself, but I dunno
 32 * how others are gonna take to it. Well, the previous version of this
 33 * connector already did this with file names and nobody seemed to mind,
 34 * so fingers-crossed nobody will mind their folder names being munged too.
 35 *
 36--->
 37
 38<cfparam name="url.command" default="QuickUpload">
 39<cfparam name="url.type" default="File">
 40<cfparam name="url.currentFolder" default="/">
 41
 42<cfif url.command eq "QuickUpload">
 43	<cfset url.currentFolder = "/">
 44</cfif>
 45
 46<cfif not isDefined("config_included")>
 47	<cfinclude template="config.cfm">
 48</cfif>
 49
 50<cfscript>
 51	function SendUploadResults(errorNumber, fileUrl, fileName, customMsg)
 52	{
 53		WriteOutput('<script type="text/javascript">');
 54		// Minified version of the document.domain automatic fix script (#1919).
 55		// The original script can be found at _dev/domain_fix_template.js
 56		WriteOutput("(function(){var d=document.domain;while (true){try{var A=window.parent.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();");
 57		WriteOutput('window.parent.OnUploadCompleted(' & errorNumber & ', "' & JSStringFormat(fileUrl) & '", "' & JSStringFormat(fileName) & '", "' & JSStringFormat(customMsg) & '");' );
 58		WriteOutput('</script>');
 59	}
 60</cfscript>
 61
 62<cfif NOT config.enabled>
 63	<cfset SendUploadResults(1, "", "", "This file uploader is disabled. Please check the ""editor/filemanager/connectors/cfm/config.cfm"" file")>
 64	<cfabort>
 65</cfif>
 66
 67<cfif isDefined("Config.ConfigAllowedCommands") and not ListFind(Config.ConfigAllowedCommands, url.command)>
 68	<cfset SendUploadResults(1, "", "", "The """ & url.command & """ command isn't allowed")>
 69	<cfabort>
 70</cfif>
 71
 72<cfif isDefined("Config.ConfigAllowedTypes") and not ListFind(Config.ConfigAllowedTypes, url.type)>
 73	<cfset SendUploadResults(1, "", "", "The """ & url.type &  """ type isn't allowed")>
 74	<cfabort>
 75</cfif>
 76
 77<cfif find( "..", url.currentFolder) or find( "\", url.currentFolder)>
 78	<cfset SendUploadResults(102)>
 79	<cfabort>
 80</cfif>
 81
 82<cfif REFind('(/\.)|(//)|[[:cntrl:]]|([\\:\*\?\"<>])', url.currentFolder)>
 83	<cfset SendUploadResults(102)>
 84	<cfabort>
 85</cfif>
 86
 87
 88<cfscript>
 89	userFilesPath = config.userFilesPath;
 90
 91	if ( userFilesPath eq "" ) {
 92		userFilesPath = "/userfiles/";
 93	}
 94
 95	// make sure the user files path is correctly formatted
 96	userFilesPath = replace(userFilesPath, "\", "/", "ALL");
 97	userFilesPath = replace(userFilesPath, '//', '/', 'ALL');
 98	if ( right(userFilesPath,1) NEQ "/" ) {
 99		userFilesPath = userFilesPath & "/";
100	}
101	if ( left(userFilesPath,1) NEQ "/" ) {
102		userFilesPath = "/" & userFilesPath;
103	}
104
105	// make sure the current folder is correctly formatted
106	url.currentFolder = replace(url.currentFolder, "\", "/", "ALL");
107	url.currentFolder = replace(url.currentFolder, '//', '/', 'ALL');
108	if ( right(url.currentFolder,1) neq "/" ) {
109		url.currentFolder = url.currentFolder & "/";
110	}
111	if ( left(url.currentFolder,1) neq "/" ) {
112		url.currentFolder = "/" & url.currentFolder;
113	}
114
115	if (find("/",getBaseTemplatePath())) {
116		fs = "/";
117	} else {
118		fs = "\";
119	}
120
121	// Get the base physical path to the web root for this application. The code to determine the path automatically assumes that
122	// the "FCKeditor" directory in the http request path is directly off the web root for the application and that it's not a
123	// virtual directory or a symbolic link / junction. Use the serverPath config setting to force a physical path if necessary.
124	if ( len(config.serverPath) ) {
125		serverPath = config.serverPath;
126
127		if ( right(serverPath,1) neq fs ) {
128			serverPath = serverPath & fs;
129		}
130	} else {
131		serverPath = replaceNoCase(getBaseTemplatePath(),replace(cgi.script_name,"/",fs,"all"),"") & replace(userFilesPath,"/",fs,"all");
132	}
133
134	rootPath = left( serverPath, Len(serverPath) - Len(userFilesPath) ) ;
135</cfscript>
136<cfif url.command eq "QuickUpload">
137	<cfset resourceTypeUrl = rereplace( replace( Config.QuickUploadPath[url.type], fs, "/", "all"), "/$", "") >
138	<cfif isDefined( "Config.QuickUploadAbsolutePath" )
139			and structkeyexists( Config.QuickUploadAbsolutePath, url.type )
140			and Len( Config.QuickUploadAbsolutePath[url.type] )>
141				<cfset userFilesServerPath = Config.QuickUploadAbsolutePath[url.type] & url.currentFolder>
142	<cfelse>
143		<cftry>
144		<cfset userFilesServerPath = expandpath( resourceTypeUrl ) & url.currentFolder>
145		<!--- Catch: Parameter 1 of function ExpandPath must be a relative path --->
146		<cfcatch type="any">
147			<cfset userFilesServerPath = rootPath & Config.QuickUploadPath[url.type] & url.currentFolder>
148		</cfcatch>
149		</cftry>
150	</cfif>
151<cfelseif url.command eq "FileUpload">
152	<cfset resourceTypeUrl = rereplace( replace( Config.FileTypesPath[url.type], fs, "/", "all"), "/$", "") >
153	<cfif isDefined( "Config.FileTypesAbsolutePath" )
154			and structkeyexists( Config.FileTypesAbsolutePath, url.type )
155			and Len( Config.FileTypesAbsolutePath[url.type] )>
156				<cfset userFilesServerPath = Config.FileTypesAbsolutePath[url.type] & url.currentFolder>
157	<cfelse>
158		<cftry>
159		<cfset userFilesServerPath = expandpath( resourceTypeUrl ) & url.currentFolder>
160		<!--- Catch: Parameter 1 of function ExpandPath must be a relative path --->
161		<cfcatch type="any">
162			<cfset userFilesServerPath = rootPath & Config.FileTypesPath[url.type] & url.currentFolder>
163		</cfcatch>
164		</cftry>
165	</cfif>
166</cfif>
167
168<cfset userFilesServerPath = replace( userFilesServerPath, "/", fs, "all" ) >
169<!--- get rid of double directory separators --->
170<cfset userFilesServerPath = replace( userFilesServerPath, fs & fs, fs, "all") >
171
172<!--- create resource type directory if not exists --->
173<cfset resourceTypeDirectory = left( userFilesServerPath, Len(userFilesServerPath) - Len(url.currentFolder) )>
174
175<cfif not directoryexists( resourceTypeDirectory )>
176
177	<cfset currentPath = "">
178	<cftry>
179		<cfloop list="#resourceTypeDirectory#" index="name" delimiters="#fs#">
180			<cfif currentPath eq "" and fs eq "\">
181				<!--- Without checking this, we would have in Windows \C:\ --->
182				<cfif not directoryExists(name)>
183					<cfdirectory action="create" directory="#name#" mode="755">
184				</cfif>
185			<cfelse>
186				<cfif not directoryExists(currentPath & fs & name)>
187					<cfdirectory action="create" directory="#currentPath##fs##name#" mode="755">
188				</cfif>
189			</cfif>
190
191			<cfif fs eq "\" and currentPath eq "">
192				<cfset currentPath = name>
193			<cfelse>
194				<cfset currentPath = currentPath & fs & name>
195			</cfif>
196		</cfloop>
197
198	<cfcatch type="any">
199
200		<!--- this should only occur as a result of a permissions problem --->
201		<cfset SendUploadResults(103)>
202		<cfabort>
203
204	</cfcatch>
205
206	</cftry>
207</cfif>
208
209<cfset currentFolderPath = userFilesServerPath>
210<cfset resourceType = url.type>
211
212<cfset fileName = "">
213<cfset fileExt = "">
214
215<!--- Can be overwritten. The last value will be sent with the result --->
216<cfset customMsg = "">
217
218<cftry>
219	<!--- first upload the file with an unique filename --->
220	<cffile action="upload"
221		fileField="NewFile"
222		destination="#currentFolderPath#"
223		nameConflict="makeunique"
224		mode="644"
225		attributes="normal">
226
227	<cfif cffile.fileSize EQ 0>
228		<cfthrow>
229	</cfif>
230
231	<cfset lAllowedExtensions = config.allowedExtensions[#resourceType#]>
232	<cfset lDeniedExtensions = config.deniedExtensions[#resourceType#]>
233
234	<cfif ( len(lAllowedExtensions) and not listFindNoCase(lAllowedExtensions,cffile.ServerFileExt) )
235		or ( len(lDeniedExtensions) and listFindNoCase(lDeniedExtensions,cffile.ServerFileExt) )>
236
237		<cfset errorNumber = "202">
238		<cffile action="delete" file="#cffile.ServerDirectory##fs##cffile.ServerFile#">
239
240	<cfelse>
241
242		<cfscript>
243		errorNumber = 0;
244		fileName = cffile.ClientFileName ;
245		fileExt = cffile.ServerFileExt ;
246		fileExisted = false ;
247
248		// munge filename for html download. Only a-z, 0-9, _, - and . are allowed
249		if( reFind("[^A-Za-z0-9_\-\.]", fileName) ) {
250			fileName = reReplace(fileName, "[^A-Za-z0-9\-\.]", "_", "ALL");
251			fileName = reReplace(fileName, "_{2,}", "_", "ALL");
252			fileName = reReplace(fileName, "([^_]+)_+$", "\1", "ALL");
253			fileName = reReplace(fileName, "$_([^_]+)$", "\1", "ALL");
254		}
255
256		// remove additional dots from file name
257		if( isDefined("Config.ForceSingleExtension") and Config.ForceSingleExtension )
258			fileName = replace( fileName, '.', "_", "all" ) ;
259
260		// When the original filename already exists, add numbers (0), (1), (2), ... at the end of the filename.
261		if( compare( cffile.ServerFileName, fileName ) ) {
262			counter = 0;
263			tmpFileName = fileName;
264			while( fileExists("#currentFolderPath##fileName#.#fileExt#") ) {
265				fileExisted = true ;
266				counter = counter + 1 ;
267				fileName = tmpFileName & '(#counter#)' ;
268			}
269		}
270		</cfscript>
271
272		<!--- Rename the uploaded file, if neccessary --->
273		<cfif compare(cffile.ServerFileName,fileName)>
274
275			<cfif fileExisted>
276				<cfset errorNumber = "201">
277			</cfif>
278			<cffile
279				action="rename"
280				source="#currentFolderPath##cffile.ServerFileName#.#cffile.ServerFileExt#"
281				destination="#currentFolderPath##fileName#.#fileExt#"
282				mode="644"
283				attributes="normal">
284
285		</cfif>
286
287	</cfif>
288
289	<cfcatch type="any">
290
291		<cfset errorNumber = "1">
292		<cfset customMsg = cfcatch.message >
293
294	</cfcatch>
295</cftry>
296
297<cfif errorNumber EQ 0>
298	<!--- file was uploaded succesfully --->
299	<cfset SendUploadResults(errorNumber, '#resourceTypeUrl##url.currentFolder##fileName#.#fileExt#', replace( fileName & "." & fileExt, "'", "\'", "ALL"), "")>
300	<cfabort>
301<cfelseif errorNumber EQ 201>
302	<!--- file was changed (201), submit the new filename --->
303	<cfset SendUploadResults(errorNumber, '#resourceTypeUrl##url.currentFolder##fileName#.#fileExt#', replace( fileName & "." & fileExt, "'", "\'", "ALL"), customMsg)>
304	<cfabort>
305<cfelse>
306	<!--- An error occured(202). Submit only the error code and a message (if available). --->
307	<cfset SendUploadResults(errorNumber, '', '', customMsg)>
308	<cfabort>
309</cfif>