Skip to content

Commit

Permalink
fix: validate checksum of cached artifacts too (#212)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarshallOfSound authored Sep 5, 2023
1 parent b70c472 commit 32211d4
Showing 1 changed file with 72 additions and 50 deletions.
122 changes: 72 additions & 50 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,69 @@ if (process.env.ELECTRON_GET_USE_PROXY) {
initializeProxy();
}

type ArtifactDownloader = (
_artifactDetails: ElectronPlatformArtifactDetailsWithDefaults,
) => Promise<string>;

async function validateArtifact(
artifactDetails: ElectronArtifactDetails,
downloadedAssetPath: string,
_downloadArtifact: ArtifactDownloader,
) {
return await withTempDirectoryIn(artifactDetails.tempDirectory, async tempFolder => {
// Don't try to verify the hash of the hash file itself
// and for older versions that don't have a SHASUMS256.txt
if (
!artifactDetails.artifactName.startsWith('SHASUMS256') &&
!artifactDetails.unsafelyDisableChecksums &&
semver.gte(artifactDetails.version, '1.3.2')
) {
let shasumPath: string;
const checksums = artifactDetails.checksums;
if (checksums) {
shasumPath = path.resolve(tempFolder, 'SHASUMS256.txt');
const fileNames: string[] = Object.keys(checksums);
if (fileNames.length === 0) {
throw new Error(
'Provided "checksums" object is empty, cannot generate a valid SHASUMS256.txt',
);
}
const generatedChecksums = fileNames
.map(fileName => `${checksums[fileName]} *${fileName}`)
.join('\n');
await fs.writeFile(shasumPath, generatedChecksums);
} else {
shasumPath = await _downloadArtifact({
isGeneric: true,
version: artifactDetails.version,
artifactName: 'SHASUMS256.txt',
force: artifactDetails.force,
downloadOptions: artifactDetails.downloadOptions,
cacheRoot: artifactDetails.cacheRoot,
downloader: artifactDetails.downloader,
mirrorOptions: artifactDetails.mirrorOptions,
});
}

// For versions 1.3.2 - 1.3.4, need to overwrite the `defaultTextEncoding` option:
// https://github.com/electron/electron/pull/6676#discussion_r75332120
if (semver.satisfies(artifactDetails.version, '1.3.2 - 1.3.4')) {
const validatorOptions: sumchecker.ChecksumOptions = {};
validatorOptions.defaultTextEncoding = 'binary';
const checker = new sumchecker.ChecksumValidator('sha256', shasumPath, validatorOptions);
await checker.validate(
path.dirname(downloadedAssetPath),
path.basename(downloadedAssetPath),
);
} else {
await sumchecker('sha256', shasumPath, path.dirname(downloadedAssetPath), [
path.basename(downloadedAssetPath),
]);
}
}
});
}

/**
* Downloads an artifact from an Electron release and returns an absolute path
* to the downloaded file.
Expand Down Expand Up @@ -74,7 +137,14 @@ export async function downloadArtifact(
d('Cache miss');
} else {
d('Cache hit');
return cachedPath;
try {
await validateArtifact(artifactDetails, cachedPath, downloadArtifact);

return cachedPath;
} catch (err) {
d("Artifact in cache didn't match checksums", err);
d('falling back to re-download');
}
}
}

Expand Down Expand Up @@ -102,55 +172,7 @@ export async function downloadArtifact(
);
await downloader.download(url, tempDownloadPath, artifactDetails.downloadOptions);

// Don't try to verify the hash of the hash file itself
// and for older versions that don't have a SHASUMS256.txt
if (
!artifactDetails.artifactName.startsWith('SHASUMS256') &&
!artifactDetails.unsafelyDisableChecksums &&
semver.gte(artifactDetails.version, '1.3.2')
) {
await withTempDirectory(async tmpDir => {
let shasumPath: string;
const checksums = artifactDetails.checksums;
if (checksums) {
shasumPath = path.resolve(tmpDir, 'SHASUMS256.txt');
const fileNames: string[] = Object.keys(checksums);
if (fileNames.length === 0) {
throw new Error(
'Provided "checksums" object is empty, cannot generate a valid SHASUMS256.txt',
);
}
const generatedChecksums = fileNames
.map(fileName => `${checksums[fileName]} *${fileName}`)
.join('\n');
await fs.writeFile(shasumPath, generatedChecksums);
} else {
shasumPath = await downloadArtifact({
isGeneric: true,
version: artifactDetails.version,
artifactName: 'SHASUMS256.txt',
force: artifactDetails.force,
downloadOptions: artifactDetails.downloadOptions,
cacheRoot: artifactDetails.cacheRoot,
downloader: artifactDetails.downloader,
mirrorOptions: artifactDetails.mirrorOptions,
});
}

// For versions 1.3.2 - 1.3.4, need to overwrite the `defaultTextEncoding` option:
// https://github.com/electron/electron/pull/6676#discussion_r75332120
if (semver.satisfies(artifactDetails.version, '1.3.2 - 1.3.4')) {
const validatorOptions: sumchecker.ChecksumOptions = {};
validatorOptions.defaultTextEncoding = 'binary';
const checker = new sumchecker.ChecksumValidator('sha256', shasumPath, validatorOptions);
await checker.validate(path.dirname(tempDownloadPath), path.basename(tempDownloadPath));
} else {
await sumchecker('sha256', shasumPath, path.dirname(tempDownloadPath), [
path.basename(tempDownloadPath),
]);
}
});
}
await validateArtifact(artifactDetails, tempDownloadPath, downloadArtifact);

return await cache.putFileInCache(url, tempDownloadPath, fileName);
});
Expand Down

0 comments on commit 32211d4

Please sign in to comment.