@@ -316,13 +316,35 @@ function parseCachedEvidence(contents: string, run: E2ERunRecord): CachedFailure
316316
317317function readCachedEvidence ( cacheDir : string , run : E2ERunRecord ) : CachedFailureEvidence | null {
318318 const file = cacheFile ( cacheDir , run ) ;
319- if ( ! fs . existsSync ( file ) ) return null ;
320- const stat = fs . lstatSync ( file ) ;
321- if ( ! stat . isFile ( ) || stat . isSymbolicLink ( ) || stat . size > MAX_CACHE_FILE_BYTES ) {
322- throw new Error ( `Cached evidence for run ${ String ( run . databaseId ) } is not a bounded regular file.` ) ;
319+ const noFollow = fs . constants . O_NOFOLLOW ;
320+ if ( typeof noFollow !== "number" ) {
321+ throw new Error ( "O_NOFOLLOW is required for the evidence cache." ) ;
322+ }
323+ let descriptor : number ;
324+ try {
325+ descriptor = fs . openSync ( file , fs . constants . O_RDONLY | noFollow | fs . constants . O_NONBLOCK ) ;
326+ } catch ( error ) {
327+ const code = ( error as NodeJS . ErrnoException ) . code ;
328+ if ( code === "ENOENT" ) return null ;
329+ if ( code === "ELOOP" ) {
330+ throw new Error (
331+ `Cached evidence for run ${ String ( run . databaseId ) } is not a bounded regular file.` ,
332+ ) ;
333+ }
334+ throw error ;
335+ }
336+ try {
337+ const stat = fs . fstatSync ( descriptor ) ;
338+ if ( ! stat . isFile ( ) || stat . size > MAX_CACHE_FILE_BYTES ) {
339+ throw new Error (
340+ `Cached evidence for run ${ String ( run . databaseId ) } is not a bounded regular file.` ,
341+ ) ;
342+ }
343+ fs . fchmodSync ( descriptor , 0o600 ) ;
344+ return parseCachedEvidence ( fs . readFileSync ( descriptor , "utf8" ) , run ) ;
345+ } finally {
346+ fs . closeSync ( descriptor ) ;
323347 }
324- fs . chmodSync ( file , 0o600 ) ;
325- return parseCachedEvidence ( fs . readFileSync ( file , "utf8" ) , run ) ;
326348}
327349
328350function writeCachedEvidence (
0 commit comments