| 182 | } |
| 183 | |
| 184 | function parseExpectedChecksum(manifest, archiveName) { |
| 185 | let expected = null; |
| 186 | for (const line of manifest.split('\n')) { |
| 187 | const fields = line.trim().split(/\s+/); |
| 188 | if (fields.length < 2) continue; |
| 189 | if (fields[1] !== archiveName && fields[1] !== `*${archiveName}`) continue; |
| 190 | |
| 191 | const digest = fields[0].toLowerCase(); |
| 192 | if (!/^[0-9a-f]{64}$/.test(digest)) { |
| 193 | throw new Error(`Invalid SHA-256 checksum for ${archiveName}`); |
| 194 | } |
| 195 | if (expected !== null && expected !== digest) { |
| 196 | throw new Error(`Conflicting SHA-256 checksums for ${archiveName}`); |
| 197 | } |
| 198 | expected = digest; |
| 199 | } |
| 200 | if (expected === null) { |
| 201 | throw new Error(`No checksum for ${archiveName} in checksums.txt`); |
| 202 | } |
| 203 | return expected; |
| 204 | } |
| 205 | |
| 206 | function verifyCandidate(candidatePath) { |
| 207 | execFileSync(candidatePath, ['--version'], { |