diff --git a/build-plugin.sh b/build-plugin.sh
index 819bef3..12e6054 100755
--- a/build-plugin.sh
+++ b/build-plugin.sh
@@ -2,7 +2,7 @@
set -eu
PLUGIN="u-navigator"
-VERSION="2026.06.23.r023"
+VERSION="2026.06.23.r024"
PKG_DIR="packages"
WORK_DIR=".plugin-build"
PKG_NAME="${PLUGIN}-${VERSION}.tgz"
diff --git a/packages/u-navigator-2026.06.23.r023.tgz b/packages/u-navigator-2026.06.23.r023.tgz
deleted file mode 100644
index 68285e4..0000000
Binary files a/packages/u-navigator-2026.06.23.r023.tgz and /dev/null differ
diff --git a/packages/u-navigator-2026.06.23.r024.tgz b/packages/u-navigator-2026.06.23.r024.tgz
new file mode 100644
index 0000000..a1aa5a9
Binary files /dev/null and b/packages/u-navigator-2026.06.23.r024.tgz differ
diff --git a/plugin-root/usr/local/emhttp/plugins/u-navigator/api/common.php b/plugin-root/usr/local/emhttp/plugins/u-navigator/api/common.php
index 136c4f4..d7bb740 100644
--- a/plugin-root/usr/local/emhttp/plugins/u-navigator/api/common.php
+++ b/plugin-root/usr/local/emhttp/plugins/u-navigator/api/common.php
@@ -164,7 +164,9 @@ function unav_guard_destination(string $source, string $destination): void {
if (file_exists($destination)) {
unav_error(409, 'Destination already exists');
}
- if ($source === $destination || str_starts_with($destination, rtrim($source, '/') . '/')) {
+ $normalizedSource = rtrim($source, '/');
+ $normalizedDestination = rtrim($destination, '/');
+ if ($normalizedSource === $normalizedDestination || (is_dir($source) && str_starts_with($normalizedDestination, $normalizedSource . '/'))) {
unav_error(400, 'Destination cannot be inside source');
}
}
diff --git a/plugin-root/usr/local/emhttp/plugins/u-navigator/api/job_worker.php b/plugin-root/usr/local/emhttp/plugins/u-navigator/api/job_worker.php
index 0396fe5..04b364e 100644
--- a/plugin-root/usr/local/emhttp/plugins/u-navigator/api/job_worker.php
+++ b/plugin-root/usr/local/emhttp/plugins/u-navigator/api/job_worker.php
@@ -54,7 +54,9 @@ function unav_worker_guard(string $source, string $destination): void {
if (file_exists($destinationPath)) {
throw new RuntimeException('Destination already exists');
}
- if ($sourceReal === $destinationPath || str_starts_with($destinationPath, rtrim($sourceReal, '/') . '/')) {
+ $normalizedSource = rtrim($sourceReal, '/');
+ $normalizedDestination = rtrim($destinationPath, '/');
+ if ($normalizedSource === $normalizedDestination || (is_dir($sourceReal) && str_starts_with($normalizedDestination, $normalizedSource . '/'))) {
throw new RuntimeException('Destination cannot be inside source');
}
}
diff --git a/server/public/app.js b/server/public/app.js
index 985a1a4..3534d0f 100644
--- a/server/public/app.js
+++ b/server/public/app.js
@@ -892,11 +892,18 @@ async function finishItemPointerDrag(event, move, up) {
}
try {
- const destination = `${target.path.replace(/\/$/, '')}/${drag.name}`;
- if (destination === drag.path) {
+ const destination = joinPath(target.path, drag.name);
+ recordDebug('pointer.destination', {
+ source: drag.path,
+ targetPath: target.path,
+ destination,
+ targetIsRow: Boolean(target.row),
+ copy: event.altKey
+ });
+ if (destination === drag.path || target.path === drag.path) {
throw new Error('Quelle und Ziel sind identisch.');
}
- if (drag.type === 'directory' && target.path.startsWith(`${drag.path.replace(/\/$/, '')}/`)) {
+ if (drag.type === 'directory' && isPathInside(target.path, drag.path)) {
throw new Error('Ein Ordner kann nicht in sich selbst verschoben werden.');
}
await createJob(event.altKey ? 'copy' : 'move', drag.path, destination, [drag.sourceWindowId, target.windowId]);
@@ -1132,6 +1139,21 @@ function dirname(value) {
return `/${parts.slice(0, -1).join('/')}`;
}
+function joinPath(parent, name) {
+ return `${String(parent || '').replace(/\/+$/, '')}/${String(name || '').replace(/^\/+/, '')}`;
+}
+
+function normalizePath(value) {
+ const parts = String(value || '').split('/').filter(Boolean);
+ return `/${parts.join('/')}`;
+}
+
+function isPathInside(path, parent) {
+ const normalizedPath = normalizePath(path);
+ const normalizedParent = normalizePath(parent);
+ return normalizedPath.startsWith(`${normalizedParent.replace(/\/$/, '')}/`);
+}
+
function formatBytes(bytes) {
const value = Number(bytes || 0);
if (value < 1024) return `${value} B`;
diff --git a/u-navigator.plg b/u-navigator.plg
index b5a5892..3fd4ecd 100644
--- a/u-navigator.plg
+++ b/u-navigator.plg
@@ -1,7 +1,7 @@
-
+
@@ -24,7 +24,7 @@
https://git.casaderoll.de/michael/Unraid-Navigator/raw/branch/main/packages/&package;
-c57cb70f4d040d65869b6ffde469b18a
+460c859d05c48638ba4c30e51e040b65