From b179a20df3b1ed14eef6b2be690c9043d606bc0c Mon Sep 17 00:00:00 2001 From: crschnick Date: Sat, 26 Sep 2026 13:52:34 +0000 Subject: [PATCH] Various fixes --- .../java/io/xpipe/app/core/AppLocalTemp.java | 8 ++++++ .../xpipe/app/platform/ClipboardHelper.java | 11 ++++---- .../java/io/xpipe/app/process/ShellTemp.java | 25 +++++++++++-------- .../xpipe/app/util/HumanReadableFormat.java | 6 ----- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/io/xpipe/app/core/AppLocalTemp.java b/app/src/main/java/io/xpipe/app/core/AppLocalTemp.java index 62683e216..c4e5fbb11 100644 --- a/app/src/main/java/io/xpipe/app/core/AppLocalTemp.java +++ b/app/src/main/java/io/xpipe/app/core/AppLocalTemp.java @@ -6,6 +6,7 @@ import io.xpipe.app.util.OsType; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.attribute.PosixFilePermissions; @@ -45,6 +46,13 @@ public class AppLocalTemp { } try { + if (Files.isDirectory(temp)) { + var owner = Files.getOwner(temp).getName(); + if (!owner.equals(user)) { + throw new IOException("Invalid temp dir ownership for " + temp); + } + } + Files.createDirectories(temp); Files.setPosixFilePermissions(temp, PosixFilePermissions.fromString("rwx------")); } catch (Exception e) { diff --git a/app/src/main/java/io/xpipe/app/platform/ClipboardHelper.java b/app/src/main/java/io/xpipe/app/platform/ClipboardHelper.java index 379fef150..2cf0623d9 100644 --- a/app/src/main/java/io/xpipe/app/platform/ClipboardHelper.java +++ b/app/src/main/java/io/xpipe/app/platform/ClipboardHelper.java @@ -28,15 +28,16 @@ public class ClipboardHelper { var hasText = map.containsKey(DataFormat.PLAIN_TEXT); var hasUrl = map.containsKey(DataFormat.URL); Map contents = Stream.of( - // When we copy textual content, erase RTF and HTML clipboard to + // When we copy textual content, erase other types to // not keep different variants of text in the clipboard hasText || hasUrl ? null : DataFormat.RTF, - hasText || hasUrl ? null : DataFormat.HTML, + hasText || hasUrl ? null : DataFormat.HTML, + hasText || hasUrl ? null : DataFormat.IMAGE, + hasText || hasUrl ? null : DataFormat.FILES, // Do the same for text and URLs hasUrl && !hasText ? null : DataFormat.PLAIN_TEXT, - hasText && !hasUrl ? null : DataFormat.URL, - DataFormat.IMAGE, - DataFormat.FILES) + hasText && !hasUrl ? null : DataFormat.URL + ) .filter(dataFormat -> dataFormat != null) .map(dataFormat -> { try { diff --git a/app/src/main/java/io/xpipe/app/process/ShellTemp.java b/app/src/main/java/io/xpipe/app/process/ShellTemp.java index e5f48a40f..ffef1e8b8 100644 --- a/app/src/main/java/io/xpipe/app/process/ShellTemp.java +++ b/app/src/main/java/io/xpipe/app/process/ShellTemp.java @@ -11,28 +11,26 @@ import java.io.IOException; public class ShellTemp { public static FilePath createUserSpecificTempDataDirectory(ShellControl proc, String sub) throws Exception { - FilePath base; // On Windows and macOS, we already have user specific temp directories // Even on macOS as root it is technically unique as only root will use /tmp if (proc.getOsType() != OsType.WINDOWS && proc.getOsType() != OsType.MACOS) { var temp = proc.getSystemTemporaryDirectory(); - base = temp.join(AppNames.ofCurrent().getKebapName()); + var base = temp.join(AppNames.ofCurrent().getKebapName()); proc.view().mkdir(base); // We have to make sure that also other users can create files here // This command should work in all shells - proc.command("chmod 777 " + proc.getShellDialect().fileArgument(base)) - .executeAndCheck(); + proc.command("chmod 1777 " + proc.getShellDialect().fileArgument(base)).execute(); var user = proc.view().user(); - base = base.join(user); + var userDir = base.join(user); // We have to make sure that also other users can create files here // This command should work in all shells - proc.command("chmod 700 " + proc.getShellDialect().fileArgument(base)) - .executeAndCheck(); + proc.command("chmod 700 " + proc.getShellDialect().fileArgument(userDir)).execute(); + return sub != null ? userDir.join(sub) : userDir; } else { var temp = proc.getSystemTemporaryDirectory(); - base = temp.join(AppNames.ofCurrent().getKebapName()); + var base = temp.join(AppNames.ofCurrent().getKebapName()); + return sub != null ? base.join(sub) : base; } - return sub != null ? base.join(sub) : base; } public static void checkTempDirectory(ShellControl sc) throws Exception { @@ -117,8 +115,13 @@ public class ShellTemp { } var d = proc.getShellDialect(); - return proc.executeSimpleBooleanCommand("test -r %s && test -w %s && test -x %s" - .formatted(d.fileArgument(dir), d.fileArgument(dir), d.fileArgument(dir))); + var fullAccess = proc.command("test -r %s && test -w %s && test -x %s" + .formatted(d.fileArgument(dir), d.fileArgument(dir), d.fileArgument(dir))).executeAndCheck(); + if (!fullAccess) { + return false; + } + + return true; } public static FilePath getSubDirectory(ShellControl proc, String... sub) throws Exception { diff --git a/app/src/main/java/io/xpipe/app/util/HumanReadableFormat.java b/app/src/main/java/io/xpipe/app/util/HumanReadableFormat.java index a702234de..58741be14 100644 --- a/app/src/main/java/io/xpipe/app/util/HumanReadableFormat.java +++ b/app/src/main/java/io/xpipe/app/util/HumanReadableFormat.java @@ -30,9 +30,6 @@ public final class HumanReadableFormat { } var f = "%.1f"; var r = String.format(f + " %cB", bytes / (double) b, ci.current()); - if (r.endsWith(".0")) { - r = r.substring(0, r.length() - 2); - } return r; } @@ -50,9 +47,6 @@ public final class HumanReadableFormat { var f = ci.getIndex() >= 2 ? "%.3f" : "%.1f"; var r = String.format(f + " %cB", bytes / (double) b, ci.current()); - if (r.endsWith(".0")) { - r = r.substring(0, r.length() - 2); - } return r; }