@@ -148,6 +148,11 @@ for (const file of publicContentFiles) {
148148
149149try {
150150 const safeRoot = root . replaceAll ( '\\' , '/' ) ;
151+ const git = ( args , options = { } ) => execFileSync (
152+ 'git' ,
153+ [ '-c' , `safe.directory=${ safeRoot } ` , '-C' , root , ...args ] ,
154+ { encoding : 'utf8' , stdio : [ 'ignore' , 'pipe' , 'pipe' ] , ...options } ,
155+ ) ;
151156 const emailOutput = execFileSync (
152157 'git' ,
153158 [ '-c' , `safe.directory=${ safeRoot } ` , '-C' , root , 'log' , '--format=%ae%n%ce' ] ,
@@ -159,8 +164,31 @@ try {
159164 fail ( `reachable Git history exposes a non-noreply email: ${ email } ` ) ;
160165 }
161166 }
167+
168+ const reachableObjects = git ( [ 'rev-list' , '--objects' , '--all' ] )
169+ . split ( / \r ? \n / )
170+ . filter ( Boolean )
171+ . map ( ( line ) => {
172+ const separator = line . indexOf ( ' ' ) ;
173+ return separator === - 1
174+ ? { objectId : line , path : '(no path)' }
175+ : { objectId : line . slice ( 0 , separator ) , path : line . slice ( separator + 1 ) } ;
176+ } ) ;
177+ const inspectedBlobs = new Set ( ) ;
178+ for ( const { objectId, path } of reachableObjects ) {
179+ if ( inspectedBlobs . has ( objectId ) ) continue ;
180+ if ( git ( [ 'cat-file' , '-t' , objectId ] ) . trim ( ) !== 'blob' ) continue ;
181+ inspectedBlobs . add ( objectId ) ;
182+ const blob = git ( [ 'cat-file' , '-p' , objectId ] , { maxBuffer : 10 * 1024 * 1024 } ) ;
183+ if ( blob . includes ( '\0' ) ) continue ;
184+ for ( const [ pattern , label ] of forbiddenPatterns ) {
185+ if ( pattern . test ( blob ) ) {
186+ fail ( `reachable Git blob ${ objectId . slice ( 0 , 12 ) } (${ path } ) contains a forbidden ${ label } pattern` ) ;
187+ }
188+ }
189+ }
162190} catch ( error ) {
163- fail ( `could not inspect reachable Git metadata: ${ error . message } ` ) ;
191+ fail ( `could not inspect reachable Git metadata and blobs : ${ error . message } ` ) ;
164192}
165193
166194const durationMs = Math . round ( performance . now ( ) - startedAt ) ;
0 commit comments