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
|
<!--- disable connector for ColdFusion > CF5 --->
|
39
|
<cfif Left(SERVER.COLDFUSION.PRODUCTVERSION,Find(",",SERVER.COLDFUSION.PRODUCTVERSION)-1) gt 5>
|
40
|
<cfabort>
|
41
|
</cfif>
|
42
|
|
43
|
<cfparam name="url.command" default="QuickUpload">
|
44
|
<cfparam name="url.type" default="File">
|
45
|
<cfparam name="url.currentFolder" default="/">
|
46
|
|
47
|
<cfif find( "/", getBaseTemplatePath() ) >
|
48
|
<cfset REQUEST.Fs = "/">
|
49
|
<cfelse>
|
50
|
<cfset REQUEST.Fs = "\">
|
51
|
</cfif>
|
52
|
|
53
|
<cfif url.command eq "QuickUpload">
|
54
|
<cfset url.currentFolder = "/">
|
55
|
</cfif>
|
56
|
|
57
|
<cfif not isDefined("REQUEST.config_included") or isDefined("URL.config_included")>
|
58
|
<cfinclude template="config.cfm">
|
59
|
</cfif>
|
60
|
|
61
|
<cfscript>
|
62
|
function SendUploadResults(errorNumber, fileUrl, fileName, customMsg)
|
63
|
{
|
64
|
WriteOutput('<script type="text/javascript">');
|
65
|
// Minified version of the document.domain automatic fix script (#1919).
|
66
|
// The original script can be found at _dev/domain_fix_template.js
|
67
|
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;}}})();");
|
68
|
WriteOutput('window.parent.OnUploadCompleted(' & errorNumber & ', "' & JSStringFormat(fileUrl) & '", "' & JSStringFormat(fileName) & '", "' & JSStringFormat(customMsg) & '");' );
|
69
|
WriteOutput('</script>');
|
70
|
}
|
71
|
</cfscript>
|
72
|
|
73
|
<cfif NOT config.enabled>
|
74
|
<cfset SendUploadResults(1, "", "", "This file uploader is disabled. Please check the ""editor/filemanager/connectors/cfm/config.cfm"" file")>
|
75
|
<cfabort>
|
76
|
</cfif>
|
77
|
|
78
|
<cfif isDefined("Config.ConfigAllowedCommands") and not ListFind(Config.ConfigAllowedCommands, url.command)>
|
79
|
<cfset SendUploadResults(1, "", "", "The """ & url.command & """ command isn't allowed")>
|
80
|
<cfabort>
|
81
|
</cfif>
|
82
|
|
83
|
<cfif isDefined("Config.ConfigAllowedTypes") and not ListFind(Config.ConfigAllowedTypes, url.type)>
|
84
|
<cfset SendUploadResults(1, "", "", "The """ & url.type & """ type isn't allowed")>
|
85
|
<cfabort>
|
86
|
</cfif>
|
87
|
|
88
|
<cfif find( "..", url.currentFolder) or find( "\", url.currentFolder)>
|
89
|
<cfset SendUploadResults(102, "", "", "")>
|
90
|
<cfabort>
|
91
|
</cfif>
|
92
|
|
93
|
<cfif REFind('(/\.)|(//)|[[:cntrl:]]|([\\:\*\?\"<>])', url.currentFolder)>
|
94
|
<cfset SendUploadResults(102, "", "", "")>
|
95
|
<cfabort>
|
96
|
</cfif>
|
97
|
|
98
|
|
99
|
<cfscript>
|
100
|
userFilesPath = config.userFilesPath;
|
101
|
|
102
|
if ( userFilesPath eq "" ) {
|
103
|
userFilesPath = "/userfiles/";
|
104
|
}
|
105
|
|
106
|
// make sure the user files path is correctly formatted
|
107
|
userFilesPath = replace(userFilesPath, "\", "/", "ALL");
|
108
|
userFilesPath = replace(userFilesPath, '//', '/', 'ALL');
|
109
|
if ( right(userFilesPath,1) NEQ "/" ) {
|
110
|
userFilesPath = userFilesPath & "/";
|
111
|
}
|
112
|
if ( left(userFilesPath,1) NEQ "/" ) {
|
113
|
userFilesPath = "/" & userFilesPath;
|
114
|
}
|
115
|
|
116
|
// make sure the current folder is correctly formatted
|
117
|
url.currentFolder = replace(url.currentFolder, "\", "/", "ALL");
|
118
|
url.currentFolder = replace(url.currentFolder, '//', '/', 'ALL');
|
119
|
if ( right(url.currentFolder,1) neq "/" ) {
|
120
|
url.currentFolder = url.currentFolder & "/";
|
121
|
}
|
122
|
if ( left(url.currentFolder,1) neq "/" ) {
|
123
|
url.currentFolder = "/" & url.currentFolder;
|
124
|
}
|
125
|
|
126
|
if (find("/",getBaseTemplatePath())) {
|
127
|
fs = "/";
|
128
|
} else {
|
129
|
fs = "\";
|
130
|
}
|
131
|
|
132
|
// Get the base physical path to the web root for this application. The code to determine the path automatically assumes that
|
133
|
// the "FCKeditor" directory in the http request path is directly off the web root for the application and that it's not a
|
134
|
// virtual directory or a symbolic link / junction. Use the serverPath config setting to force a physical path if necessary.
|
135
|
if ( len(config.serverPath) ) {
|
136
|
serverPath = config.serverPath;
|
137
|
|
138
|
if ( right(serverPath,1) neq fs ) {
|
139
|
serverPath = serverPath & fs;
|
140
|
}
|
141
|
} else {
|
142
|
serverPath = replaceNoCase(getBaseTemplatePath(),replace(cgi.script_name,"/",fs,"all"),"") & replace(userFilesPath,"/",fs,"all");
|
143
|
}
|
144
|
|
145
|
rootPath = left( serverPath, Len(serverPath) - Len(userFilesPath) ) ;
|
146
|
</cfscript>
|
147
|
<cfif url.command eq "QuickUpload">
|
148
|
<cfset resourceTypeUrl = rereplace( replace( Config.QuickUploadPath[url.type], fs, "/", "all"), "/$", "") >
|
149
|
<cfif isDefined( "Config.QuickUploadAbsolutePath" )
|
150
|
and structkeyexists( Config.QuickUploadAbsolutePath, url.type )
|
151
|
and Len( Config.QuickUploadAbsolutePath[url.type] )>
|
152
|
<cfset userFilesServerPath = Config.QuickUploadAbsolutePath[url.type] & url.currentFolder>
|
153
|
<cfelse>
|
154
|
<cftry>
|
155
|
<cfset userFilesServerPath = expandpath( resourceTypeUrl ) & url.currentFolder>
|
156
|
<!--- Catch: Parameter 1 of function ExpandPath must be a relative path --->
|
157
|
<cfcatch type="any">
|
158
|
<cfset userFilesServerPath = rootPath & Config.QuickUploadPath[url.type] & url.currentFolder>
|
159
|
</cfcatch>
|
160
|
</cftry>
|
161
|
</cfif>
|
162
|
<cfelseif url.command eq "FileUpload">
|
163
|
<cfset resourceTypeUrl = rereplace( replace( Config.FileTypesPath[url.type], fs, "/", "all"), "/$", "") >
|
164
|
<cfif isDefined( "Config.FileTypesAbsolutePath" )
|
165
|
and structkeyexists( Config.FileTypesAbsolutePath, url.type )
|
166
|
and Len( Config.FileTypesAbsolutePath[url.type] )>
|
167
|
<cfset userFilesServerPath = Config.FileTypesAbsolutePath[url.type] & url.currentFolder>
|
168
|
<cfelse>
|
169
|
<cftry>
|
170
|
<cfset userFilesServerPath = expandpath( resourceTypeUrl ) & url.currentFolder>
|
171
|
<!--- Catch: Parameter 1 of function ExpandPath must be a relative path --->
|
172
|
<cfcatch type="any">
|
173
|
<cfset userFilesServerPath = rootPath & Config.FileTypesPath[url.type] & url.currentFolder>
|
174
|
</cfcatch>
|
175
|
</cftry>
|
176
|
</cfif>
|
177
|
</cfif>
|
178
|
|
179
|
<cfset userFilesServerPath = replace( userFilesServerPath, "/", fs, "all" ) >
|
180
|
<!--- get rid of double directory separators --->
|
181
|
<cfset userFilesServerPath = replace( userFilesServerPath, fs & fs, fs, "all") >
|
182
|
|
183
|
<!--- create resource type directory if not exists --->
|
184
|
<cfset resourceTypeDirectory = left( userFilesServerPath, Len(userFilesServerPath) - Len(url.currentFolder) )>
|
185
|
|
186
|
<cfif not directoryexists( resourceTypeDirectory )>
|
187
|
|
188
|
<cfset currentPath = "">
|
189
|
<cftry>
|
190
|
<cfloop list="#resourceTypeDirectory#" index="name" delimiters="#fs#">
|
191
|
<cfif currentPath eq "" and fs eq "\">
|
192
|
<!--- Without checking this, we would have in Windows \C:\ --->
|
193
|
<cfif not directoryExists(name)>
|
194
|
<cfdirectory action="create" directory="#name#" mode="755">
|
195
|
</cfif>
|
196
|
<cfelse>
|
197
|
<cfif not directoryExists(currentPath & fs & name)>
|
198
|
<cfdirectory action="create" directory="#currentPath##fs##name#" mode="755">
|
199
|
</cfif>
|
200
|
</cfif>
|
201
|
|
202
|
<cfif fs eq "\" and currentPath eq "">
|
203
|
<cfset currentPath = name>
|
204
|
<cfelse>
|
205
|
<cfset currentPath = currentPath & fs & name>
|
206
|
</cfif>
|
207
|
</cfloop>
|
208
|
|
209
|
<cfcatch type="any">
|
210
|
|
211
|
<!--- this should only occur as a result of a permissions problem --->
|
212
|
<cfset SendUploadResults(103, "", "", "")>
|
213
|
<cfabort>
|
214
|
|
215
|
</cfcatch>
|
216
|
|
217
|
</cftry>
|
218
|
</cfif>
|
219
|
|
220
|
<cfset currentFolderPath = userFilesServerPath>
|
221
|
<cfset resourceType = url.type>
|
222
|
|
223
|
<cfset fileName = "">
|
224
|
<cfset fileExt = "">
|
225
|
|
226
|
<!--- Can be overwritten. The last value will be sent with the result --->
|
227
|
<cfset customMsg = "">
|
228
|
|
229
|
<cftry>
|
230
|
<cfif isDefined( "REQUEST.Config.TempDirectory" )>
|
231
|
<cfset sTempDir = REQUEST.Config.TempDirectory>
|
232
|
<cfelse>
|
233
|
<cfset sTempDir = GetTempDirectory()>
|
234
|
</cfif>
|
235
|
|
236
|
<!--- first upload the file with an unique filename --->
|
237
|
<cffile action="upload"
|
238
|
fileField="NewFile"
|
239
|
destination="#sTempDir#"
|
240
|
nameConflict="makeunique"
|
241
|
mode="644"
|
242
|
attributes="normal">
|
243
|
|
244
|
<cfif cffile.fileSize EQ 0>
|
245
|
<cffile action="delete" file="#cffile.ServerDirectory##fs##cffile.ServerFile#">
|
246
|
<cfthrow>
|
247
|
</cfif>
|
248
|
|
249
|
<cfset sTempFilePath = CFFILE.ServerDirectory & REQUEST.fs & CFFILE.ServerFile>
|
250
|
<cfset lAllowedExtensions = config.allowedExtensions[#resourceType#]>
|
251
|
<cfset lDeniedExtensions = config.deniedExtensions[#resourceType#]>
|
252
|
|
253
|
<cfif ( len(lAllowedExtensions) and not listFindNoCase(lAllowedExtensions,cffile.ServerFileExt) )
|
254
|
or ( len(lDeniedExtensions) and listFindNoCase(lDeniedExtensions,cffile.ServerFileExt) )>
|
255
|
<cfset errorNumber = "202">
|
256
|
<cffile action="delete" file="#cffile.ServerDirectory##fs##cffile.ServerFile#">
|
257
|
<cfelse>
|
258
|
<cfscript>
|
259
|
errorNumber = 0;
|
260
|
fileName = cffile.ClientFileName ;
|
261
|
fileExt = cffile.ServerFileExt ;
|
262
|
fileExisted = false ;
|
263
|
|
264
|
// munge filename for html download. Only a-z, 0-9, _, - and . are allowed
|
265
|
if( reFind("[^A-Za-z0-9_\-\.]", fileName) ) {
|
266
|
fileName = reReplace(fileName, "[^A-Za-z0-9\-\.]", "_", "ALL");
|
267
|
fileName = reReplace(fileName, "_{2,}", "_", "ALL");
|
268
|
fileName = reReplace(fileName, "([^_]+)_+$", "\1", "ALL");
|
269
|
fileName = reReplace(fileName, "$_([^_]+)$", "\1", "ALL");
|
270
|
}
|
271
|
|
272
|
// remove additional dots from file name
|
273
|
if( isDefined("Config.ForceSingleExtension") and Config.ForceSingleExtension )
|
274
|
fileName = replace( fileName, '.', "_", "all" ) ;
|
275
|
|
276
|
// When the original filename already exists, add numbers (0), (1), (2), ... at the end of the filename.
|
277
|
counter = 0;
|
278
|
tmpFileName = fileName;
|
279
|
while( fileExists("#currentFolderPath##fileName#.#fileExt#") ) {
|
280
|
fileExisted = true ;
|
281
|
counter = counter + 1 ;
|
282
|
fileName = tmpFileName & '(#counter#)' ;
|
283
|
}
|
284
|
</cfscript>
|
285
|
|
286
|
<cfset destination = currentFolderPath & fileName & "." & fileExt>
|
287
|
<cfif fileExisted>
|
288
|
<cfset errorNumber = "201">
|
289
|
</cfif>
|
290
|
|
291
|
<cftry>
|
292
|
<cffile action="copy" source="#sTempFilePath#" destination="#destination#" mode="755">
|
293
|
<cfcatch type="any">
|
294
|
<cfset errorNumber = 102>
|
295
|
</cfcatch>
|
296
|
</cftry>
|
297
|
<cftry>
|
298
|
<cffile action="delete" file="#sTempFilePath#">
|
299
|
<cfcatch type="any">
|
300
|
</cfcatch>
|
301
|
</cftry>
|
302
|
</cfif>
|
303
|
|
304
|
<cfcatch type="any">
|
305
|
|
306
|
<cfset errorNumber = "1">
|
307
|
<cfset customMsg = cfcatch.message >
|
308
|
|
309
|
</cfcatch>
|
310
|
</cftry>
|
311
|
|
312
|
<cfif errorNumber EQ 0>
|
313
|
<!--- file was uploaded succesfully --->
|
314
|
<cfset SendUploadResults(errorNumber, '#resourceTypeUrl##url.currentFolder##fileName#.#fileExt#', replace( fileName & "." & fileExt, "'", "\'", "ALL"), "")>
|
315
|
<cfabort>
|
316
|
<cfelseif errorNumber EQ 201>
|
317
|
<!--- file was changed (201), submit the new filename --->
|
318
|
<cfset SendUploadResults(errorNumber, '#resourceTypeUrl##url.currentFolder##fileName#.#fileExt#', replace( fileName & "." & fileExt, "'", "\'", "ALL"), customMsg)>
|
319
|
<cfabort>
|
320
|
<cfelse>
|
321
|
<!--- An error occured(202). Submit only the error code and a message (if available). --->
|
322
|
<cfset SendUploadResults(errorNumber, '', '', customMsg)>
|
323
|
<cfabort>
|
324
|
</cfif>
|