mirror of
https://github.com/michalcz10/USB-RAID-Array.git
synced 2026-11-11 16:09:03 +00:00
Fix SFTP root navigation on Windows
Use portable POSIX parent paths instead of platform-dependent dirname() for remote navigation, previews, uploads, file operations and shared URLs. Normalize browser paths, avoid doubled root separators and preserve top-level directory names in ZIP downloads. Add regression coverage for root navigation, generated links, relative paths and ZIP members, and document the new test command. Verified with PHP syntax checks and all three regression suites.
This commit is contained in:
@@ -5,7 +5,7 @@ $sftp = initializeSFTP();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete'])) {
|
||||
$itemToDelete = $_POST['delete'];
|
||||
$parentDir = dirname($itemToDelete);
|
||||
$parentDir = remoteDirname($itemToDelete);
|
||||
|
||||
if ($parentDir === '/' || $parentDir === '.') {
|
||||
$parentDir = $defaultPath;
|
||||
|
||||
@@ -41,7 +41,7 @@ try {
|
||||
$fullRemotePath = rtrim($currentPath, '/') . '/' . $file;
|
||||
|
||||
$baseDirName = basename($remoteBasePath);
|
||||
$relPathFromBase = substr($fullRemotePath, strlen(dirname($remoteBasePath)) + 1);
|
||||
$relPathFromBase = substr($fullRemotePath, strlen(rtrim(remoteDirname($remoteBasePath), '/')) + 1);
|
||||
file_put_contents($logFile, "Processing: $fullRemotePath (relative: $relPathFromBase)\n", FILE_APPEND);
|
||||
|
||||
$isDir = $sftp->is_dir($fullRemotePath);
|
||||
@@ -214,4 +214,4 @@ try {
|
||||
header("HTTP/1.1 500 Internal Server Error");
|
||||
echo $errorMessage;
|
||||
}
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -24,7 +24,7 @@ $sftp = initializeSFTP();
|
||||
// Process extraction request
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['archive'])) {
|
||||
$archivePath = $_POST['archive'];
|
||||
$dirPath = dirname($archivePath);
|
||||
$dirPath = remoteDirname($archivePath);
|
||||
$archiveName = basename($archivePath);
|
||||
$extension = pathinfo($archiveName, PATHINFO_EXTENSION);
|
||||
|
||||
|
||||
+16
-15
@@ -13,11 +13,12 @@
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../config/config.php';
|
||||
require_once __DIR__ . '/../../includes/workspace.php';
|
||||
require_once __DIR__ . '/../../includes/workspace.php';
|
||||
$sftp = initializeSFTP();
|
||||
|
||||
$defaultPath = normalizePath($defaultPath);
|
||||
$currentPath = isset($_GET['path']) ? normalizePath($_GET['path']) : $defaultPath;
|
||||
if (strpos($currentPath, $defaultPath) !== 0) {
|
||||
if ($currentPath !== $defaultPath && strpos($currentPath, rtrim($defaultPath, '/') . '/') !== 0) {
|
||||
$currentPath = $defaultPath;
|
||||
}
|
||||
|
||||
@@ -188,30 +189,30 @@ require_once __DIR__ . '/../../includes/workspace.php';
|
||||
|
||||
if ($currentPath !== $defaultPath) : ?>
|
||||
<tr>
|
||||
<td colspan="3"><a class="text-danger" href="?path=<?= urlencode(dirname($currentPath)) ?>"><b>↑ Parent folder</b></a></td>
|
||||
<td colspan="3"><a class="text-danger" href="?path=<?= urlencode(remoteDirname($currentPath)) ?>"><b>↑ Parent folder</b></a></td>
|
||||
</tr>
|
||||
<?php endif;
|
||||
|
||||
foreach ($directories as $directory) : ?>
|
||||
<tr data-file-name="<?= htmlspecialchars($directory) ?>" data-kind="folder">
|
||||
<td><span class="file-icon folder-icon" aria-hidden="true">▰</span>
|
||||
<a href="?path=<?= urlencode($currentPath . '/' . $directory) ?>"><?= htmlspecialchars($directory) ?></a></td><td class="size-cell">—</td>
|
||||
<a href="?path=<?= urlencode(rtrim($currentPath, '/') . '/' . $directory) ?>"><?= htmlspecialchars($directory) ?></a></td><td class="size-cell">—</td>
|
||||
<td>
|
||||
<?php if (isset($_SESSION["delPer"]) && $_SESSION["delPer"] == true) : ?>
|
||||
<form method="POST" action="delete.php" style="display:inline;">
|
||||
<input type="hidden" name="delete" value="<?= htmlspecialchars($currentPath . '/' . $directory) ?>">
|
||||
<input type="hidden" name="delete" value="<?= htmlspecialchars(rtrim($currentPath, '/') . '/' . $directory) ?>">
|
||||
<button type="submit" class="btn btn-danger mt-1 mb-1" onclick="confirmDelete(event)">Delete</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_SESSION["downPer"]) && $_SESSION["downPer"] == true) : ?>
|
||||
<form method="POST" action="download.php" style="display:inline;">
|
||||
<input type="hidden" name="file" value="<?= htmlspecialchars($currentPath . '/' . $directory) ?>">
|
||||
<input type="hidden" name="file" value="<?= htmlspecialchars(rtrim($currentPath, '/') . '/' . $directory) ?>">
|
||||
<button type="submit" class="btn btn-success mt-1 mb-1">Download</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["upPer"]) && $_SESSION["upPer"] == true) : ?>
|
||||
<button type="button" class="btn btn-warning mt-1 mb-1" onclick="openRenameModal('<?= htmlspecialchars(addslashes($directory)) ?>', '<?= htmlspecialchars(addslashes($currentPath . '/' . $directory)) ?>', true)">Rename</button>
|
||||
<button type="button" class="btn btn-warning mt-1 mb-1" onclick="openRenameModal('<?= htmlspecialchars(addslashes($directory)) ?>', '<?= htmlspecialchars(addslashes(rtrim($currentPath, '/') . '/' . $directory)) ?>', true)">Rename</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -235,7 +236,7 @@ require_once __DIR__ . '/../../includes/workspace.php';
|
||||
<tr data-file-name="<?= htmlspecialchars($file) ?>" data-kind="file">
|
||||
<td><span class="file-icon" aria-hidden="true">▤</span>
|
||||
<?php if ($isMedia): ?>
|
||||
<a class="text-info-emphasis" href="view.php?file=<?= urlencode($currentPath . '/' . $file) ?>">
|
||||
<a class="text-info-emphasis" href="view.php?file=<?= urlencode(rtrim($currentPath, '/') . '/' . $file) ?>">
|
||||
<?= htmlspecialchars($file) ?>
|
||||
</a>
|
||||
<?php if ($isImage): ?>
|
||||
@@ -246,12 +247,12 @@ require_once __DIR__ . '/../../includes/workspace.php';
|
||||
<span class="badge bg-info rounded-pill">Audio</span>
|
||||
<?php endif; ?>
|
||||
<?php elseif ($isEditable): ?>
|
||||
<a class="text-warning-emphasis" href="open.php?file=<?= urlencode($currentPath . '/' . $file) ?>">
|
||||
<a class="text-warning-emphasis" href="open.php?file=<?= urlencode(rtrim($currentPath, '/') . '/' . $file) ?>">
|
||||
<?= htmlspecialchars($file) ?>
|
||||
</a>
|
||||
<span class="badge bg-secondary rounded-pill"><?= htmlspecialchars($fileExtension) ?></span>
|
||||
<?php elseif ($isPDF): ?>
|
||||
<a class="text-info-emphasis" href="pdf.php?file=<?= urlencode($currentPath . '/' . $file) ?>&type=pdf">
|
||||
<a class="text-info-emphasis" href="pdf.php?file=<?= urlencode(rtrim($currentPath, '/') . '/' . $file) ?>&type=pdf">
|
||||
<?= htmlspecialchars($file) ?>
|
||||
</a>
|
||||
<span class="badge bg-danger rounded-pill">PDF</span>
|
||||
@@ -261,28 +262,28 @@ require_once __DIR__ . '/../../includes/workspace.php';
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text"><?= formatBytes($sftp->stat($currentPath . '/' . $file)['size']) ?></span>
|
||||
<span class="text"><?= formatBytes($sftp->stat(rtrim($currentPath, '/') . '/' . $file)['size']) ?></span>
|
||||
</td>
|
||||
<td>
|
||||
<?php if (isset($_SESSION["delPer"]) && $_SESSION["delPer"] == true) : ?>
|
||||
<form method="POST" action="delete.php" style="display:inline;">
|
||||
<input type="hidden" name="delete" value="<?= htmlspecialchars($currentPath . '/' . $file) ?>">
|
||||
<input type="hidden" name="delete" value="<?= htmlspecialchars(rtrim($currentPath, '/') . '/' . $file) ?>">
|
||||
<button type="submit" class="btn btn-danger mt-1 mb-1" onclick="confirmDelete(event)">Delete</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_SESSION["downPer"]) && $_SESSION["downPer"] == true) : ?>
|
||||
<form method="POST" action="download.php" style="display:inline;">
|
||||
<input type="hidden" name="file" value="<?= htmlspecialchars($currentPath . '/' . $file) ?>">
|
||||
<input type="hidden" name="file" value="<?= htmlspecialchars(rtrim($currentPath, '/') . '/' . $file) ?>">
|
||||
<button type="submit" class="btn btn-success mt-1 mb-1">Download</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["upPer"]) && $_SESSION["upPer"] == true) : ?>
|
||||
<button type="button" class="btn btn-warning mt-1 mb-1" onclick="openRenameModal('<?= htmlspecialchars(addslashes($file)) ?>', '<?= htmlspecialchars(addslashes($currentPath . '/' . $file)) ?>')">Rename</button>
|
||||
<button type="button" class="btn btn-warning mt-1 mb-1" onclick="openRenameModal('<?= htmlspecialchars(addslashes($file)) ?>', '<?= htmlspecialchars(addslashes(rtrim($currentPath, '/') . '/' . $file)) ?>')">Rename</button>
|
||||
<?php endif; ?>
|
||||
<?php if ($isArchive && isset($_SESSION["upPer"]) && $_SESSION["upPer"] == true) : ?>
|
||||
<form method="POST" action="extract.php" style="display:inline;">
|
||||
<input type="hidden" name="archive" value="<?= htmlspecialchars($currentPath . '/' . $file) ?>">
|
||||
<input type="hidden" name="archive" value="<?= htmlspecialchars(rtrim($currentPath, '/') . '/' . $file) ?>">
|
||||
<button type="submit" class="btn btn-info mt-1 mb-1">Extract</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -52,7 +52,7 @@ if (!empty($filePath) && $sftp->file_exists($filePath) && !$sftp->is_dir($filePa
|
||||
|
||||
$showLineNumbers = in_array(strtolower($extension), ['php', 'js', 'html', 'css', 'py', 'java', 'c', 'cpp', 'h', 'hpp', 'rb', 'sh', 'xml', 'json']);
|
||||
|
||||
$parentDir = dirname($filePath);
|
||||
$parentDir = remoteDirname($filePath);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
@@ -134,7 +134,7 @@ if (isset($_GET['stream'])) {
|
||||
'title' => $fileName,
|
||||
'description' => 'Browse your document without leaving the workspace.',
|
||||
'connected' => true,
|
||||
'back' => 'index.php?path=' . urlencode(dirname($filePath)),
|
||||
'back' => 'index.php?path=' . urlencode(remoteDirname($filePath)),
|
||||
'class' => 'pdf-page',
|
||||
]); ?>
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
die("Missing required information for renaming.");
|
||||
}
|
||||
|
||||
$dirPath = dirname($oldPath);
|
||||
$dirPath = remoteDirname($oldPath);
|
||||
$oldName = basename($oldPath);
|
||||
|
||||
$newPath = $dirPath . '/' . $newName;
|
||||
|
||||
@@ -20,7 +20,7 @@ function createDirectoryRecursive($sftp, $path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$parent = dirname($path);
|
||||
$parent = remoteDirname($path);
|
||||
if ($parent != '/' && !$sftp->is_dir($parent)) {
|
||||
createDirectoryRecursive($sftp, $parent);
|
||||
}
|
||||
@@ -91,7 +91,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!empty($relativePath)) {
|
||||
$fileName = basename($relativePath);
|
||||
|
||||
$dirPart = dirname($relativePath);
|
||||
$dirPart = remoteDirname($relativePath);
|
||||
if ($dirPart !== '.' && $dirPart !== '') {
|
||||
$remoteDirPath = $currentPath . '/' . $dirPart;
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ if (isset($_POST['createShare'])) {
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$shareUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]" .
|
||||
dirname($_SERVER['PHP_SELF']) . "/shared.php?token=$token";
|
||||
remoteDirname($_SERVER['PHP_SELF']) . "/shared.php?token=$token";
|
||||
|
||||
$_SESSION['shareCreated'] = true;
|
||||
$_SESSION['shareUrl'] = $shareUrl;
|
||||
@@ -274,7 +274,7 @@ if (isset($_GET['stream'])) {
|
||||
'title' => $fileName,
|
||||
'description' => 'Preview your media, download a copy or create a shared link.',
|
||||
'connected' => true,
|
||||
'back' => 'index.php?path=' . urlencode(dirname($filePath)),
|
||||
'back' => 'index.php?path=' . urlencode(remoteDirname($filePath)),
|
||||
'class' => 'media-page',
|
||||
]); ?>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user