diff --git a/package.json b/package.json index 1419a6cefc10..5c9eae38fe41 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,6 @@ "@types/babel__core": "7.20.1", "@types/babel__template": "7.4.1", "@types/browserslist": "^4.15.0", - "@types/cacache": "^15.0.0", "@types/express": "^4.16.0", "@types/http-proxy": "^1.17.4", "@types/ini": "^1.3.31", @@ -129,7 +128,6 @@ "bootstrap": "^4.0.0", "browserslist": "^4.21.5", "buffer": "6.0.3", - "cacache": "17.1.3", "chokidar": "3.5.3", "copy-webpack-plugin": "11.0.0", "critters": "0.0.18", diff --git a/packages/angular_devkit/build_angular/BUILD.bazel b/packages/angular_devkit/build_angular/BUILD.bazel index 6c9d13598cf9..50f3decc08b2 100644 --- a/packages/angular_devkit/build_angular/BUILD.bazel +++ b/packages/angular_devkit/build_angular/BUILD.bazel @@ -129,7 +129,6 @@ ts_library( "@npm//@types/babel__core", "@npm//@types/babel__template", "@npm//@types/browserslist", - "@npm//@types/cacache", "@npm//@types/inquirer", "@npm//@types/karma", "@npm//@types/less", @@ -145,7 +144,6 @@ ts_library( "@npm//babel-loader", "@npm//babel-plugin-istanbul", "@npm//browserslist", - "@npm//cacache", "@npm//chokidar", "@npm//copy-webpack-plugin", "@npm//critters", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 394c8c5beff8..85392620c50c 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -28,7 +28,6 @@ "babel-loader": "9.1.2", "babel-plugin-istanbul": "6.1.1", "browserslist": "^4.21.5", - "cacache": "17.1.3", "chokidar": "3.5.3", "copy-webpack-plugin": "11.0.0", "critters": "0.0.18", diff --git a/packages/angular_devkit/build_angular/src/utils/index-file/inline-fonts.ts b/packages/angular_devkit/build_angular/src/utils/index-file/inline-fonts.ts index 2f358cbad7ff..4746d589d22a 100644 --- a/packages/angular_devkit/build_angular/src/utils/index-file/inline-fonts.ts +++ b/packages/angular_devkit/build_angular/src/utils/index-file/inline-fonts.ts @@ -6,12 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ -import * as cacache from 'cacache'; -import * as fs from 'fs'; -import * as https from 'https'; import proxyAgent from 'https-proxy-agent'; -import { join } from 'path'; -import { URL } from 'url'; +import { createHash } from 'node:crypto'; +import { readFile, rm, writeFile } from 'node:fs/promises'; +import * as https from 'node:https'; +import { join } from 'node:path'; +import { URL } from 'node:url'; import { NormalizedCachedOptions } from '../normalize-cache'; import { VERSION } from '../package-version'; import { htmlRewritingStream } from './html-rewriting-stream'; @@ -34,6 +34,16 @@ const SUPPORTED_PROVIDERS: Record = { }, }; +/** + * Hash algorithm used for cached files. + */ +const CONTENT_HASH_ALGORITHM = 'sha256'; + +/** + * String length of the SHA-256 content hash stored in cached files. + */ +const CONTENT_HASH_LENGTH = 64; + export class InlineFontsProcessor { private readonly cachePath: string | undefined; constructor(private options: InlineFontsOptions) { @@ -161,13 +171,29 @@ export class InlineFontsProcessor { } private async getResponse(url: URL): Promise { - const key = `${VERSION}|${url}`; - + let cacheFile; if (this.cachePath) { - const entry = await cacache.get.info(this.cachePath, key); - if (entry) { - return fs.promises.readFile(entry.path, 'utf8'); - } + const key = createHash(CONTENT_HASH_ALGORITHM).update(`${VERSION}|${url}`).digest('hex'); + cacheFile = join(this.cachePath, key); + } + + if (cacheFile) { + try { + const data = await readFile(cacheFile, 'utf8'); + // Check for valid content via stored hash + if (data.length > CONTENT_HASH_LENGTH) { + const storedHash = data.slice(0, CONTENT_HASH_LENGTH); + const content = data.slice(CONTENT_HASH_LENGTH); + const contentHash = createHash(CONTENT_HASH_ALGORITHM).update(content).digest('base64'); + if (storedHash === contentHash) { + // Return valid content + return content; + } else { + // Delete corrupted cache content + await rm(cacheFile); + } + } + } catch {} } let agent: proxyAgent.HttpsProxyAgent | undefined; @@ -214,8 +240,11 @@ export class InlineFontsProcessor { ); }); - if (this.cachePath) { - await cacache.put(this.cachePath, key, data); + if (cacheFile) { + try { + const dataHash = createHash(CONTENT_HASH_ALGORITHM).update(data).digest('hex'); + await writeFile(cacheFile, dataHash + data); + } catch {} } return data; diff --git a/yarn.lock b/yarn.lock index 8cc1ea206a69..a38ad2cb89d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3305,13 +3305,6 @@ dependencies: browserslist "*" -"@types/cacache@^15.0.0": - version "15.0.1" - resolved "https://registry.yarnpkg.com/@types/cacache/-/cacache-15.0.1.tgz#3d1943cc80ade160c9ae98bd5c1ebcc538f9cd57" - integrity sha512-JhL2GFJuHMx4RMg4z0XfXB4ZkKdyiOaOLpjoYMXcyKfrkF3IBXNZBj6/Peo9zX/7PPHyfI63NWVD589cI2YTzg== - dependencies: - "@types/node" "*" - "@types/connect-history-api-fallback@^1.3.5": version "1.5.0" resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#9fd20b3974bdc2bcd4ac6567e2e0f6885cb2cf41"