1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.impl;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.io.BufferedReader;
26 import java.io.IOException;
27 import java.nio.charset.StandardCharsets;
28 import java.nio.file.Files;
29 import java.nio.file.Path;
30
31 import org.eclipse.aether.spi.io.ChecksumProcessor;
32 import org.eclipse.aether.spi.io.PathProcessor;
33
34 import static java.util.Objects.requireNonNull;
35
36
37
38
39 @Singleton
40 @Named
41 public class DefaultChecksumProcessor implements ChecksumProcessor {
42
43
44
45
46
47
48
49 static final int MAX_CHECKSUM_FILE_CHARS = 8192;
50
51 private final PathProcessor pathProcessor;
52
53 @Inject
54 public DefaultChecksumProcessor(PathProcessor pathProcessor) {
55 this.pathProcessor = requireNonNull(pathProcessor);
56 }
57
58 @Override
59 public String readChecksum(final Path checksumPath) throws IOException {
60 String checksum;
61 try (BufferedReader br = Files.newBufferedReader(checksumPath, StandardCharsets.UTF_8)) {
62 checksum = readFirstNonEmptyLine(br, checksumPath.toString());
63 }
64
65 if (isAlgorithmHeaderFormat(checksum)) {
66 int lastSpacePos = checksum.lastIndexOf(' ');
67 checksum = checksum.substring(lastSpacePos + 1);
68 } else {
69 int spacePos = checksum.indexOf(' ');
70
71 if (spacePos != -1) {
72 checksum = checksum.substring(0, spacePos);
73 }
74 }
75
76 return checksum;
77 }
78
79
80
81
82
83 static String readFirstNonEmptyLine(BufferedReader reader, String source) throws IOException {
84 StringBuilder buffer = new StringBuilder(64);
85 int read = 0;
86 int c;
87 while ((c = reader.read()) != -1) {
88 if (++read > MAX_CHECKSUM_FILE_CHARS) {
89 throw new IOException("Checksum file " + source + " is malformed: longer than "
90 + MAX_CHECKSUM_FILE_CHARS + " characters");
91 }
92 if (c == '\n' || c == '\r') {
93 String line = buffer.toString().trim();
94 if (!line.isEmpty()) {
95 return line;
96 }
97 buffer.setLength(0);
98 } else {
99 buffer.append((char) c);
100 }
101 }
102 return buffer.toString().trim();
103 }
104
105
106
107
108
109
110 static boolean isAlgorithmHeaderFormat(String line) {
111 int lastSpacePos = line.lastIndexOf(' ');
112 if (lastSpacePos < 2 || lastSpacePos == line.length() - 1 || line.charAt(lastSpacePos - 1) != '=') {
113 return false;
114 }
115 for (int i = lastSpacePos + 1; i < line.length(); i++) {
116 char ch = line.charAt(i);
117 boolean hex = (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
118 if (!hex) {
119 return false;
120 }
121 }
122 return true;
123 }
124
125 @Override
126 public void writeChecksum(Path target, String checksum) throws IOException {
127
128 pathProcessor.write(target, checksum);
129 }
130 }