From 5febc7eb9bcd17d648c254b13eb102462e4a9041 Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Wed, 10 Jun 2026 11:48:33 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E5=AE=89=E5=85=A8):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=9D=99=E6=80=81=E8=B5=84=E6=BA=90=E6=8E=A5=E5=8F=A3=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E7=A9=BF=E8=B6=8A=E3=80=81=E4=BB=BB=E6=84=8F=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=AF=BB=E5=8F=96=E5=8F=8A=E8=B5=84=E6=BA=90=E6=B3=A8?= =?UTF-8?q?=E5=85=A5=E6=BC=8F=E6=B4=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commons/utils/ExcelWatermarkUtils.java | 18 +++++- .../dataease/utils/StaticResourceUtils.java | 56 ++++++++++++++++++- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/core/core-backend/src/main/java/io/dataease/commons/utils/ExcelWatermarkUtils.java b/core/core-backend/src/main/java/io/dataease/commons/utils/ExcelWatermarkUtils.java index a11cdddfa6..2a8bc193a7 100644 --- a/core/core-backend/src/main/java/io/dataease/commons/utils/ExcelWatermarkUtils.java +++ b/core/core-backend/src/main/java/io/dataease/commons/utils/ExcelWatermarkUtils.java @@ -16,10 +16,17 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.regex.Pattern; public class ExcelWatermarkUtils { private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private static final int MAX_TEXT_LENGTH = 100; + private static final int MAX_IMAGE_WIDTH = 4096; + private static final int MAX_IMAGE_HEIGHT = 4096; + private static final Pattern IP_PATTERN = Pattern.compile( + "^([0-9]{1,3}\\.){3}[0-9]{1,3}$|^([0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}$"); + public static String transContent(WatermarkContentDTO watermarkContent, UserFormVO userInfo) { String content = ""; @@ -31,7 +38,11 @@ public class ExcelWatermarkUtils { default -> content = "${username}"; } String nickName = userInfo.getName().contains("i18n_") ?Translator.get(userInfo.getName()):userInfo.getName(); - content = content.replaceAll("\\$\\{ip}", IPUtils.get() == null ? "127.0.0.1" : IPUtils.get()); + String ip = IPUtils.get(); + if (ip == null || !IP_PATTERN.matcher(ip.trim()).matches()) { + ip = "127.0.0.1"; + } + content = content.replaceAll("\\$\\{ip}", ip); content = content.replaceAll("\\$\\{username}", userInfo.getAccount()); content = content.replaceAll("\\$\\{nickName}", nickName); content = content.replaceAll("\\$\\{time}", sdf.format(new Date())); @@ -89,9 +100,14 @@ public class ExcelWatermarkUtils { } public static byte[] createTextImage(String text, WatermarkContentDTO watermarkContent) { + if (text.length() > MAX_TEXT_LENGTH) { + text = text.substring(0, MAX_TEXT_LENGTH); + } double radians = Math.toRadians(15);// 15度偏转 int width = watermarkContent.getWatermark_fontsize() * text.length(); int height = (int) Math.round(watermarkContent.getWatermark_fontsize() + width * Math.sin(radians)); + width = Math.min(width, MAX_IMAGE_WIDTH); + height = Math.min(height, MAX_IMAGE_HEIGHT); int fontSize = watermarkContent.getWatermark_fontsize(); Color baseColor = Color.decode(watermarkContent.getWatermark_color()); diff --git a/sdk/common/src/main/java/io/dataease/utils/StaticResourceUtils.java b/sdk/common/src/main/java/io/dataease/utils/StaticResourceUtils.java index 1bb4350c7b..62801e86ee 100644 --- a/sdk/common/src/main/java/io/dataease/utils/StaticResourceUtils.java +++ b/sdk/common/src/main/java/io/dataease/utils/StaticResourceUtils.java @@ -4,10 +4,15 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.lang.NonNull; import org.springframework.util.Assert; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Base64; +import java.util.Locale; +import java.util.Set; +import java.util.regex.Pattern; import static io.dataease.constant.StaticResourceConstants.*; @@ -15,6 +20,12 @@ public class StaticResourceUtils { private final static String FILE_BASE_PATH = USER_HOME + FILE_SEPARATOR + UPLOAD_URL_PREFIX; + private static final Pattern SAFE_RESOURCE_FILE_NAME = Pattern.compile("^[A-Za-z0-9._-]+$"); + + private static final Set ALLOWED_RESOURCE_EXTENSIONS = Set.of( + ".gif", ".svg", ".png", ".jpeg", ".jpg" + ); + public static String ensureBoth(@NonNull String string, @NonNull String bothfix) { return ensureBoth(string, bothfix, bothfix); } @@ -58,12 +69,28 @@ public class StaticResourceUtils { * @return */ public static String getImgFileToBase64(String imgFile) { + if (StringUtils.isBlank(imgFile) || !SAFE_RESOURCE_FILE_NAME.matcher(imgFile).matches()) { + LogUtil.warn("Reject illegal static resource file name: " + imgFile); + return null; + } + if (!hasAllowedExtension(imgFile)) { + LogUtil.warn("Reject static resource with disallowed extension: " + imgFile); + return null; + } + Path targetPath = resolveSafeResourcePath(imgFile); + if (targetPath == null) { + return null; + } + if (!Files.isRegularFile(targetPath)) { + LogUtil.warn("Reject static resource that is not a regular file: " + imgFile); + return null; + } //Convert the picture file into byte array and encode it with Base64 InputStream inputStream = null; byte[] buffer = null; //Read picture byte array try { - inputStream = new FileInputStream(FILE_BASE_PATH + FILE_SEPARATOR + imgFile); + inputStream = Files.newInputStream(targetPath); int count = 0; while (count == 0) { count = inputStream.available(); @@ -92,4 +119,29 @@ public class StaticResourceUtils { } } + private static Path resolveSafeResourcePath(String fileName) { + try { + Path basePath = Paths.get(FILE_BASE_PATH).toAbsolutePath().normalize(); + Path targetPath = basePath.resolve(fileName).normalize(); + if (!targetPath.startsWith(basePath)) { + LogUtil.warn("Reject static resource path outside base directory: " + fileName); + return null; + } + return targetPath; + } catch (Exception e) { + LogUtil.error(e); + return null; + } + } + + private static boolean hasAllowedExtension(String fileName) { + String lower = fileName.toLowerCase(Locale.ROOT); + for (String ext : ALLOWED_RESOURCE_EXTENSIONS) { + if (lower.endsWith(ext)) { + return true; + } + } + return false; + } + }