Skip to content

Commit 89177d5

Browse files
author
Maruan Sahyoun
committed
PDFBOX-6185: improve handling of files in temp directory; Windows settings by Claude Sonnet 4.6
git-svn-id: https://svn.apache.org/repos/asf/pdfbox/trunk@1932647 13f79535-47bb-0310-9956-ffa450edef68
1 parent 28a46c0 commit 89177d5

1 file changed

Lines changed: 91 additions & 2 deletions

File tree

  • debugger/src/main/java/org/apache/pdfbox/debugger/ui

debugger/src/main/java/org/apache/pdfbox/debugger/ui/Tree.java

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,23 @@
3939
import java.io.File;
4040
import java.io.IOException;
4141
import java.io.InputStream;
42+
import java.nio.file.FileSystems;
4243
import java.nio.file.Files;
44+
import java.nio.file.Path;
4345
import java.nio.file.StandardCopyOption;
46+
import java.nio.file.attribute.AclEntry;
47+
import java.nio.file.attribute.AclEntryPermission;
48+
import java.nio.file.attribute.AclEntryType;
49+
import java.nio.file.attribute.AclFileAttributeView;
50+
import java.nio.file.attribute.PosixFilePermissions;
51+
import java.nio.file.attribute.UserPrincipal;
4452
import java.util.ArrayList;
53+
import java.util.Collections;
54+
import java.util.Comparator;
4555
import java.util.List;
4656
import java.util.StringJoiner;
57+
import java.util.stream.Stream;
58+
4759
import org.apache.pdfbox.debugger.PDFDebugger;
4860

4961
/**
@@ -58,6 +70,84 @@ public class Tree extends JTree
5870
private final JPopupMenu treePopupMenu;
5971
private final Object rootNode;
6072

73+
// Temporary files are stored in a private temp directory with restricted permissions,
74+
// which is deleted on exit using a shutdown hook.
75+
// PDFBOX-6185
76+
private static final Path TEMP_DIR = createTempDir();
77+
78+
private static Path createTempDir()
79+
{
80+
try
81+
{
82+
Path tempDir = Files.createTempDirectory("pdfbox-");
83+
applyOwnerOnlyPermissions(tempDir);
84+
85+
// use shutdown hook instead of deleteOnExit() to ensure deletion
86+
// of the entire directory in case of not automatically deleted on
87+
// JVM exit (e.g. due to hard crash or kill -9)
88+
Runtime.getRuntime().addShutdownHook(new Thread(() ->
89+
{
90+
try (Stream<Path> entries = Files.walk(tempDir))
91+
{
92+
entries.sorted(Comparator.reverseOrder())
93+
.forEach(p -> p.toFile().delete());
94+
}
95+
catch (IOException ignored) {}
96+
}));
97+
98+
return tempDir;
99+
}
100+
catch (IOException e)
101+
{
102+
throw new RuntimeException("Failed to create temporary directory for PDFDebugger", e);
103+
}
104+
}
105+
106+
private static void applyOwnerOnlyPermissions(Path dir) throws IOException
107+
{
108+
if (FileSystems.getDefault().supportedFileAttributeViews().contains("posix"))
109+
{
110+
// Unix/macOS — rwx------
111+
Files.setPosixFilePermissions(dir, PosixFilePermissions.fromString("rwx------"));
112+
}
113+
else
114+
{
115+
// Windows — replace the entire ACL with a single owner-only ALLOW entry
116+
AclFileAttributeView aclView =
117+
Files.getFileAttributeView(dir, AclFileAttributeView.class);
118+
119+
if (aclView == null)
120+
{
121+
throw new IOException("Neither posix nor ACL view is supported on this file system");
122+
}
123+
124+
UserPrincipal owner = aclView.getOwner();
125+
126+
AclEntry ownerFullControl = AclEntry.newBuilder()
127+
.setType(AclEntryType.ALLOW)
128+
.setPrincipal(owner)
129+
.setPermissions(
130+
AclEntryPermission.READ_DATA,
131+
AclEntryPermission.WRITE_DATA,
132+
AclEntryPermission.APPEND_DATA,
133+
AclEntryPermission.READ_NAMED_ATTRS,
134+
AclEntryPermission.WRITE_NAMED_ATTRS,
135+
AclEntryPermission.EXECUTE,
136+
AclEntryPermission.DELETE_CHILD,
137+
AclEntryPermission.READ_ATTRIBUTES,
138+
AclEntryPermission.WRITE_ATTRIBUTES,
139+
AclEntryPermission.DELETE,
140+
AclEntryPermission.READ_ACL,
141+
AclEntryPermission.WRITE_ACL,
142+
AclEntryPermission.SYNCHRONIZE
143+
)
144+
.build();
145+
146+
// Set so that only the owner has permissions, and remove any inherited ACL entries
147+
aclView.setAcl(Collections.singletonList(ownerFullControl));
148+
}
149+
}
150+
61151
/**
62152
* Constructor.
63153
*/
@@ -295,8 +385,7 @@ private JMenuItem getFileOpenMenu(final COSStream cosStream, final TreePath node
295385
{
296386
try
297387
{
298-
File temp = Files.createTempFile("pdfbox", "." + extension).toFile();
299-
temp.deleteOnExit();
388+
File temp = Files.createTempFile(TEMP_DIR, "pdfbox", "." + extension).toFile();
300389

301390
try (InputStream is = cosStream.createInputStream())
302391
{

0 commit comments

Comments
 (0)