From 6c843c403026b26a7774f9d8483c4e1962c4399e Mon Sep 17 00:00:00 2001 From: database-mysql Date: Mon, 2 Nov 2026 09:56:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=B4=A8=E9=87=8F?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E5=9C=A8=20Java=2021=20=E4=B8=8B=E4=B8=8D?= =?UTF-8?q?=E5=8F=AF=E7=94=A8=EF=BC=8C=E5=B9=B6=E4=BF=AE=E5=A4=8D=20SpotBu?= =?UTF-8?q?gs=20=E5=8F=91=E7=8E=B0=E7=9A=84=E7=A9=BA=E6=8C=87=E9=92=88?= =?UTF-8?q?=E9=A3=8E=E9=99=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - checkstyle: 升级至 3.6.0,新增 checkstyle.xml 基础规则,绑定 verify 阶段 - findbugs: 替换为 spotbugs-maven-plugin 4.8.6.6(FindBugs 已停止维护且无法解析 Java 21 字节码), 绑定 verify 阶段,新增 spotbugs-exclude.xml 排除遗留命名等检查 - javadoc: 升级至 3.12.0(3.12.1 在中央仓库不存在),禁用 doclint - 修复 SpotBugs 发现的问题:压缩/解压方法中 getFileName()/getParent() 可能为 null 的防御, 共享 SecureRandom 实例避免重复创建 --- checkstyle.xml | 28 ++++++++++++++ pom.xml | 38 ++++++++++++++++--- spotbugs-exclude.xml | 26 +++++++++++++ .../library/utils/compress/compress.java | 24 ++++++++++-- .../utils/file/EncryptionAndDecryption.java | 10 ++++- 5 files changed, 115 insertions(+), 11 deletions(-) create mode 100644 checkstyle.xml create mode 100644 spotbugs-exclude.xml diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 0000000..a1c8b92 --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index d0617e2..a5c1e73 100644 --- a/pom.xml +++ b/pom.xml @@ -68,25 +68,53 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.2 + 3.6.0 checkstyle.xml + UTF-8 + true + + + checkstyle-check + verify + + check + + + - org.codehaus.mojo - findbugs-maven-plugin - 3.0.5 + com.github.spotbugs + spotbugs-maven-plugin + 4.8.6.6 + + Max + Medium + true + true + spotbugs-exclude.xml + + + + spotbugs-check + verify + + check + + + org.apache.maven.plugins maven-javadoc-plugin - 3.3.0 + 3.12.0 private true + none diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml new file mode 100644 index 0000000..cb20c5b --- /dev/null +++ b/spotbugs-exclude.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/compress/compress.java b/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/compress/compress.java index 13e8ac7..bb17cc8 100644 --- a/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/compress/compress.java +++ b/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/compress/compress.java @@ -52,7 +52,11 @@ public class compress { if (entry.isDirectory()) { Files.createDirectories(targetPath); } else { - Files.createDirectories(targetPath.getParent()); + Path parent = targetPath.getParent(); + if (parent == null) { + throw new IllegalArgumentException("无法确定条目父目录: " + entry.getName()); + } + Files.createDirectories(parent); Files.copy(tarIn, targetPath); } } @@ -115,7 +119,11 @@ public class compress { } }); } else { - TarArchiveEntry entry = new TarArchiveEntry(sourcePath, sourcePath.getFileName().toString()); + Path fileName = sourcePath.getFileName(); + if (fileName == null) { + throw new IllegalArgumentException("无法从源路径获取文件名: " + sourcePath); + } + TarArchiveEntry entry = new TarArchiveEntry(sourcePath, fileName.toString()); tarOut.putArchiveEntry(entry); Files.copy(sourcePath, tarOut); tarOut.closeArchiveEntry(); @@ -164,7 +172,11 @@ public class compress { } }); } else { - ZipArchiveEntry entry = new ZipArchiveEntry(sourcePath.getFileName().toString()); + Path fileName = sourcePath.getFileName(); + if (fileName == null) { + throw new IllegalArgumentException("无法从源路径获取文件名: " + sourcePath); + } + ZipArchiveEntry entry = new ZipArchiveEntry(fileName.toString()); zipOut.putArchiveEntry(entry); Files.copy(sourcePath, zipOut); zipOut.closeArchiveEntry(); @@ -200,7 +212,11 @@ public class compress { if (entry.isDirectory()) { Files.createDirectories(targetPath); } else { - Files.createDirectories(targetPath.getParent()); + Path parent = targetPath.getParent(); + if (parent == null) { + throw new IllegalArgumentException("无法确定条目父目录: " + entry.getName()); + } + Files.createDirectories(parent); Files.copy(zipIn, targetPath); } } diff --git a/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/file/EncryptionAndDecryption.java b/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/file/EncryptionAndDecryption.java index 8665590..6384200 100644 --- a/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/file/EncryptionAndDecryption.java +++ b/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/file/EncryptionAndDecryption.java @@ -53,6 +53,9 @@ public class EncryptionAndDecryption { private static final String DES_ECB = "DES/ECB/PKCS5Padding"; private static final String RSA_WRAP = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"; + /** 共享的安全随机数发生器,避免每次加密都新建 SecureRandom 实例 */ + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); + /** * 文件加密。加密后覆盖原文件(原子替换),密钥保存到 keyPath 目录下,密钥名为 原文件名.key。 * @@ -135,7 +138,7 @@ public class EncryptionAndDecryption { private static void encryptAesGcm(File file, SecretKey key) throws Exception { byte[] iv = new byte[GCM_IV_BYTES]; - new SecureRandom().nextBytes(iv); + SECURE_RANDOM.nextBytes(iv); Cipher cipher = buildCipher(AES_GCM, Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(GCM_TAG_BITS, iv)); Path tmp = tempSibling(file); @@ -172,7 +175,7 @@ public class EncryptionAndDecryption { // 随机 AES-256 会话密钥,RSA-OAEP 包裹后存入文件头 SecretKey sessionKey = generateKey("AES", AES_KEY_BITS); byte[] iv = new byte[GCM_IV_BYTES]; - new SecureRandom().nextBytes(iv); + SECURE_RANDOM.nextBytes(iv); Cipher wrapCipher = Cipher.getInstance(RSA_WRAP); wrapCipher.init(Cipher.WRAP_MODE, publicKey); @@ -279,6 +282,9 @@ public class EncryptionAndDecryption { */ private static Path tempSibling(File file) throws IOException { Path dir = file.toPath().toAbsolutePath().getParent(); + if (dir == null) { + throw new IOException("无法确定文件所在目录: " + file); + } return Files.createTempFile(dir, file.getName() + ".", ".tmp"); }