Index: /FCKeditor.Net/trunk/FCKeditor.cs
===================================================================
--- /FCKeditor.Net/trunk/FCKeditor.cs	(revision 1201)
+++ /FCKeditor.Net/trunk/FCKeditor.cs	(revision 1202)
@@ -425,5 +425,5 @@
 			string sUserAgent = request.UserAgent;
 
-			if ( sUserAgent.Contains( "Gecko/" ) )
+			if ( sUserAgent.IndexOf( "Gecko/" ) >= 0 )
 			{
 				Match oMatch = Regex.Match( request.UserAgent, @"(?<=Gecko/)\d{8}" );
@@ -431,5 +431,5 @@
 			}
 
-			if ( sUserAgent.Contains( "Opera/" ) )
+			if ( sUserAgent.IndexOf( "Opera/" ) >= 0 )
 			{
 				Match oMatch = Regex.Match( request.UserAgent, @"(?<=Opera/)[\d\.]+" );
@@ -437,5 +437,5 @@
 			}
 
-			if ( sUserAgent.Contains( "AppleWebKit/" ) )
+			if ( sUserAgent.IndexOf( "AppleWebKit/" ) >= 0 )
 			{
 				Match oMatch = Regex.Match( request.UserAgent, @"(?<=AppleWebKit/)\d+" );
Index: /FCKeditor.Net/trunk/FileBrowser/Config.cs
===================================================================
--- /FCKeditor.Net/trunk/FileBrowser/Config.cs	(revision 1202)
+++ /FCKeditor.Net/trunk/FileBrowser/Config.cs	(revision 1202)
@@ -0,0 +1,164 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the code behind of the connector.aspx page used by the 
+ * File Browser.
+ */
+
+using System;
+using System.Text;
+using System.Web;
+
+namespace FredCK.FCKeditorV2.FileBrowser
+{
+	public class Config : System.Web.UI.UserControl
+	{
+		private const string DEFAULT_USER_FILES_PATH = "/userfiles/";
+
+		private string sUserFilesDirectory;
+
+		public bool Enabled;
+		public string UserFilesPath;
+		public string UserFilesAbsolutePath;
+		public bool ForceSingleExtension;
+		public string[] AllowedTypes;
+		public string[] HtmlExtensions;
+		public TypeConfigList TypeConfig;
+
+		public Config()
+		{}
+
+		private void DefaultSettings() 
+		{
+			// Initialize all default settings.
+
+			Enabled = false;
+			UserFilesPath = "/userfiles/";
+			UserFilesAbsolutePath = "";
+			ForceSingleExtension = true;
+			AllowedTypes = new string[] { "File", "Image", "Flash", "Media" };
+			HtmlExtensions = new string[] { "html", "htm", "xml", "xsd", "txt", "js" };
+
+			TypeConfig = new TypeConfigList( (FileWorkerBase)this.Page );
+
+			TypeConfig[ "File" ].AllowedExtensions = new string[] { "7z", "aiff", "asf", "avi", "bmp", "csv", "doc", "fla", "flv", "gif", "gz", "gzip", "jpeg", "jpg", "mid", "mov", "mp3", "mp4", "mpc", "mpeg", "mpg", "ods", "odt", "pdf", "png", "ppt", "pxd", "qt", "ram", "rar", "rm", "rmi", "rmvb", "rtf", "sdc", "sitd", "swf", "sxc", "sxw", "tar", "tgz", "tif", "tiff", "txt", "vsd", "wav", "wma", "wmv", "xls", "xml", "zip" };
+			TypeConfig[ "File" ].DeniedExtensions = new string[] { };
+			TypeConfig[ "File" ].FilesPath = "%UserFilesPath%file/";
+			TypeConfig[ "File" ].FilesAbsolutePath = ( UserFilesAbsolutePath == "" ? "" : "%UserFilesAbsolutePath%file/" );
+			TypeConfig[ "File" ].QuickUploadPath = "%UserFilesPath%";
+			TypeConfig[ "File" ].QuickUploadAbsolutePath = "%UserFilesAbsolutePath%";
+
+			TypeConfig[ "Image" ].AllowedExtensions = new string[] { "bmp", "gif", "jpeg", "jpg", "png" };
+			TypeConfig[ "Image" ].DeniedExtensions = new string[] { };
+			TypeConfig[ "Image" ].FilesPath = "%UserFilesPath%image/";
+			TypeConfig[ "Image" ].FilesAbsolutePath = ( UserFilesAbsolutePath == "" ? "" : "%UserFilesAbsolutePath%image/" );
+			TypeConfig[ "Image" ].QuickUploadPath = "%UserFilesPath%";
+			TypeConfig[ "Image" ].QuickUploadAbsolutePath = "%UserFilesAbsolutePath%";
+
+			TypeConfig[ "Flash" ].AllowedExtensions = new string[] { "swf", "flv" };
+			TypeConfig[ "Flash" ].DeniedExtensions = new string[] { };
+			TypeConfig[ "Flash" ].FilesPath = "%UserFilesPath%flash/";
+			TypeConfig[ "Flash" ].FilesAbsolutePath = ( UserFilesAbsolutePath == "" ? "" : "%UserFilesAbsolutePath%flash/" );
+			TypeConfig[ "Flash" ].QuickUploadPath = "%UserFilesPath%";
+			TypeConfig[ "Flash" ].QuickUploadAbsolutePath = "%UserFilesAbsolutePath%";
+
+			TypeConfig[ "Media" ].AllowedExtensions = new string[] { "aiff", "asf", "avi", "bmp", "fla", "flv", "gif", "jpeg", "jpg", "mid", "mov", "mp3", "mp4", "mpc", "mpeg", "mpg", "png", "qt", "ram", "rm", "rmi", "rmvb", "swf", "tif", "tiff", "wav", "wma", "wmv" };
+			TypeConfig[ "Media" ].DeniedExtensions = new string[] { };
+			TypeConfig[ "Media" ].FilesPath = "%UserFilesPath%media/";
+			TypeConfig[ "Media" ].FilesAbsolutePath = ( UserFilesAbsolutePath == "" ? "" : "%UserFilesAbsolutePath%media/" );
+			TypeConfig[ "Media" ].QuickUploadPath = "%UserFilesPath%";
+			TypeConfig[ "Media" ].QuickUploadAbsolutePath = "%UserFilesAbsolutePath%";
+		}
+
+		internal void LoadConfig()
+		{
+			DefaultSettings();
+
+			// Call the setConfig() function for the configuration file (config.ascx).
+			SetConfig();
+
+			// Look for possible UserFilesPath override options.
+
+			// Session
+			string userFilesPath = Session[ "FCKeditor:UserFilesPath" ] as string;
+
+			// Application
+			if ( userFilesPath == null || userFilesPath.Length == 0 )
+				userFilesPath = Application[ "FCKeditor:UserFilesPath" ] as string;
+
+			// Web.config file.
+			if ( userFilesPath == null || userFilesPath.Length == 0 )
+				userFilesPath = System.Configuration.ConfigurationSettings.AppSettings[ "FCKeditor:UserFilesPath" ];
+
+			// config.asxc
+			if ( userFilesPath == null || userFilesPath.Length == 0 )
+				userFilesPath = this.UserFilesPath;
+
+			if ( userFilesPath == null || userFilesPath.Length == 0 )
+				userFilesPath = DEFAULT_USER_FILES_PATH;
+
+			// Check that the user path ends with slash ("/")
+			if ( !userFilesPath.EndsWith( "/" ) )
+				userFilesPath += "/";
+
+			userFilesPath = this.ResolveUrl( userFilesPath );
+
+			this.UserFilesPath = userFilesPath;
+		}
+
+		/// <summary>
+		/// The absolution path (server side) of the user files directory. It 
+		/// is based on the <see cref="FileWorkerBase.UserFilesPath"/>.
+		/// </summary>
+		internal string UserFilesDirectory
+		{
+			get
+			{
+				if ( sUserFilesDirectory == null )
+				{
+					if ( this.UserFilesAbsolutePath.Length > 0 )
+					{
+						sUserFilesDirectory = this.UserFilesAbsolutePath;
+						sUserFilesDirectory = sUserFilesDirectory.TrimEnd( '\\', '/' ) + '/';
+					}
+					else
+					{
+						// Get the local (server) directory path translation.
+						sUserFilesDirectory = Server.MapPath( this.UserFilesPath );
+					}
+				}
+				return sUserFilesDirectory;
+			}
+		}
+
+		public virtual void SetConfig()
+		{ }
+
+		internal bool CheckIsTypeAllowed( string typeName )
+		{
+			return ( System.Array.IndexOf( this.AllowedTypes, typeName ) >= 0 );
+		}
+
+		internal bool CheckIsNonHtmlExtension( string extension )
+		{
+			return ( this.HtmlExtensions.Length == 0 || !Util.ArrayContains( this.HtmlExtensions, extension, System.Collections.CaseInsensitiveComparer.DefaultInvariant ) );
+		}
+	}
+}
Index: /FCKeditor.Net/trunk/FileBrowser/Connector.cs
===================================================================
--- /FCKeditor.Net/trunk/FileBrowser/Connector.cs	(revision 1202)
+++ /FCKeditor.Net/trunk/FileBrowser/Connector.cs	(revision 1202)
@@ -0,0 +1,207 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the code behind of the connector.aspx page used by the 
+ * File Browser.
+ */
+
+using System ;
+using System.Globalization ;
+using System.Xml ;
+using System.Web ;
+
+namespace FredCK.FCKeditorV2.FileBrowser
+{
+	public class Connector : FileWorkerBase
+	{
+		protected override void OnLoad(EventArgs e)
+		{
+			Config.LoadConfig();
+
+			if ( !Config.Enabled )
+			{
+				XmlResponseHandler.SendError( Response, 1, "This connector is disabled. Please check the \"editor/filemanager/connectors/aspx/config.aspx\" file." );
+				return;
+			}
+
+			// Get the main request information.
+			string sCommand = Request.QueryString["Command"] ;
+			string sResourceType = Request.QueryString[ "Type" ];
+			string sCurrentFolder = Request.QueryString[ "CurrentFolder" ];
+
+			if ( sCommand == null || sResourceType == null || sCurrentFolder == null )
+			{
+				XmlResponseHandler.SendError( Response, 1, "Invalid request." );
+				return;
+			}
+
+			// Check if it is an allowed type.
+			if ( !Config.CheckIsTypeAllowed( sResourceType ) )
+			{
+				XmlResponseHandler.SendError( Response, 1, "Invalid resource type specified." ) ;
+				return ;
+			}
+
+			// Check the current folder syntax (must begin and start with a slash).
+			if ( ! sCurrentFolder.EndsWith( "/" ) )
+				sCurrentFolder += "/" ;
+			if ( ! sCurrentFolder.StartsWith( "/" ) )
+				sCurrentFolder = "/" + sCurrentFolder ;
+
+			// Check for invalid folder paths (..).
+			if ( sCurrentFolder.IndexOf( ".." ) >= 0 )
+			{
+				XmlResponseHandler.SendError( Response, 102, "" );
+				return;
+			}
+
+			// File Upload doesn't have to return XML, so it must be intercepted before anything.
+			if ( sCommand == "FileUpload" )
+			{
+				this.FileUpload( sResourceType, sCurrentFolder, false ) ;
+				return ;
+			}
+
+			XmlResponseHandler oResponseHandler = new XmlResponseHandler( this, Response );
+			XmlNode oConnectorNode = oResponseHandler.CreateBaseXml( sCommand, sResourceType, sCurrentFolder );
+
+			// Execute the required command.
+			switch( sCommand )
+			{
+				case "GetFolders" :
+					this.GetFolders( oConnectorNode, sResourceType, sCurrentFolder ) ;
+					break ;
+				case "GetFoldersAndFiles" :
+					this.GetFolders( oConnectorNode, sResourceType, sCurrentFolder ) ;
+					this.GetFiles( oConnectorNode, sResourceType, sCurrentFolder ) ;
+					break ;
+				case "CreateFolder" :
+					this.CreateFolder( oConnectorNode, sResourceType, sCurrentFolder ) ;
+					break ;
+			}
+
+			oResponseHandler.SendResponse();
+		}
+
+		#region Command Handlers
+
+		private void GetFolders( XmlNode connectorNode, string resourceType, string currentFolder )
+		{
+			// Map the virtual path to the local server path.
+			string sServerDir = this.ServerMapFolder( resourceType, currentFolder, false ) ;
+
+			// Create the "Folders" node.
+			XmlNode oFoldersNode = XmlUtil.AppendElement( connectorNode, "Folders" ) ;
+
+			System.IO.DirectoryInfo oDir = new System.IO.DirectoryInfo( sServerDir ) ;
+			System.IO.DirectoryInfo[] aSubDirs = oDir.GetDirectories() ;
+
+			for ( int i = 0 ; i < aSubDirs.Length ; i++ )
+			{
+				// Create the "Folders" node.
+				XmlNode oFolderNode = XmlUtil.AppendElement( oFoldersNode, "Folder" ) ;
+				XmlUtil.SetAttribute( oFolderNode, "name", aSubDirs[i].Name ) ;
+			}
+		}
+
+		private void GetFiles( XmlNode connectorNode, string resourceType, string currentFolder )
+		{
+			// Map the virtual path to the local server path.
+			string sServerDir = this.ServerMapFolder( resourceType, currentFolder, false ) ;
+
+			// Create the "Files" node.
+			XmlNode oFilesNode = XmlUtil.AppendElement( connectorNode, "Files" ) ;
+
+			System.IO.DirectoryInfo oDir = new System.IO.DirectoryInfo( sServerDir ) ;
+			System.IO.FileInfo[] aFiles = oDir.GetFiles() ;
+
+			for ( int i = 0 ; i < aFiles.Length ; i++ )
+			{
+				Decimal iFileSize = Math.Round( (Decimal)aFiles[i].Length / 1024 ) ;
+				if ( iFileSize < 1 && aFiles[i].Length != 0 ) iFileSize = 1 ;
+
+				// Create the "File" node.
+				XmlNode oFileNode = XmlUtil.AppendElement( oFilesNode, "File" ) ;
+				XmlUtil.SetAttribute( oFileNode, "name", aFiles[i].Name ) ;
+				XmlUtil.SetAttribute( oFileNode, "size", iFileSize.ToString( CultureInfo.InvariantCulture ) ) ;
+			}
+		}
+
+		private void CreateFolder( XmlNode connectorNode, string resourceType, string currentFolder )
+		{
+			string sErrorNumber = "0" ;
+
+			string sNewFolderName = Request.QueryString["NewFolderName"] ;
+			sNewFolderName = this.SanitizeFolderName( sNewFolderName );
+
+			if ( sNewFolderName == null || sNewFolderName.Length == 0 )
+				sErrorNumber = "102" ;
+			else
+			{
+				// Map the virtual path to the local server path of the current folder.
+				string sServerDir = this.ServerMapFolder( resourceType, currentFolder, false ) ;
+
+				try
+				{
+					Util.CreateDirectory( System.IO.Path.Combine( sServerDir, sNewFolderName )) ;
+				}
+				catch ( ArgumentException )
+				{
+					sErrorNumber = "102" ;
+				}
+				catch ( System.IO.PathTooLongException )
+				{
+					sErrorNumber = "102" ;
+				}
+				catch ( System.IO.IOException )
+				{
+					sErrorNumber = "101" ;
+				}
+				catch ( System.Security.SecurityException )
+				{
+					sErrorNumber = "103" ;
+				}
+				catch ( Exception )
+				{
+					sErrorNumber = "110" ;
+				}
+			}
+
+			// Create the "Error" node.
+			XmlNode oErrorNode = XmlUtil.AppendElement( connectorNode, "Error" ) ;
+			XmlUtil.SetAttribute( oErrorNode, "number", sErrorNumber ) ;
+		}
+
+
+		#endregion
+
+		#region Directory Mapping
+
+		internal string GetUrlFromPath( string resourceType, string folderPath )
+		{
+			if ( resourceType == null || resourceType.Length == 0 )
+				return this.Config.UserFilesPath.TrimEnd( '/' ) + folderPath;
+			else
+				return this.Config.TypeConfig[ resourceType ].GetFilesPath().TrimEnd( '/' ) + folderPath;
+		}
+
+		#endregion
+	}
+}
Index: /FCKeditor.Net/trunk/FileBrowser/FileWorkerBase.cs
===================================================================
--- /FCKeditor.Net/trunk/FileBrowser/FileWorkerBase.cs	(revision 1202)
+++ /FCKeditor.Net/trunk/FileBrowser/FileWorkerBase.cs	(revision 1202)
@@ -0,0 +1,189 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Base class used by the FileBrowserConnector and Uploader.
+ */
+
+using System;
+using System.Web;
+using System.Text.RegularExpressions;
+
+namespace FredCK.FCKeditorV2.FileBrowser
+{
+	public abstract class FileWorkerBase : System.Web.UI.Page
+	{
+		public Config Config;
+
+		protected void FileUpload( string resourceType, string currentFolder, bool isQuickUpload )
+		{
+			HttpPostedFile oFile = Request.Files[ "NewFile" ];
+
+			string sFileName = "";
+
+			if ( oFile == null )
+			{
+				this.SendFileUploadResponse( 202, isQuickUpload );
+				return;
+			}
+
+			// Map the virtual path to the local server path.
+			string sServerDir = this.ServerMapFolder( resourceType, currentFolder, isQuickUpload );
+
+			// Get the uploaded file name.
+			sFileName = System.IO.Path.GetFileName( oFile.FileName );
+			sFileName = this.SanitizeFileName( sFileName );
+
+			string sExtension = System.IO.Path.GetExtension( oFile.FileName );
+			sExtension = sExtension.TrimStart( '.' );
+
+			if ( !this.Config.TypeConfig[ resourceType ].CheckIsAllowedExtension( sExtension ) )
+			{
+				this.SendFileUploadResponse( 202, isQuickUpload );
+				return;
+			}
+
+			if ( this.Config.CheckIsNonHtmlExtension( sExtension ) && !this.CheckNonHtmlFile( oFile ) )
+			{
+				this.SendFileUploadResponse( 202, isQuickUpload );
+				return;
+			}
+
+			int iErrorNumber = 0;
+			int iCounter = 0;
+
+			while ( true )
+			{
+				string sFilePath = System.IO.Path.Combine( sServerDir, sFileName );
+
+				if ( System.IO.File.Exists( sFilePath ) )
+				{
+					iCounter++;
+					sFileName =
+						System.IO.Path.GetFileNameWithoutExtension( oFile.FileName ) +
+						"(" + iCounter + ")." +
+						sExtension;
+
+					iErrorNumber = 201;
+				}
+				else
+				{
+					oFile.SaveAs( sFilePath );
+					break;
+				}
+			}
+
+			TypeConfig typeConfig = this.Config.TypeConfig[resourceType] ;
+
+			string sFileUrl = isQuickUpload ? typeConfig.GetQuickUploadPath() : typeConfig.GetFilesPath() ;
+			sFileUrl += sFileName;
+
+			this.SendFileUploadResponse( iErrorNumber, isQuickUpload, sFileUrl, sFileName );
+		}
+
+		private void SendFileUploadResponse( int errorNumber, bool isQuickUpload )
+		{
+			this.SendFileUploadResponse( errorNumber, isQuickUpload, "", "", "" );
+		}
+
+		private void SendFileUploadResponse( int errorNumber, bool isQuickUpload, string fileUrl, string fileName )
+		{
+			this.SendFileUploadResponse( errorNumber, isQuickUpload, fileUrl, fileName, "" );
+		}
+
+		protected void SendFileUploadResponse( int errorNumber, bool isQuickUpload, string fileUrl, string fileName, string customMsg )
+		{
+			Response.Clear();
+
+			Response.Write( "<script type=\"text/javascript\">" );
+
+			if ( isQuickUpload )
+				Response.Write( "window.parent.OnUploadCompleted(" + errorNumber + ",'" + fileUrl.Replace( "'", "\\'" ) + "','" + fileName.Replace( "'", "\\'" ) + "','" + customMsg.Replace( "'", "\\'" ) + "') ;" );
+			else
+				Response.Write( "window.parent.frames['frmUpload'].OnUploadCompleted(" + errorNumber + ",'" + fileName.Replace( "'", "\\'" ) + "') ;" );
+
+			Response.Write( "</script>" );
+
+			Response.End();
+		}
+
+		protected string ServerMapFolder( string resourceType, string folderPath, bool isQuickUpload )
+		{
+			TypeConfig typeConfig = this.Config.TypeConfig[ resourceType ];
+
+			// Get the resource type directory.
+			string sResourceTypePath = isQuickUpload ? typeConfig.GetQuickUploadDirectory() : typeConfig.GetFilesDirectory();
+
+			// Ensure that the directory exists.
+			Util.CreateDirectory( sResourceTypePath );
+
+			// Return the resource type directory combined with the required path.
+			return System.IO.Path.Combine( sResourceTypePath, folderPath.TrimStart( '/' ) );
+		}
+
+
+		// Do a cleanup of the folder name to avoid possible problems
+		protected string SanitizeFolderName( string folderName )
+		{
+			// Remove . \ / | : ? * " < >
+			return Regex.Replace( folderName, @"[.\\/|:?*""<>]", "_", RegexOptions.None );
+		}
+
+		// Do a cleanup of the file name to avoid possible problems
+		private string SanitizeFileName( string fileName )
+		{
+			// Replace dots in the name with underscores (only one dot can be there... security issue).
+			if ( Config.ForceSingleExtension )
+				fileName = Regex.Replace( fileName, @"\.(?![^.]*$)", "_", RegexOptions.None );
+
+			// Remove \ / | : ? * " < >
+			return Regex.Replace( fileName, @"[\\/|:?*""<>]", "_", RegexOptions.None );
+		}
+
+		private bool CheckNonHtmlFile( HttpPostedFile file )
+		{
+			byte[] buffer = new byte[ 1024 ];
+			file.InputStream.Read( buffer, 0, 1024 );
+
+			string firstKB = System.Text.ASCIIEncoding.ASCII.GetString( buffer );
+
+			if ( Regex.IsMatch( firstKB, @"<!DOCTYPE\W*X?HTML", RegexOptions.IgnoreCase | RegexOptions.Singleline ) )
+				return false;
+
+			if ( Regex.IsMatch( firstKB, @"<(?:body|head|html|img|pre|script|table|title)", RegexOptions.IgnoreCase | RegexOptions.Singleline ) )
+				return false;
+
+			//type = javascript
+			if ( Regex.IsMatch( firstKB, @"type\s*=\s*[\'""]?\s*(?:\w*/)?(?:ecma|java)", RegexOptions.IgnoreCase | RegexOptions.Singleline ) )
+				return false;
+
+			//href = javascript
+			//src = javascript
+			//data = javascript
+			if ( Regex.IsMatch( firstKB, @"(?:href|src|data)\s*=\s*[\'""]?\s*(?:ecma|java)script:", RegexOptions.IgnoreCase | RegexOptions.Singleline ) )
+				return false;
+
+			//url(javascript
+			if ( Regex.IsMatch( firstKB, @"url\s*\(\s*[\'""]?\s*(?:ecma|java)script:", RegexOptions.IgnoreCase | RegexOptions.Singleline ) )
+				return false;
+
+			return true;
+		}
+	}
+}
Index: /FCKeditor.Net/trunk/FileBrowser/TypeConfig.cs
===================================================================
--- /FCKeditor.Net/trunk/FileBrowser/TypeConfig.cs	(revision 1202)
+++ /FCKeditor.Net/trunk/FileBrowser/TypeConfig.cs	(revision 1202)
@@ -0,0 +1,117 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ */
+
+using System;
+
+namespace FredCK.FCKeditorV2.FileBrowser
+{
+	public class TypeConfig
+	{
+		private FileWorkerBase _FileWorker;
+
+		public string[] AllowedExtensions;
+		public string[] DeniedExtensions;
+		public string FilesPath;
+		public string FilesAbsolutePath;
+		public string QuickUploadPath;
+		public string QuickUploadAbsolutePath;
+
+		private string _UserFilesPath;
+		private string _UserFilesDirectory;
+
+		private string _QuickUploadPath;
+		private string _QuickUploadDirectory;
+
+		public TypeConfig( FileWorkerBase fileWorker )
+		{
+			_FileWorker = fileWorker;
+
+			AllowedExtensions = new string[ 0 ];
+			DeniedExtensions = new string[ 0 ];
+			FilesPath = "";
+			FilesAbsolutePath = "";
+			QuickUploadPath = "";
+			QuickUploadAbsolutePath = "";
+		}
+
+		private FileWorkerBase FileWorker
+		{
+			get { return _FileWorker; }
+		}
+
+		internal string GetFilesPath()
+		{
+			if ( _UserFilesPath == null )
+				_UserFilesPath = FilesPath.Replace( "%UserFilesPath%", this.FileWorker.Config.UserFilesPath );
+
+			return _UserFilesPath;
+		}
+
+		internal string GetFilesDirectory()
+		{
+			if ( _UserFilesDirectory == null )
+			{
+				if ( this.FilesAbsolutePath.Length == 0 )
+					_UserFilesDirectory = System.Web.HttpContext.Current.Server.MapPath( this.GetFilesPath() );
+				else
+					_UserFilesDirectory = FilesAbsolutePath.Replace( "%UserFilesAbsolutePath%", this.FileWorker.Config.UserFilesDirectory );
+			}
+
+			return _UserFilesDirectory;
+		}
+
+		internal string GetQuickUploadPath()
+		{
+			if ( _QuickUploadPath == null )
+				_QuickUploadPath = QuickUploadPath.Replace( "%UserFilesPath%", this.FileWorker.Config.UserFilesPath );
+
+			return _QuickUploadPath;
+		}
+
+		internal string GetQuickUploadDirectory()
+		{
+			if ( _QuickUploadDirectory == null )
+			{
+				if ( this.QuickUploadAbsolutePath.Length == 0 )
+					_QuickUploadDirectory = System.Web.HttpContext.Current.Server.MapPath( this.GetQuickUploadPath() );
+				else
+					_QuickUploadDirectory = QuickUploadAbsolutePath.Replace( "%UserFilesAbsolutePath%", this.FileWorker.Config.UserFilesDirectory );
+			}
+
+			return _QuickUploadDirectory;
+		}
+
+		internal bool CheckIsAllowedExtension( string extension )
+		{
+			// Do not accept empty settings.
+			if ( AllowedExtensions.Length == 0 && DeniedExtensions.Length == 0 )
+				return false;
+
+			if ( DeniedExtensions.Length > 0 && !Util.ArrayContains( DeniedExtensions, extension, System.Collections.CaseInsensitiveComparer.DefaultInvariant ) )
+				return false;
+
+			if ( AllowedExtensions.Length > 0 && !Util.ArrayContains( AllowedExtensions, extension, System.Collections.CaseInsensitiveComparer.DefaultInvariant ) )
+				return false;
+
+			return true;
+		}
+	}
+}
Index: /FCKeditor.Net/trunk/FileBrowser/TypeConfigList.cs
===================================================================
--- /FCKeditor.Net/trunk/FileBrowser/TypeConfigList.cs	(revision 1202)
+++ /FCKeditor.Net/trunk/FileBrowser/TypeConfigList.cs	(revision 1202)
@@ -0,0 +1,49 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ */
+
+using System;
+
+namespace FredCK.FCKeditorV2.FileBrowser
+{
+	public class TypeConfigList
+	{
+		private FileWorkerBase _FileWorker;
+		private System.Collections.Hashtable _Types;
+
+		public TypeConfigList( FileWorkerBase fileWorker )
+		{
+			_FileWorker = fileWorker;
+
+			_Types = new System.Collections.Hashtable( 4 );
+		}
+
+		public TypeConfig this[ string typeName ]
+		{
+			get
+			{
+				if ( !_Types.Contains( typeName ) )
+					_Types[ typeName ] = new TypeConfig( _FileWorker );
+
+				return (TypeConfig)_Types[ typeName ];
+			}
+		}
+	}
+}
Index: /FCKeditor.Net/trunk/FileBrowser/Uploader.cs
===================================================================
--- /FCKeditor.Net/trunk/FileBrowser/Uploader.cs	(revision 1202)
+++ /FCKeditor.Net/trunk/FileBrowser/Uploader.cs	(revision 1202)
@@ -0,0 +1,61 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This is the code behind of the uploader.aspx page used for Quick Uploads.
+ */
+
+using System ;
+using System.Globalization ;
+using System.Xml ;
+using System.Web ;
+
+namespace FredCK.FCKeditorV2.FileBrowser
+{
+	public class Uploader : FileWorkerBase
+	{
+		protected override void OnLoad(EventArgs e)
+		{
+			this.Config.LoadConfig();
+
+			if ( !Config.Enabled )
+			{
+				this.SendFileUploadResponse( 1, true, "", "", "This connector is disabled. Please check the \"editor/filemanager/connectors/aspx/config.aspx\" file." );
+				return;
+			}
+
+			string sResourceType = Request.QueryString[ "Type" ];
+
+			if ( sResourceType == null )
+			{
+				this.SendFileUploadResponse( 1, true, "", "", "Invalid request." );
+				return;
+			}
+
+			// Check if it is an allowed type.
+			if ( !Config.CheckIsTypeAllowed( sResourceType ) )
+			{
+				this.SendFileUploadResponse( 1, true, "", "", "Invalid resource type specified." );
+				return;
+			}
+
+			this.FileUpload( sResourceType, "/", true );
+		}
+	}
+}
Index: /FCKeditor.Net/trunk/FileBrowser/XmlResponseHandler.cs
===================================================================
--- /FCKeditor.Net/trunk/FileBrowser/XmlResponseHandler.cs	(revision 1202)
+++ /FCKeditor.Net/trunk/FileBrowser/XmlResponseHandler.cs	(revision 1202)
@@ -0,0 +1,117 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ */
+
+using System;
+using System.Web;
+using System.Xml;
+
+namespace FredCK.FCKeditorV2.FileBrowser
+{
+	class XmlResponseHandler
+	{
+		private Connector _Connector;
+		private HttpResponse _Response;
+		private XmlDocument _Xml;
+
+		internal XmlResponseHandler( Connector connector, HttpResponse response )
+		{
+			_Connector = connector;
+			_Response = response;
+		}
+
+		private HttpResponse Response
+		{
+			get { return _Response; }
+		}
+
+		private Connector Connector
+		{
+			get { return _Connector; }
+		}
+
+		private XmlDocument Xml
+		{
+			get
+			{
+				if ( _Xml == null )
+					_Xml = new XmlDocument();
+				
+				return _Xml;
+			}
+		}
+
+		public XmlNode CreateBaseXml( string command, string resourceType, string currentFolder )
+		{
+			// Create the XML document header.
+			Xml.AppendChild( Xml.CreateXmlDeclaration( "1.0", "utf-8", null ) );
+
+			// Create the main "Connector" node.
+			XmlNode oConnectorNode = XmlUtil.AppendElement( Xml, "Connector" );
+			XmlUtil.SetAttribute( oConnectorNode, "command", command );
+			XmlUtil.SetAttribute( oConnectorNode, "resourceType", resourceType );
+
+			// Add the current folder node.
+			XmlNode oCurrentNode = XmlUtil.AppendElement( oConnectorNode, "CurrentFolder" );
+			XmlUtil.SetAttribute( oCurrentNode, "path", currentFolder );
+			XmlUtil.SetAttribute( oCurrentNode, "url", Connector.GetUrlFromPath( resourceType, currentFolder ) );
+
+			return oConnectorNode;
+		}
+
+		private void SetupResponse()
+		{
+			XmlResponseHandler.SetupResponse( this.Response );
+		}
+
+		private static void SetupResponse( HttpResponse response )
+		{
+			// Cleans the response buffer.
+			response.ClearHeaders();
+			response.Clear();
+
+			// Prevent the browser from caching the result.
+			response.CacheControl = "no-cache";
+
+			// Set the response format.
+			response.ContentEncoding = System.Text.UTF8Encoding.UTF8;
+			response.ContentType = "text/xml";
+		}
+
+		public void SendResponse()
+		{
+			SetupResponse();
+			Response.Write( Xml.OuterXml );
+			Response.End();
+		}
+
+		internal static void SendError( HttpResponse response, int errorNumber, string errorText )
+		{
+			SetupResponse( response );
+
+			response.Write( "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" ) ;
+			response.Write( "<Connector>" );
+			response.Write( "<Error number=\"" + errorNumber + "\" text=\"" + HttpUtility.HtmlEncode( errorText ) + "\" />" );
+			response.Write( "</Connector>" );
+
+			response.End() ;
+		}
+	}
+}
Index: Keditor.Net/trunk/FileBrowserConnector.cs
===================================================================
--- /FCKeditor.Net/trunk/FileBrowserConnector.cs	(revision 1201)
+++ 	(revision )
@@ -1,280 +1,0 @@
-/*
- * FCKeditor - The text editor for Internet - http://www.fckeditor.net
- * Copyright (C) 2003-2007 Frederico Caldeira Knabben
- *
- * == BEGIN LICENSE ==
- *
- * Licensed under the terms of any of the following licenses at your
- * choice:
- *
- *  - GNU General Public License Version 2 or later (the "GPL")
- *    http://www.gnu.org/licenses/gpl.html
- *
- *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
- *    http://www.gnu.org/licenses/lgpl.html
- *
- *  - Mozilla Public License Version 1.1 or later (the "MPL")
- *    http://www.mozilla.org/MPL/MPL-1.1.html
- *
- * == END LICENSE ==
- *
- * This is the code behind of the connector.aspx page used by the 
- * File Browser.
- */
-
-using System ;
-using System.Globalization ;
-using System.Xml ;
-using System.Web ;
-
-namespace FredCK.FCKeditorV2
-{
-	public class FileBrowserConnector : FileWorkerBase
-	{
-		protected override void OnLoad(EventArgs e)
-		{
-			// Get the main request informaiton.
-			string sCommand = Request.QueryString["Command"] ;
-			if ( sCommand == null ) return ;
-
-			string sResourceType = Request.QueryString["Type"] ;
-			if ( sResourceType == null ) return ;
-
-			string sCurrentFolder = Request.QueryString["CurrentFolder"] ;
-			if ( sCurrentFolder == null ) return ;
-
-			// Check the current folder syntax (must begin and start with a slash).
-			if ( ! sCurrentFolder.EndsWith( "/" ) )
-				sCurrentFolder += "/" ;
-			if ( ! sCurrentFolder.StartsWith( "/" ) )
-				sCurrentFolder = "/" + sCurrentFolder ;
-
-			// File Upload doesn't have to return XML, so it must be intercepted before anything.
-			if ( sCommand == "FileUpload" )
-			{
-				this.FileUpload( sResourceType, sCurrentFolder ) ;
-				return ;
-			}
-
-			// Cleans the response buffer.
-			Response.ClearHeaders() ;
-			Response.Clear() ;
-
-			// Prevent the browser from caching the result.
-			Response.CacheControl = "no-cache" ;
-
-			// Set the response format.
-			Response.ContentEncoding	= System.Text.UTF8Encoding.UTF8 ;
-			Response.ContentType		= "text/xml" ;
-
-			XmlDocument oXML = new XmlDocument() ;
-			XmlNode oConnectorNode = CreateBaseXml( oXML, sCommand, sResourceType, sCurrentFolder ) ;
-
-			// Execute the required command.
-			switch( sCommand )
-			{
-				case "GetFolders" :
-					this.GetFolders( oConnectorNode, sResourceType, sCurrentFolder ) ;
-					break ;
-				case "GetFoldersAndFiles" :
-					this.GetFolders( oConnectorNode, sResourceType, sCurrentFolder ) ;
-					this.GetFiles( oConnectorNode, sResourceType, sCurrentFolder ) ;
-					break ;
-				case "CreateFolder" :
-					this.CreateFolder( oConnectorNode, sResourceType, sCurrentFolder ) ;
-					break ;
-			}
-
-			// Output the resulting XML.
-			Response.Write( oXML.OuterXml ) ;
-
-			Response.End() ;
-		}
-
-		#region Base XML Creation
-
-		private XmlNode CreateBaseXml( XmlDocument xml, string command, string resourceType, string currentFolder )
-		{
-			// Create the XML document header.
-			xml.AppendChild( xml.CreateXmlDeclaration( "1.0", "utf-8", null ) ) ;
-
-			// Create the main "Connector" node.
-			XmlNode oConnectorNode = XmlUtil.AppendElement( xml, "Connector" ) ;
-			XmlUtil.SetAttribute( oConnectorNode, "command", command ) ;
-			XmlUtil.SetAttribute( oConnectorNode, "resourceType", resourceType ) ;
-
-			// Add the current folder node.
-			XmlNode oCurrentNode = XmlUtil.AppendElement( oConnectorNode, "CurrentFolder" ) ;
-			XmlUtil.SetAttribute( oCurrentNode, "path", currentFolder ) ;
-			XmlUtil.SetAttribute( oCurrentNode, "url", GetUrlFromPath( resourceType, currentFolder) ) ;
-
-			return oConnectorNode ;
-		}
-
-		#endregion
-
-		#region Command Handlers
-
-		private void GetFolders( XmlNode connectorNode, string resourceType, string currentFolder )
-		{
-			// Map the virtual path to the local server path.
-			string sServerDir = this.ServerMapFolder( resourceType, currentFolder ) ;
-
-			// Create the "Folders" node.
-			XmlNode oFoldersNode = XmlUtil.AppendElement( connectorNode, "Folders" ) ;
-
-			System.IO.DirectoryInfo oDir = new System.IO.DirectoryInfo( sServerDir ) ;
-			System.IO.DirectoryInfo[] aSubDirs = oDir.GetDirectories() ;
-
-			for ( int i = 0 ; i < aSubDirs.Length ; i++ )
-			{
-				// Create the "Folders" node.
-				XmlNode oFolderNode = XmlUtil.AppendElement( oFoldersNode, "Folder" ) ;
-				XmlUtil.SetAttribute( oFolderNode, "name", aSubDirs[i].Name ) ;
-			}
-		}
-
-		private void GetFiles( XmlNode connectorNode, string resourceType, string currentFolder )
-		{
-			// Map the virtual path to the local server path.
-			string sServerDir = this.ServerMapFolder( resourceType, currentFolder ) ;
-
-			// Create the "Files" node.
-			XmlNode oFilesNode = XmlUtil.AppendElement( connectorNode, "Files" ) ;
-
-			System.IO.DirectoryInfo oDir = new System.IO.DirectoryInfo( sServerDir ) ;
-			System.IO.FileInfo[] aFiles = oDir.GetFiles() ;
-
-			for ( int i = 0 ; i < aFiles.Length ; i++ )
-			{
-				Decimal iFileSize = Math.Round( (Decimal)aFiles[i].Length / 1024 ) ;
-				if ( iFileSize < 1 && aFiles[i].Length != 0 ) iFileSize = 1 ;
-
-				// Create the "File" node.
-				XmlNode oFileNode = XmlUtil.AppendElement( oFilesNode, "File" ) ;
-				XmlUtil.SetAttribute( oFileNode, "name", aFiles[i].Name ) ;
-				XmlUtil.SetAttribute( oFileNode, "size", iFileSize.ToString( CultureInfo.InvariantCulture ) ) ;
-			}
-		}
-
-		private void CreateFolder( XmlNode connectorNode, string resourceType, string currentFolder )
-		{
-			string sErrorNumber = "0" ;
-
-			string sNewFolderName = Request.QueryString["NewFolderName"] ;
-
-			if ( sNewFolderName == null || sNewFolderName.Length == 0 )
-				sErrorNumber = "102" ;
-			else
-			{
-				// Map the virtual path to the local server path of the current folder.
-				string sServerDir = this.ServerMapFolder( resourceType, currentFolder ) ;
-
-				try
-				{
-					Util.CreateDirectory( System.IO.Path.Combine( sServerDir, sNewFolderName )) ;
-				}
-				catch ( ArgumentException )
-				{
-					sErrorNumber = "102" ;
-				}
-				catch ( System.IO.PathTooLongException )
-				{
-					sErrorNumber = "102" ;
-				}
-				catch ( System.IO.IOException )
-				{
-					sErrorNumber = "101" ;
-				}
-				catch ( System.Security.SecurityException )
-				{
-					sErrorNumber = "103" ;
-				}
-				catch ( Exception )
-				{
-					sErrorNumber = "110" ;
-				}
-			}
-
-			// Create the "Error" node.
-			XmlNode oErrorNode = XmlUtil.AppendElement( connectorNode, "Error" ) ;
-			XmlUtil.SetAttribute( oErrorNode, "number", sErrorNumber ) ;
-		}
-
-		private void FileUpload( string resourceType, string currentFolder )
-		{
-			HttpPostedFile oFile = Request.Files["NewFile"] ;
-
-			string sErrorNumber = "0" ;
-			string sFileName = "" ;
-
-			if ( oFile != null )
-			{
-				// Map the virtual path to the local server path.
-				string sServerDir = this.ServerMapFolder( resourceType, currentFolder ) ;
-
-				// Get the uploaded file name.
-				sFileName = System.IO.Path.GetFileName( oFile.FileName ) ;
-
-				int iCounter = 0 ;
-
-				while ( true )
-				{
-					string sFilePath = System.IO.Path.Combine( sServerDir, sFileName ) ;
-
-					if ( System.IO.File.Exists( sFilePath ) )
-					{
-						iCounter++ ;
-						sFileName = 
-							System.IO.Path.GetFileNameWithoutExtension( oFile.FileName ) +
-							"(" + iCounter + ")" +
-							System.IO.Path.GetExtension( oFile.FileName ) ;
-
-						sErrorNumber = "201" ;
-					}
-					else
-					{
-						oFile.SaveAs( sFilePath ) ;
-						break ;
-					}
-				}
-			}
-			else
-				sErrorNumber = "202" ;
-
-			Response.Clear() ;
-
-			Response.Write( "<script type=\"text/javascript\">" ) ;
-			Response.Write( "window.parent.frames['frmUpload'].OnUploadCompleted(" + sErrorNumber + ",'" + sFileName.Replace( "'", "\\'" ) + "') ;" ) ;
-			Response.Write( "</script>" ) ;
-
-			Response.End() ;
-		}
-
-		#endregion
-
-		#region Directory Mapping
-
-		private string ServerMapFolder( string resourceType, string folderPath )
-		{
-			// Get the resource type directory.
-			string sResourceTypePath = System.IO.Path.Combine( this.UserFilesDirectory, resourceType ) ;
-
-			// Ensure that the directory exists.
-			Util.CreateDirectory( sResourceTypePath ) ;
-
-			// Return the resource type directory combined with the required path.
-			return System.IO.Path.Combine( sResourceTypePath, folderPath.TrimStart('/') ) ;
-		}
-
-		private string GetUrlFromPath( string resourceType, string folderPath )
-		{
-			if ( resourceType == null || resourceType.Length == 0 )
-				return this.UserFilesPath.TrimEnd('/') + folderPath ;
-			else
-				return this.UserFilesPath + resourceType + folderPath ;
-		}
-
-		#endregion
-	}
-}
Index: Keditor.Net/trunk/FileWorkerBase.cs
===================================================================
--- /FCKeditor.Net/trunk/FileWorkerBase.cs	(revision 1201)
+++ 	(revision )
@@ -1,87 +1,0 @@
-/*
- * FCKeditor - The text editor for Internet - http://www.fckeditor.net
- * Copyright (C) 2003-2007 Frederico Caldeira Knabben
- *
- * == BEGIN LICENSE ==
- *
- * Licensed under the terms of any of the following licenses at your
- * choice:
- *
- *  - GNU General Public License Version 2 or later (the "GPL")
- *    http://www.gnu.org/licenses/gpl.html
- *
- *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
- *    http://www.gnu.org/licenses/lgpl.html
- *
- *  - Mozilla Public License Version 1.1 or later (the "MPL")
- *    http://www.mozilla.org/MPL/MPL-1.1.html
- *
- * == END LICENSE ==
- *
- * Base class used by the FileBrowserConnector and Uploader.
- */
-
-using System;
-
-namespace FredCK.FCKeditorV2
-{
-	public abstract class FileWorkerBase : System.Web.UI.Page
-	{
-		private const string DEFAULT_USER_FILES_PATH = "/userfiles/" ;
-
-		private string sUserFilesPath ;
-		private string sUserFilesDirectory ;
-
-		protected string UserFilesPath
-		{
-			get
-			{
-				if ( sUserFilesPath == null )
-				{
-					// Try to get from the "Application".
-					sUserFilesPath = (string)Application["FCKeditor:UserFilesPath"] ;
-
-					// Try to get from the "Session".
-					if ( sUserFilesPath == null || sUserFilesPath.Length == 0 )
-					{
-						sUserFilesPath = (string)Session["FCKeditor:UserFilesPath"] ;
-						
-						// Try to get from the Web.config file.
-						if ( sUserFilesPath == null || sUserFilesPath.Length == 0 )
-						{
-							sUserFilesPath = System.Configuration.ConfigurationSettings.AppSettings["FCKeditor:UserFilesPath"] ;
-							
-							// Otherwise use the default value.
-							if ( sUserFilesPath == null || sUserFilesPath.Length == 0 ) 
-								sUserFilesPath = DEFAULT_USER_FILES_PATH ;
-						}
-					}
-
-					// Check that the user path ends with slash ("/")
-					if ( ! sUserFilesPath.EndsWith("/") )
-						sUserFilesPath += "/" ;
-
-					sUserFilesPath = this.ResolveUrl( sUserFilesPath ) ;
-				}
-				return sUserFilesPath ;
-			}
-		}
-
-		/// <summary>
-		/// The absolution path (server side) of the user files directory. It 
-		/// is based on the <see cref="FileWorkerBase.UserFilesPath"/>.
-		/// </summary>
-		protected string UserFilesDirectory
-		{
-			get	
-			{
-				if ( sUserFilesDirectory == null )
-				{
-					// Get the local (server) directory path translation.
-					sUserFilesDirectory = Server.MapPath( this.UserFilesPath ) ;
-				}
-				return sUserFilesDirectory ;
-			}
-		}
-	}
-}
Index: /FCKeditor.Net/trunk/FredCK.FCKeditorV2.vs2003.csproj
===================================================================
--- /FCKeditor.Net/trunk/FredCK.FCKeditorV2.vs2003.csproj	(revision 1201)
+++ /FCKeditor.Net/trunk/FredCK.FCKeditorV2.vs2003.csproj	(revision 1202)
@@ -108,8 +108,4 @@
                 />
                 <File
-                    RelPath = "_license.txt"
-                    BuildAction = "Content"
-                />
-                <File
                     RelPath = "_whatsnew.html"
                     BuildAction = "Content"
@@ -136,19 +132,4 @@
                 />
                 <File
-                    RelPath = "FileBrowserConnector.cs"
-                    SubType = "ASPXCodeBehind"
-                    BuildAction = "Compile"
-                />
-                <File
-                    RelPath = "FileWorkerBase.cs"
-                    SubType = "ASPXCodeBehind"
-                    BuildAction = "Compile"
-                />
-                <File
-                    RelPath = "Uploader.cs"
-                    SubType = "ASPXCodeBehind"
-                    BuildAction = "Compile"
-                />
-                <File
                     RelPath = "Util.cs"
                     SubType = "Code"
@@ -160,4 +141,39 @@
                     BuildAction = "Compile"
                 />
+                <File
+                    RelPath = "FileBrowser\Config.cs"
+                    SubType = "ASPXCodeBehind"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "FileBrowser\Connector.cs"
+                    SubType = "ASPXCodeBehind"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "FileBrowser\FileWorkerBase.cs"
+                    SubType = "ASPXCodeBehind"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "FileBrowser\TypeConfig.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "FileBrowser\TypeConfigList.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "FileBrowser\Uploader.cs"
+                    SubType = "ASPXCodeBehind"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "FileBrowser\XmlResponseHandler.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
             </Include>
         </Files>
Index: /FCKeditor.Net/trunk/FredCK.FCKeditorV2.vs2005.csproj
===================================================================
--- /FCKeditor.Net/trunk/FredCK.FCKeditorV2.vs2005.csproj	(revision 1201)
+++ /FCKeditor.Net/trunk/FredCK.FCKeditorV2.vs2005.csproj	(revision 1202)
@@ -111,11 +111,16 @@
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="FileBrowserConnector.cs">
+    <Compile Include="FileBrowser\Config.cs">
       <SubType>ASPXCodeBehind</SubType>
     </Compile>
-    <Compile Include="FileWorkerBase.cs">
+    <Compile Include="FileBrowser\Connector.cs">
       <SubType>ASPXCodeBehind</SubType>
     </Compile>
-    <Compile Include="Uploader.cs">
+    <Compile Include="FileBrowser\TypeConfig.cs" />
+    <Compile Include="FileBrowser\TypeConfigList.cs" />
+    <Compile Include="FileBrowser\FileWorkerBase.cs">
+      <SubType>ASPXCodeBehind</SubType>
+    </Compile>
+    <Compile Include="FileBrowser\Uploader.cs">
       <SubType>ASPXCodeBehind</SubType>
     </Compile>
@@ -123,4 +128,5 @@
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="FileBrowser\XmlResponseHandler.cs" />
     <Compile Include="XmlUtil.cs">
       <SubType>Code</SubType>
Index: Keditor.Net/trunk/Uploader.cs
===================================================================
--- /FCKeditor.Net/trunk/Uploader.cs	(revision 1201)
+++ 	(revision )
@@ -1,104 +1,0 @@
-/*
- * FCKeditor - The text editor for Internet - http://www.fckeditor.net
- * Copyright (C) 2003-2007 Frederico Caldeira Knabben
- *
- * == BEGIN LICENSE ==
- *
- * Licensed under the terms of any of the following licenses at your
- * choice:
- *
- *  - GNU General Public License Version 2 or later (the "GPL")
- *    http://www.gnu.org/licenses/gpl.html
- *
- *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
- *    http://www.gnu.org/licenses/lgpl.html
- *
- *  - Mozilla Public License Version 1.1 or later (the "MPL")
- *    http://www.mozilla.org/MPL/MPL-1.1.html
- *
- * == END LICENSE ==
- *
- * This is the code behind of the uploader.aspx page used for Quick Uploads.
- */
-
-using System ;
-using System.Globalization ;
-using System.Xml ;
-using System.Web ;
-
-namespace FredCK.FCKeditorV2
-{
-	public class Uploader : FileWorkerBase
-	{
-		protected override void OnLoad(EventArgs e)
-		{
-			// Get the posted file.
-			HttpPostedFile oFile = Request.Files["NewFile"] ;
-
-			// Check if the file has been correctly uploaded
-			if ( oFile == null || oFile.ContentLength == 0 )
-			{
-				SendResults( 202 ) ;
-				return ;
-			}
-
-			int iErrorNumber = 0 ;
-			string sFileUrl = "" ;
-
-			// Get the uploaded file name.
-			string sFileName = System.IO.Path.GetFileName( oFile.FileName ) ;
-
-			int iCounter = 0 ;
-
-			while ( true )
-			{
-				string sFilePath = System.IO.Path.Combine( this.UserFilesDirectory, sFileName ) ;
-
-				if ( System.IO.File.Exists( sFilePath ) )
-				{
-					iCounter++ ;
-					sFileName = 
-						System.IO.Path.GetFileNameWithoutExtension( oFile.FileName ) +
-						"(" + iCounter + ")" +
-						System.IO.Path.GetExtension( oFile.FileName ) ;
-
-					iErrorNumber = 201 ;
-				}
-				else
-				{
-					oFile.SaveAs( sFilePath ) ;
-
-					sFileUrl = this.UserFilesPath + sFileName ;
-					break ;
-				}
-			}
-
-			SendResults( iErrorNumber, sFileUrl, sFileName ) ;
-		}
-
-		#region SendResults Method
-
-		private void SendResults( int errorNumber )
-		{
-			SendResults( errorNumber, "", "", "" ) ;
-		}
-
-		private void SendResults( int errorNumber, string fileUrl, string fileName )
-		{
-			SendResults( errorNumber, fileUrl, fileName, "" ) ;
-		}
-
-		private void SendResults( int errorNumber, string fileUrl, string fileName, string customMsg )
-		{
-			Response.Clear() ;
-
-			Response.Write( "<script type=\"text/javascript\">" ) ;
-			Response.Write( "window.parent.OnUploadCompleted(" + errorNumber + ",'" + fileUrl.Replace( "'", "\\'" ) + "','" + fileName.Replace( "'", "\\'" ) + "','" + customMsg.Replace( "'", "\\'" ) + "') ;" ) ;
-			Response.Write( "</script>" ) ;
-
-			Response.End() ;
-		}
-
-		#endregion
-	}
-}
Index: /FCKeditor.Net/trunk/Util.cs
===================================================================
--- /FCKeditor.Net/trunk/Util.cs	(revision 1201)
+++ /FCKeditor.Net/trunk/Util.cs	(revision 1202)
@@ -29,5 +29,5 @@
 namespace FredCK.FCKeditorV2
 {
-	public sealed class Util
+	internal sealed class Util
 	{
 		// The "_mkdir" function is used by the "CreateDirectory" method.
@@ -107,4 +107,14 @@
 			}
 		}
+
+		public static bool ArrayContains( Array array, object value, System.Collections.IComparer comparer )
+		{
+			foreach ( object item in array )
+			{
+				if ( comparer.Compare( item, value ) == 0 )
+					return true;
+			}
+			return false;
+		}
 	}
 }
Index: /FCKeditor.Net/trunk/_whatsnew.html
===================================================================
--- /FCKeditor.Net/trunk/_whatsnew.html	(revision 1201)
+++ /FCKeditor.Net/trunk/_whatsnew.html	(revision 1202)
@@ -1,3 +1,3 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <!--
  * FCKeditor - The text editor for Internet - http://www.fckeditor.net
@@ -36,6 +36,6 @@
 		Version 2.5</h3>
 	<p>
-		<strong><span style="color: #ff0000">Attention :</span></strong> This version is
-		not compatible with releases before FCKeditor 2.5.</p>
+		<strong><span style="color: #ff0000">Attention :</span></strong> The File Browser
+		and Uploader in this version is not compatible with releases before FCKeditor 2.5.1.</p>
 	<p>
 		New Features and Improvements:</p>
@@ -58,7 +58,22 @@
 			setting is enforced by the editor component, to avoid having to set ValidateRequest="false"
 			on pages using the editor.</li>
-		<li><span style="color: #ff0000"><strong>Attention :</strong></span> The default connector
-			path has been changed to "/userfiles/", instead of "/UserFiles/". This change should
-			not impact Windows installations.</li>
+		<li>Several changes to the File Browser and Uploader:<ul>
+			<li>Several security checks have been introduced. <strong>Upgrading is hightly recommended</strong>.</li>
+			<li>The code has been reviewed according to our standards, aligning the FCKeditor.Net
+				File Browser to the same quality and feature level present in other server language
+				implementations of it, like the PHP implementation.</li>
+			<li>The connector can now be fully configured by using the "editor/filemanager/connectors/aspx/config.ascx"
+				file, available with FCKeditor 2.5.1.</li>
+			<li>For file uploads, the file extension is precisely controlled in a list defined in
+				the config.ascx file.</li>
+			<li>It is possible to define different folder locations for each file type.</li>
+			<li><strong><span style="color: #ff0000">Attention :</span></strong> For security, the
+				connector must be explicitly activated, by setting "Enabled = true" in the config.ascx
+				file.</li>
+			<li><span style="color: #ff0000"><strong>Attention :</strong></span> The default connector
+				path has been changed to "/userfiles/", instead of "/UserFiles/". This change should
+				not impact Windows installations.</li>
+		</ul>
+		</li>
 	</ul>
 	<p>
