Author: msahyoun
Date: Sat Mar 28 19:28:21 2026
New Revision: 1932647
Log:
PDFBOX-6185: improve handling of files in temp directory; Windows settings by
Claude Sonnet 4.6
Modified:
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/ui/Tree.java
Modified:
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/ui/Tree.java
==============================================================================
--- pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/ui/Tree.java
Sat Mar 28 18:45:04 2026 (r1932646)
+++ pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/ui/Tree.java
Sat Mar 28 19:28:21 2026 (r1932647)
@@ -39,11 +39,23 @@ import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.FileSystems;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.AclEntry;
+import java.nio.file.attribute.AclEntryPermission;
+import java.nio.file.attribute.AclEntryType;
+import java.nio.file.attribute.AclFileAttributeView;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.nio.file.attribute.UserPrincipal;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.StringJoiner;
+import java.util.stream.Stream;
+
import org.apache.pdfbox.debugger.PDFDebugger;
/**
@@ -58,6 +70,84 @@ public class Tree extends JTree
private final JPopupMenu treePopupMenu;
private final Object rootNode;
+ // Temporary files are stored in a private temp directory with restricted
permissions,
+ // which is deleted on exit using a shutdown hook.
+ // PDFBOX-6185
+ private static final Path TEMP_DIR = createTempDir();
+
+ private static Path createTempDir()
+ {
+ try
+ {
+ Path tempDir = Files.createTempDirectory("pdfbox-");
+ applyOwnerOnlyPermissions(tempDir);
+
+ // use shutdown hook instead of deleteOnExit() to ensure deletion
+ // of the entire directory in case of not automatically deleted on
+ // JVM exit (e.g. due to hard crash or kill -9)
+ Runtime.getRuntime().addShutdownHook(new Thread(() ->
+ {
+ try (Stream<Path> entries = Files.walk(tempDir))
+ {
+ entries.sorted(Comparator.reverseOrder())
+ .forEach(p -> p.toFile().delete());
+ }
+ catch (IOException ignored) {}
+ }));
+
+ return tempDir;
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Failed to create temporary directory
for PDFDebugger", e);
+ }
+ }
+
+ private static void applyOwnerOnlyPermissions(Path dir) throws IOException
+ {
+ if
(FileSystems.getDefault().supportedFileAttributeViews().contains("posix"))
+ {
+ // Unix/macOS — rwx------
+ Files.setPosixFilePermissions(dir,
PosixFilePermissions.fromString("rwx------"));
+ }
+ else
+ {
+ // Windows — replace the entire ACL with a single owner-only ALLOW
entry
+ AclFileAttributeView aclView =
+ Files.getFileAttributeView(dir, AclFileAttributeView.class);
+
+ if (aclView == null)
+ {
+ throw new IOException("Neither posix nor ACL view is supported
on this file system");
+ }
+
+ UserPrincipal owner = aclView.getOwner();
+
+ AclEntry ownerFullControl = AclEntry.newBuilder()
+ .setType(AclEntryType.ALLOW)
+ .setPrincipal(owner)
+ .setPermissions(
+ AclEntryPermission.READ_DATA,
+ AclEntryPermission.WRITE_DATA,
+ AclEntryPermission.APPEND_DATA,
+ AclEntryPermission.READ_NAMED_ATTRS,
+ AclEntryPermission.WRITE_NAMED_ATTRS,
+ AclEntryPermission.EXECUTE,
+ AclEntryPermission.DELETE_CHILD,
+ AclEntryPermission.READ_ATTRIBUTES,
+ AclEntryPermission.WRITE_ATTRIBUTES,
+ AclEntryPermission.DELETE,
+ AclEntryPermission.READ_ACL,
+ AclEntryPermission.WRITE_ACL,
+ AclEntryPermission.SYNCHRONIZE
+ )
+ .build();
+
+ // Set so that only the owner has permissions, and remove any
inherited ACL entries
+ aclView.setAcl(Collections.singletonList(ownerFullControl));
+ }
+ }
+
/**
* Constructor.
*/
@@ -295,8 +385,7 @@ public class Tree extends JTree
{
try
{
- File temp = Files.createTempFile("pdfbox", "." +
extension).toFile();
- temp.deleteOnExit();
+ File temp = Files.createTempFile(TEMP_DIR, "pdfbox", "." +
extension).toFile();
try (InputStream is = cosStream.createInputStream())
{