@@ -182,7 +182,8 @@ static File inputStreamToFile(InputStream ins, String name){
182182 public static File upload (MultipartFile file , String filePath ) {
183183 Date date = new Date ();
184184 SimpleDateFormat format = new SimpleDateFormat ("yyyyMMddhhmmssS" );
185- String name = getFileNameNoEx (file .getOriginalFilename ());
185+ // 过滤非法文件名
186+ String name = getFileNameNoEx (verifyFilename (file .getOriginalFilename ()));
186187 String suffix = getExtensionName (file .getOriginalFilename ());
187188 String nowStr = "-" + format .format (date );
188189 try {
@@ -350,6 +351,44 @@ public static void downloadFile(HttpServletRequest request, HttpServletResponse
350351 }
351352 }
352353
354+ /**
355+ * 验证并过滤非法的文件名
356+ * @param fileName 文件名
357+ * @return 文件名
358+ */
359+ public static String verifyFilename (String fileName ) {
360+ // 过滤掉特殊字符
361+ fileName = fileName .replaceAll ("[\\ \\ /:*?\" <>|~\\ s]" , "" );
362+
363+ // 去掉文件名开头和结尾的空格和点
364+ fileName = fileName .trim ().replaceAll ("^[. ]+|[. ]+$" , "" );
365+
366+ // 不允许文件名超过255(在Mac和Linux中)或260(在Windows中)个字符
367+ int maxFileNameLength = 255 ;
368+ if (System .getProperty ("os.name" ).startsWith ("Windows" )) {
369+ maxFileNameLength = 260 ;
370+ }
371+ if (fileName .length () > maxFileNameLength ) {
372+ fileName = fileName .substring (0 , maxFileNameLength );
373+ }
374+
375+ // 过滤掉控制字符
376+ fileName = fileName .replaceAll ("[\\ p{Cntrl}]" , "" );
377+
378+ // 过滤掉 ".." 路径
379+ fileName = fileName .replaceAll ("\\ .{2,}" , "" );
380+
381+ // 去掉文件名开头的 ".."
382+ fileName = fileName .replaceAll ("^\\ .+/" , "" );
383+
384+ // 保留文件名中最后一个 "." 字符,过滤掉其他 "."
385+ fileName = fileName .replaceAll ("^(.*)(\\ .[^.]*)$" , "$1" ).replaceAll ("\\ ." , "" ) +
386+ fileName .replaceAll ("^(.*)(\\ .[^.]*)$" , "$2" );
387+
388+ return fileName ;
389+ }
390+
391+
353392 public static String getMd5 (File file ) {
354393 return getMd5 (getByte (file ));
355394 }
0 commit comments