@@ -111,8 +111,8 @@ private static final class SecureDirectoryOpsImpl implements SecureDirectoryOps
111111
112112 @ Override
113113 public void writeAtomically (Path reportName , String content ) throws IOException {
114- SecureDirectoryStream <Path > current = openSecurePath ();
115114 try {
115+ SecureDirectoryStream <Path > current = openSecurePath ();
116116 writeAtomicallySecure (current , reportName , content );
117117 } finally {
118118 closeDirectories (openedDirectories );
@@ -126,6 +126,9 @@ private SecureDirectoryStream<Path> openSecurePath() throws IOException {
126126 Path currentPath = startPath ;
127127
128128 for (Path component : startPath .relativize (outputDirectory )) {
129+ if (component .toString ().isEmpty ()) {
130+ continue ;
131+ }
129132 SecureDirectoryStream <Path > child ;
130133 try {
131134 child = current .newDirectoryStream (component , NOFOLLOW_LINKS );
@@ -194,20 +197,18 @@ private static final class FallbackDirectoryOps implements SecureDirectoryOps {
194197
195198 @ Override
196199 public void writeAtomically (Path reportName , String content ) throws IOException {
200+ Path targetFile = outputDirectory .resolve (reportName );
201+ rejectExistingSymbolicLinkComponents (targetFile );
202+
197203 // Ensure parent directories exist
198204 Files .createDirectories (outputDirectory );
199205
200- Path targetFile = outputDirectory .resolve (reportName );
201-
202206 // Check if target exists and is a symlink or directory
203207 if (Files .exists (targetFile , NOFOLLOW_LINKS )) {
204208 BasicFileAttributes attrs = Files .readAttributes (targetFile , BasicFileAttributes .class , NOFOLLOW_LINKS );
205209 if (attrs .isSymbolicLink () || attrs .isDirectory ()) {
206210 throw new IOException ("Refusing to replace non-regular report path: " + reportName );
207211 }
208- } else {
209- // Verify no symlink in path components
210- rejectExistingSymbolicLinkComponents (targetFile );
211212 }
212213
213214 // Write to temporary file then atomically move
0 commit comments