1 /* 2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net 3 * Copyright (C) 2004-2009 Frederico Caldeira Knabben 4 * 5 * == BEGIN LICENSE == 6 * 7 * Licensed under the terms of any of the following licenses at your 8 * choice: 9 * 10 * - GNU General Public License Version 2 or later (the "GPL") 11 * http://www.gnu.org/licenses/gpl.html 12 * 13 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 14 * http://www.gnu.org/licenses/lgpl.html 15 * 16 * - Mozilla Public License Version 1.1 or later (the "MPL") 17 * http://www.mozilla.org/MPL/MPL-1.1.html 18 * 19 * == END LICENSE == 20 */ 21 package net.fckeditor.tool; 22 23 import java.io.File; 24 import java.io.InputStream; 25 26 import net.fckeditor.handlers.PropertiesLoader; 27 28 import org.apache.commons.io.FilenameUtils; 29 import org.devlib.schmidt.imageinfo.ImageInfo; 30 31 /** 32 * Static helper methods for files. 33 * 34 * @version $Id: UtilsFile.java 3695 2009-06-18 20:18:38Z mosipov $ 35 */ 36 public class UtilsFile { 37 38 /** 39 * Sanitizes a filename from certain chars.<br /> 40 * 41 * This method enforces the <code>forceSingleExtension</code> property and 42 * then replaces all occurrences of \, /, |, :, ?, *, ", <, >, 43 * control chars by _ (underscore). 44 * 45 * @param filename 46 * a potentially 'malicious' filename 47 * @return sanitized filename 48 */ 49 public static String sanitizeFileName(final String filename) { 50 51 if (Utils.isEmpty(filename)) 52 return filename; 53 54 String name = (PropertiesLoader.isForceSingleExtension()) ? UtilsFile 55 .forceSingleExtension(filename) : filename; 56 57 // Remove \ / | : ? * " < > 'Control Chars' with _ 58 return name.replaceAll("\\\\|/|\\||:|\\?|\\*|\"|<|>|\\p{Cntrl}", "_"); 59 } 60 61 /** 62 * Sanitizes a folder name from certain chars.<br /> 63 * 64 * This method replaces all occurrences of \, /, |, :, ?, *, ", <, 65 * >, control chars by _ (underscore). 66 * 67 * @param folderName 68 * a potentially 'malicious' folder name 69 * @return sanitized folder name 70 */ 71 public static String sanitizeFolderName(final String folderName) { 72 73 if (Utils.isEmpty(folderName)) 74 return folderName; 75 76 // Remove . \ / | : ? * " < > 'Control Chars' with _ 77 return folderName.replaceAll( 78 "\\.|\\\\|/|\\||:|\\?|\\*|\"|<|>|\\p{Cntrl}", "_"); 79 } 80 81 /** 82 * Checks if the underlying input stream contains an image. 83 * 84 * @param in 85 * input stream of an image 86 * @return <code>true</code> if the underlying input stream contains an 87 * image, else <code>false</code> 88 */ 89 public static boolean isImage(final InputStream in) { 90 ImageInfo ii = new ImageInfo(); 91 ii.setInput(in); 92 return ii.check(); 93 } 94 95 /** 96 * Checks whether a path complies with the FCKeditor File Browser <a href="http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Server_Side_Integration#File_Browser_Requests" 97 * target="_blank">rules</a>. 98 * 99 * @param path 100 * a potentially 'malicious' path 101 * @return <code>true</code> if path complies with the rules, else 102 * <code>false</code> 103 */ 104 public static boolean isValidPath(final String path) { 105 if (Utils.isEmpty(path)) 106 return false; 107 if (!path.startsWith("/")) 108 return false; 109 if (!path.endsWith("/")) 110 return false; 111 112 if (!path.equals(FilenameUtils.separatorsToUnix(FilenameUtils 113 .normalize(path)))) 114 return false; 115 116 return true; 117 } 118 119 /** 120 * Replaces all dots in a filename with underscores except the last one. 121 * 122 * @param filename 123 * filename to sanitize 124 * @return string with a single dot only 125 */ 126 public static String forceSingleExtension(final String filename) { 127 return filename.replaceAll("\\.(?![^.]+$)", "_"); 128 } 129 130 /** 131 * Checks if a filename contains more than one dot. 132 * 133 * @param filename 134 * filename to check 135 * @return <code>true</code> if filename contains severals dots, else 136 * <code>false</code> 137 */ 138 public static boolean isSingleExtension(final String filename) { 139 return filename.matches("[^\\.]+\\.[^\\.]+"); 140 } 141 142 /** 143 * Checks a directory for existence and creates it if non-existent. 144 * 145 * @param dir 146 * directory to check/create 147 */ 148 public static void checkDirAndCreate(File dir) { 149 if (!dir.exists()) 150 dir.mkdirs(); 151 } 152 153 /** 154 * Iterates over a base name and returns the first non-existent file.<br /> 155 * This method extracts a file's base name, iterates over it until the first 156 * non-existent appearance with <code>basename(n).ext</code>. Where n is a 157 * positive integer starting from one. 158 * 159 * @param file 160 * base file 161 * @return first non-existent file 162 */ 163 public static File getUniqueFile(final File file) { 164 if (!file.exists()) 165 return file; 166 167 File tmpFile = new File(file.getAbsolutePath()); 168 File parentDir = tmpFile.getParentFile(); 169 int count = 1; 170 String extension = FilenameUtils.getExtension(tmpFile.getName()); 171 String baseName = FilenameUtils.getBaseName(tmpFile.getName()); 172 do { 173 tmpFile = new File(parentDir, baseName + "(" + count++ + ")." 174 + extension); 175 } while (tmpFile.exists()); 176 return tmpFile; 177 } 178 }