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