Explorar el Código

修复加号被转换成空格导致Base64解码出错 (#340)

* 修复url中加号被替换为空格导致的Base64解码出错

* Base64解码抽象到工具类

* #340 补充注释
gkchp hace 2 años
padre
commit
35a8c4a5a6

+ 31 - 4
server/src/main/java/cn/keking/utils/WebUtils.java

@@ -9,6 +9,7 @@ import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLEncoder;
+import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
@@ -156,22 +157,48 @@ public class WebUtils {
         String currentUrl = request.getParameter("currentUrl");
         String urlPath = request.getParameter("urlPath");
         if (StringUtils.isNotBlank(url)) {
-            return new String(Base64Utils.decodeFromString(url), StandardCharsets.UTF_8);
+            return decodeBase64String(url);
         }
         if (StringUtils.isNotBlank(currentUrl)) {
-            return new String(Base64Utils.decodeFromString(currentUrl), StandardCharsets.UTF_8);
+            return decodeBase64String(currentUrl);
         }
         if (StringUtils.isNotBlank(urlPath)) {
-            return new String(Base64Utils.decodeFromString(urlPath), StandardCharsets.UTF_8);
+            return decodeBase64String(urlPath);
         }
         if (StringUtils.isNotBlank(urls)) {
-            urls = new String(Base64Utils.decodeFromString(urls), StandardCharsets.UTF_8);
+            urls = decodeBase64String(urls);
             String[] images = urls.split("\\|");
             return images[0];
         }
         return null;
     }
 
+    /**
+     * 将 Base64 字符串解码,默认使用 UTF-8
+     * @param source 原始 Base64 字符串
+     * @return decoded string
+     */
+    public static String decodeBase64String(String source) {
+        return decodeBase64String(source, StandardCharsets.UTF_8);
+    }
+
+    /**
+     * 将 Base64 字符串使用指定字符集解码
+     * @param source 原始 Base64 字符串
+     * @param charsets 字符集
+     * @return decoded string
+     */
+    public static String decodeBase64String(String source, Charset charsets) {
+        /*
+         * url 传入的参数里加号会被替换成空格,导致解析出错,这里需要把空格替换回加号
+         * 有些 Base64 实现可能每 76 个字符插入换行符,也一并去掉
+         * https://github.com/kekingcn/kkFileView/pull/340
+         */
+        return new String(Base64Utils.decodeFromString(
+                source.replaceAll(" ", "+").replaceAll("\n", "")
+        ), charsets);
+    }
+
     /**
      * 获取 url 的 host
      * @param urlStr url

+ 3 - 3
server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java

@@ -56,7 +56,7 @@ public class OnlinePreviewController {
     public String onlinePreview(String url, Model model, HttpServletRequest req) {
         String fileUrl;
         try {
-            fileUrl = new String(Base64.decodeBase64(url), StandardCharsets.UTF_8);
+            fileUrl = WebUtils.decodeBase64String(url);
         } catch (Exception ex) {
             String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "url");
             return otherFilePreview.notSupportedFile(model, errorMsg);
@@ -72,7 +72,7 @@ public class OnlinePreviewController {
     public String picturesPreview(String urls, Model model, HttpServletRequest req) throws UnsupportedEncodingException {
         String fileUrls;
         try {
-            fileUrls = new String(Base64.decodeBase64(urls));
+            fileUrls = WebUtils.decodeBase64String(urls);
             // 防止XSS攻击
             fileUrls = HtmlUtils.htmlEscape(fileUrls);
         } catch (Exception ex) {
@@ -106,7 +106,7 @@ public class OnlinePreviewController {
     @GetMapping("/getCorsFile")
     public void getCorsFile(String urlPath, HttpServletResponse response) {
         try {
-            urlPath = new String(Base64.decodeBase64(urlPath), StandardCharsets.UTF_8);
+            urlPath = WebUtils.decodeBase64String(urlPath);
         } catch (Exception ex) {
             logger.error(String.format(BASE64_DECODE_ERROR_MSG, urlPath),ex);
             return;