修复无法下载 SHA-1 为空字符串的文件的问题#6170
Conversation
- validate cache lookups and writes with SHA-1 format checks instead of only rejecting null hashes - throw an I/O error when caching is requested with a non-SHA-1 checksum to avoid creating invalid cache entries - skip checksum verification for empty download values so missing hashes no longer flow into cache and file validation paths
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces stricter checksum validation when caching files and libraries, specifically by checking if hashes are valid SHA-1 digests and ensuring checksums are not empty during file downloads. The review feedback correctly points out that hardcoding SHA-1 validation in CacheRepository breaks support for other hashing algorithms (such as MD5 or SHA-256) that the repository is designed to handle. The reviewer suggests implementing a dynamic isValidHash(algorithm, hash) method to support multiple algorithms and gracefully handle empty or null hashes to prevent unnecessary exceptions.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
|
||
| protected boolean fileExists(String algorithm, String hash) { | ||
| if (hash == null) return false; | ||
| if (!DigestUtils.isSha1Digest(hash)) return false; |
There was a problem hiding this comment.
在 fileExists 方法中,直接使用 DigestUtils.isSha1Digest(hash) 会导致非 SHA-1 算法(如 MD5、SHA-256 等)的校验失效。由于 CacheRepository 的设计是支持多种算法的(通过 algorithm 参数和对应的子目录),这里应该根据传入的 algorithm 来动态验证哈希值的有效性。建议使用一个通用的 isValidHash(algorithm, hash) 方法进行校验。
| if (!DigestUtils.isSha1Digest(hash)) return false; | |
| if (!isValidHash(algorithm, hash)) return false; |
| private void checkHash(String hash) throws IOException { | ||
| if (!DigestUtils.isSha1Digest(hash)) { | ||
| throw new IOException("Not SHA-1 checksum: " + hash); | ||
| } | ||
| } | ||
|
|
||
| public void tryCacheFile(Path path, String algorithm, String hash) throws IOException { | ||
| checkHash(hash); | ||
|
|
||
| Path cache = getFile(algorithm, hash); | ||
| if (Files.isRegularFile(cache)) return; | ||
| FileUtils.copyFile(path, cache); | ||
| } | ||
|
|
||
| public Path cacheFile(Path path, String algorithm, String hash) throws IOException { | ||
| checkHash(hash); | ||
|
|
||
| Path cache = getFile(algorithm, hash); | ||
| FileUtils.copyFile(path, cache); | ||
| return cache; |
There was a problem hiding this comment.
在 checkHash 方法中硬编码 DigestUtils.isSha1Digest(hash) 会导致非 SHA-1 算法在缓存时抛出 IOException。此外,当下载 SHA-1 为空字符串的文件时,FileDownloadTask 仍会尝试调用 cacheFile,这会导致抛出异常并打印警告日志。
建议:
- 实现一个通用的
isValidHash(algorithm, hash)方法,根据不同的算法验证哈希长度和十六进制格式。 - 重构
checkHash方法,使其接受algorithm参数并调用isValidHash。 - 在
tryCacheFile和cacheFile中,如果hash为空或为null,则直接返回(no-op),避免抛出异常和打印无意义的警告日志。
private static boolean isValidHash(String algorithm, String hash) {
if (hash == null) return false;
int expectedLength = switch (algorithm.toUpperCase(Locale.ROOT)) {
case "SHA-1", "SHA1" -> 40;
case "MD5" -> 32;
case "SHA-256", "SHA256" -> 64;
case "SHA-512", "SHA512" -> 128;
default -> -1;
};
if (expectedLength != -1) {
if (hash.length() != expectedLength) return false;
} else {
if (hash.length() < 2) return false;
}
for (int i = 0; i < hash.length(); i++) {
char ch = hash.charAt(i);
if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f') && (ch < 'A' || ch > 'F')) {
return false;
}
}
return true;
}
private void checkHash(String algorithm, String hash) throws IOException {
if (!isValidHash(algorithm, hash)) {
throw new IOException("Not " + algorithm + " checksum: " + hash);
}
}
public void tryCacheFile(Path path, String algorithm, String hash) throws IOException {
if (hash == null || hash.isEmpty()) return;
checkHash(algorithm, hash);
Path cache = getFile(algorithm, hash);
if (Files.isRegularFile(cache)) return;
FileUtils.copyFile(path, cache);
}
public Path cacheFile(Path path, String algorithm, String hash) throws IOException {
if (hash == null || hash.isEmpty()) return path;
checkHash(algorithm, hash);
Path cache = getFile(algorithm, hash);
FileUtils.copyFile(path, cache);
return cache;
}
No description provided.