From 35a8c4a5a66a3a6ec47e4320b22637b032095bc9 Mon Sep 17 00:00:00 2001 From: gkchp Date: Fri, 29 Jul 2022 23:08:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8A=A0=E5=8F=B7=E8=A2=AB?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E6=88=90=E7=A9=BA=E6=A0=BC=E5=AF=BC=E8=87=B4?= =?UTF-8?q?Base64=E8=A7=A3=E7=A0=81=E5=87=BA=E9=94=99=20(#340)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修复url中加号被替换为空格导致的Base64解码出错 * Base64解码抽象到工具类 * #340 补充注释 --- .../main/java/cn/keking/utils/WebUtils.java | 35 ++++++++++++++++--- .../controller/OnlinePreviewController.java | 6 ++-- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/cn/keking/utils/WebUtils.java b/server/src/main/java/cn/keking/utils/WebUtils.java index 38472eaf..5b04067a 100644 --- a/server/src/main/java/cn/keking/utils/WebUtils.java +++ b/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 diff --git a/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java b/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java index 0855dca0..c2d09264 100644 --- a/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java +++ b/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;