From e8708736c03adde1887d074f7b862145a8127eb5 Mon Sep 17 00:00:00 2001 From: imcraftsman Date: Fri, 17 Jan 2025 20:49:35 +0800 Subject: [PATCH 1/7] Update tinyfilemanager.php running envirement: Android 4.4+PHP 7.4.3+ KSWEB http://192.168.1.2/tinyfilemanager.php, afer login,the main page could not be showed entirely,it just shows half of navigation bar. that's becuase of there are two same lines of codes which cause the problem. they are $owner = posix_getpwuid(fileowner($path . '/' . $f)); when the funciton fileowner($path . '/' . $f) return 0 and run the function posix_getpwuid(....), it trig an error. please check the codes in line 2156--2168 and 2221--2233 suggest replace these two parts with followed codes: $owner = array('name' => '?'); $group = array('name' => '?'); if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) { try{ $owner_id = fileowner($path . '/' . $f); if($owner_id != 0) { $owner_info = posix_getpwuid($owner_id); if ($owner_info) { $owner = $owner_info; } } $group_id = filegroup($path . '/' . $f); $group_info = posix_getgrgid($group_id); if ($group_info) { $group = $group_info; } } catch(Exception $e){ error_log("exception:" . $e->getMessage()); } } --- tinyfilemanager.php | 60 ++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/tinyfilemanager.php b/tinyfilemanager.php index e6633e7f..7111dea8 100644 --- a/tinyfilemanager.php +++ b/tinyfilemanager.php @@ -2153,19 +2153,29 @@ class="edit-file"> '?'); + $group = array('name' => '?'); if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) { - $owner = posix_getpwuid(fileowner($path . '/' . $f)); - $group = posix_getgrgid(filegroup($path . '/' . $f)); - if ($owner === false) { - $owner = array('name' => '?'); + try{ + $owner_id = fileowner($path . '/' . $f); + if($owner_id != 0) { + $owner_info = posix_getpwuid($owner_id); + if ($owner_info) { + $owner = $owner_info; + } + } + + $group_id = filegroup($path . '/' . $f); + $group_info = posix_getgrgid($group_id); + if ($group_info) { + $group = $group_info; + } + + } catch(Exception $e){ + error_log("exception:" . $e->getMessage()); } - if ($group === false) { - $group = array('name' => '?'); - } - } else { - $owner = array('name' => '?'); - $group = array('name' => '?'); } + ?> @@ -2218,19 +2228,29 @@ class="edit-file"> '?'); + $group = array('name' => '?'); if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) { - $owner = posix_getpwuid(fileowner($path . '/' . $f)); - $group = posix_getgrgid(filegroup($path . '/' . $f)); - if ($owner === false) { - $owner = array('name' => '?'); + try{ + $owner_id = fileowner($path . '/' . $f); + if($owner_id != 0) { + $owner_info = posix_getpwuid($owner_id); + if ($owner_info) { + $owner = $owner_info; + } + } + + $group_id = filegroup($path . '/' . $f); + $group_info = posix_getgrgid($group_id); + if ($group_info) { + $group = $group_info; + } + + } catch(Exception $e){ + error_log("exception:" . $e->getMessage()); } - if ($group === false) { - $group = array('name' => '?'); - } - } else { - $owner = array('name' => '?'); - $group = array('name' => '?'); } + ?> From f4f7a22ac1fadd0715999ea1c360b13b731ff99f Mon Sep 17 00:00:00 2001 From: imcraftsman Date: Wed, 22 Jan 2025 22:58:41 +0800 Subject: [PATCH 2/7] add proxy to show image/vedio out of the webserver root directory add proxy to show image/vedio out of the webserver root directory when we login as an ordinary client, our folders which assigned by the administrator are usually not in the webserver root directory. so, we could not get the file's hyperlink, and we could not preview our pictures and watch our video online. now, the problem is solved. I add a proxy to settle this. modified list: 1) add a proxy; 2) modify image's/video's hyperlinks 3) modify file's 'direct link' related with open button. in addition: There is a clerical error in lin "$fileTypes['jfif'] = 'image/jpg';" it should be "$fileTypes['jfif'] = 'image/jfif';" in my another PR(PR id= #1269) --- tinyfilemanager.php | 122 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 9 deletions(-) diff --git a/tinyfilemanager.php b/tinyfilemanager.php index 7111dea8..fbffb4cb 100644 --- a/tinyfilemanager.php +++ b/tinyfilemanager.php @@ -458,6 +458,79 @@ function getClientIP() /*************************** ACTIONS ***************************/ +// file proxy +if (isset($_GET['proxy_file'])) { + header('Access-Control-Allow-Origin: *'); + header('Access-Control-Allow-Methods: GET'); + + function sanitizePath($path) { + if (substr($path, 0, 1) !== '/') { + die('Invalid file path.'); + } + if ($path === '/') + return '/'; + return realpath($path); + } + + // get file path + $filePath = isset($_GET['path'])?$_GET['path']:"/"; + + $filePath = sanitizePath($filePath); + + if ($filePath === false || !file_exists($filePath)) { + http_response_code(404); + die('File not found or inaccessible.'); + } + + if (is_dir($filePath)) { + // if it is dir,list the content + $fileList = getFileList($filePath); + echo generateDirectoryListing($filePath, $fileList); + exit; + } else { + // if it is image or vedio file ,return the immage file content + if (!is_readable($filePath)) { + http_response_code(403); + die("File is not readable."); + } + $mimeType = mime_content_type($filePath); + header('Content-Type: ' . $mimeType); + header('Content-Length: ' . filesize($filePath)); + readfile($filePath); + exit; + } +} + +// get file lists +function getFileList($dir) +{ + $files = array(); + $entries = scandir($dir); + foreach ($entries as $entry) { + if ($entry != "." && $entry != "..") { + $files[] = $entry; + } + } + return $files; +} +// create file lists HTML +function generateDirectoryListing($dir, $fileList) +{ + $html = "Index of {$dir}"; + $html .= "

Index of {$dir}



"; + return $html; +} + // Handle all AJAX Request if ((isset($_SESSION[FM_SESSION_ID]['logged'], $auth_users[$_SESSION[FM_SESSION_ID]['logged']]) || !FM_USE_AUTH) && isset($_POST['ajax'], $_POST['token']) && !FM_READONLY) { if (!verifyToken($_POST['token'])) { @@ -1816,8 +1889,14 @@ function getSelected($l) Delete - - " target="_blank"> +

'; + if (in_array($ext, array('gif', 'jpg', 'jpeg','jfif', 'png', 'bmp', 'ico', 'svg', 'webp', 'avif'))) { + if($_SERVER['DOCUMENT_ROOT'] === $root_path){ + echo '

'; + } + else{ + echo '

'; + } } } elseif ($is_audio) { // Audio content @@ -2209,7 +2295,16 @@ class="edit-file"> " href="#" onclick="rename('', '');return false;"> - + + >
- + if (in_array(strtolower(pathinfo($f, PATHINFO_EXTENSION)), array('gif', 'jpg', 'jpeg','jfif', 'png', 'bmp', 'ico', 'svg', 'webp', 'avif'))): ?> + @@ -2290,7 +2385,14 @@ class="edit-file"> ..." href="?p=&copy="> - + @@ -2907,6 +3009,7 @@ function fm_get_file_icon_class($path) case 'gif': case 'jpg': case 'jpeg': + case 'jfif': case 'jpc': case 'jp2': case 'jpx': @@ -3104,7 +3207,7 @@ function fm_get_file_icon_class($path) */ function fm_get_image_exts() { - return array('ico', 'gif', 'jpg', 'jpeg', 'jpc', 'jp2', 'jpx', 'xbm', 'wbmp', 'png', 'bmp', 'tif', 'tiff', 'psd', 'svg', 'webp', 'avif'); + return array('ico', 'gif', 'jpg', 'jpeg','jfif', 'jpc', 'jp2', 'jpx', 'xbm', 'wbmp', 'png', 'bmp', 'tif', 'tiff', 'psd', 'svg', 'webp', 'avif'); } /** @@ -3288,6 +3391,7 @@ function fm_get_file_mimes($extension) $fileTypes['gif'] = 'image/gif'; $fileTypes['png'] = 'image/png'; $fileTypes['jpeg'] = 'image/jpg'; + $fileTypes['jfif'] = 'image/jfif'; $fileTypes['jpg'] = 'image/jpg'; $fileTypes['webp'] = 'image/webp'; $fileTypes['avif'] = 'image/avif'; From ae8abd661bd98bc56790e1a347a8c05783dfdb23 Mon Sep 17 00:00:00 2001 From: imcraftsman Date: Thu, 23 Jan 2025 16:44:35 +0800 Subject: [PATCH 3/7] Update tinyfilemanager.php simplify the method of calling proxy --- tinyfilemanager.php | 45 ++++++++++----------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/tinyfilemanager.php b/tinyfilemanager.php index fbffb4cb..2c8101ce 100644 --- a/tinyfilemanager.php +++ b/tinyfilemanager.php @@ -1796,6 +1796,7 @@ function getSelected($l) $file_url = FM_ROOT_URL . fm_convert_win((FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file); $file_path = $path . '/' . $file; + $file_url = ($_SERVER['DOCUMENT_ROOT'] === $root_path) ? $file_url : ('?p=&proxy_file=1&path=' . urlencode($file_path)); $ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION)); $mime_type = fm_get_mime_type($file_path); @@ -1889,14 +1890,8 @@ function getSelected($l) Delete - - " target="_blank"> +

'; - } - else{ - echo '

'; - } + echo '

'; } } elseif ($is_audio) { // Audio content @@ -2295,16 +2283,10 @@ class="preview-img">

'; - - + +

';
- + @@ -2385,14 +2367,7 @@ class="preview-img">

';
- + From cbf761691f2280a61442074c08bb243b2097e2f7 Mon Sep 17 00:00:00 2001 From: imcraftsman Date: Mon, 3 Feb 2025 20:50:57 +0800 Subject: [PATCH 4/7] Update tinyfilemanager.php 0)update from https://github.com/prasathmani/tinyfilemanager 1) modify proxy, add some codes to adapt isset($_SERVER['HTTP_RANGE']) 2)add new function --- album. --- tinyfilemanager.php | 341 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 291 insertions(+), 50 deletions(-) diff --git a/tinyfilemanager.php b/tinyfilemanager.php index 2c8101ce..cd93465d 100644 --- a/tinyfilemanager.php +++ b/tinyfilemanager.php @@ -97,7 +97,7 @@ $favicon_path = ''; // Files and folders to excluded from listing -// e.g. array('myfile.html', 'personal-folder', '*.php', ...) +// e.g. array('myfile.html', 'personal-folder', '*.php', '/path/to/folder', ...) $exclude_items = array(); // Online office Docs Viewer @@ -151,6 +151,9 @@ // External CDN resources that can be used in the HTML (replace for GDPR compliance) $external = array( + 'css-photoswipe' => '', + 'js-photoswipe-lightbox' => 'https://cdn.jsdelivr.net/npm/photoswipe@5.4.3/dist/photoswipe-lightbox.esm.js', + 'js-photoswipe-module' => 'https://cdn.jsdelivr.net/npm/photoswipe@5.4.3/dist/photoswipe.esm.js', 'css-bootstrap' => '', 'css-dropzone' => '', 'css-font-awesome' => '', @@ -459,7 +462,7 @@ function getClientIP() /*************************** ACTIONS ***************************/ // file proxy -if (isset($_GET['proxy_file'])) { +if (isset($_GET['proxy_file'])) { header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET'); @@ -467,14 +470,14 @@ function sanitizePath($path) { if (substr($path, 0, 1) !== '/') { die('Invalid file path.'); } - if ($path === '/') - return '/'; + if ($path === '/') { + return '/'; + } return realpath($path); } - // get file path - $filePath = isset($_GET['path'])?$_GET['path']:"/"; - + // get file path + $filePath = isset($_GET['path']) ? $_GET['path'] : "/"; $filePath = sanitizePath($filePath); if ($filePath === false || !file_exists($filePath)) { @@ -488,16 +491,45 @@ function sanitizePath($path) { echo generateDirectoryListing($filePath, $fileList); exit; } else { - // if it is image or vedio file ,return the immage file content if (!is_readable($filePath)) { http_response_code(403); die("File is not readable."); } $mimeType = mime_content_type($filePath); header('Content-Type: ' . $mimeType); - header('Content-Length: ' . filesize($filePath)); - readfile($filePath); - exit; + $fileSize = filesize($filePath); + header("Accept-Ranges: bytes"); + if (isset($_SERVER['HTTP_RANGE'])) { + list(, $range) = explode("=", $_SERVER['HTTP_RANGE'], 2); + list($start, $end) = explode("-", $range); + $start = intval($start); + $end = ($end === '') ? $fileSize - 1 : intval($end); + + if ($start > $end || $start >= $fileSize || $end >= $fileSize) { + header("HTTP/1.1 416 Range Not Satisfiable"); + header("Content-Range: bytes */$fileSize"); + exit; + } + + $length = $end - $start + 1; + $file = fopen($filePath, 'rb'); + fseek($file, $start); + + header("HTTP/1.1 206 Partial Content"); + header("Content-Length: $length"); + header("Content-Range: bytes $start-$end/$fileSize"); + + while (!feof($file) && ($p = ftell($file)) <= $end) { + echo fread($file, min(1024 * 16, $end - $p + 1)); + flush(); + } + fclose($file); + exit; + } else { + header("Content-Length: $fileSize"); + readfile($filePath); + exit; + } } } @@ -1407,7 +1439,7 @@ function get_file_path() $folders = array(); $files = array(); $current_path = array_slice(explode("/", $path), -1)[0]; -if (is_array($objects) && fm_is_exclude_items($current_path)) { +if (is_array($objects) && fm_is_exclude_items($current_path, $path)) { foreach ($objects as $file) { if ($file == '.' || $file == '..') { continue; @@ -1416,9 +1448,9 @@ function get_file_path() continue; } $new_path = $path . '/' . $file; - if (@is_file($new_path) && fm_is_exclude_items($file)) { + if (@is_file($new_path) && fm_is_exclude_items($file, $new_path)) { $files[] = $file; - } elseif (@is_dir($new_path) && $file != '.' && $file != '..' && fm_is_exclude_items($file)) { + } elseif (@is_dir($new_path) && $file != '.' && $file != '..' && fm_is_exclude_items($file, $new_path)) { $folders[] = $file; } } @@ -1535,6 +1567,212 @@ function getUploadExt() exit; } +//album form +if (isset($_GET['photoalbum']) && !FM_READONLY) { + fm_show_header(); // HEADER + fm_show_nav_path(FM_PATH); // current path + //get the allowed file extensions + +/** + * create Thumbnail + * + * @param string $filePath Original image path + * @param string $thumbnailPath Thumbnail save path + * @param array $size Original image size + */ +function createThumbnail($filePath, $thumbnailPath, $size) { + // Check if thumbnail already exists + if (file_exists($thumbnailPath)) { + return; + } + + // Determine which imagecreatefrom function to use + $createFunc = null; + switch (strtolower(pathinfo($filePath, PATHINFO_EXTENSION))) { + case 'jpg': + case 'jpeg': + case 'jfif': + $createFunc = 'imagecreatefromjpeg'; + break; + case 'png': + $createFunc = 'imagecreatefrompng'; + break; + case 'gif': + $createFunc = 'imagecreatefromgif'; + break; + case 'webp': + $createFunc = 'imagecreatefromwebp'; + break; + case 'bmp': + $createFunc = 'imagecreatefrombmp'; + break; + } + + if ($createFunc && function_exists($createFunc)) { + $sourceImage = @$createFunc($filePath); + if ($sourceImage === false) { + return; // Skip if image cannot be loaded + } + + // Create thumbnail + $thumbWidth = 110; + $thumbHeight = 90; + $thumbImage = imagecreatetruecolor($thumbWidth, $thumbHeight); + + // Handle transparent background + imagealphablending($thumbImage, false); + imagesavealpha($thumbImage, true); + $transparent = imagecolorallocatealpha($thumbImage, 255, 255, 255, 127); + imagefilledrectangle($thumbImage, 0, 0, $thumbWidth, $thumbHeight, $transparent); + + // Scale the image + if (!imagecopyresampled($thumbImage, $sourceImage, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $size[0], $size[1])) { + imagedestroy($sourceImage); + imagedestroy($thumbImage); + return; + } + + // Save the thumbnail + $saveFunc = null; + switch (strtolower(pathinfo($filePath, PATHINFO_EXTENSION))) { + case 'jpg': + case 'jpeg': + case 'jfif': + $saveFunc = 'imagejpeg'; + break; + case 'png': + $saveFunc = 'imagepng'; + break; + case 'gif': + $saveFunc = 'imagegif'; + break; + case 'webp': + $saveFunc = 'imagewebp'; + break; + case 'bmp': + $saveFunc = 'imagebmp'; + break; + } + + if ($saveFunc && function_exists($saveFunc)) { + $saveFunc($thumbImage, $thumbnailPath); + } + + // Clean up resources + imagedestroy($sourceImage); + imagedestroy($thumbImage); + } +} + +function generateThumbnails($dir) { + $images = []; + + // Check if the directory is "thumbnails", skip unnecessary processing + $isThumbnailsDir = (basename($dir) === 'thumbnails'); + + // Get all files in the directory + $files = scandir($dir); + if ($files === false) { + return $images; + } + + // If not "thumbnails", create a thumbnails directory + if (!$isThumbnailsDir) { + $thumbnailsDir = $dir . '/thumbnails'; + if (!is_dir($thumbnailsDir) && !mkdir($thumbnailsDir, 0755, true)) { + echo "Error: Unable to create thumbnails directory '$thumbnailsDir'
"; + return false; + } + } + + // Iterate over the files in the directory + foreach ($files as $file) { + if ($file === '.' || $file === '..') { + continue; // Ignore current and parent directories + } + + $filePath = $dir . '/' . $file; + + // Check if it's a supported image file + if (is_file($filePath) && preg_match('/\.(jpg|jpeg|png|gif|jfif|bmp|webp)$/i', $file)) { + $size = @getimagesize($filePath); + if ($size === false) { + continue; // Skip if image info cannot be obtained + } + + // Add image info to the results array + $fileName = basename($filePath); + $images[] = ['src' => $fileName, 'width' => $size[0], 'height' => $size[1]]; + + // If not "thumbnails" directory, create thumbnails + if (!$isThumbnailsDir) { + $thumbnailPath = $thumbnailsDir . '/' . $fileName; + createThumbnail($filePath, $thumbnailPath, $size); + } + } + } + + return $images; +} + + + ?> + + +

+ + +

+ + + + + +:
  • :
  • -
  • File size:
  • -
  • MIME-type:
  • +
  • :
  • +
  • :
  • +
  • :
  • '?'); $group = array('name' => '?'); if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) { - try{ + try { $owner_id = fileowner($path . '/' . $f); - if($owner_id != 0) { + if ($owner_id != 0) { $owner_info = posix_getpwuid($owner_id); - if ($owner_info) { - $owner = $owner_info; - } - } - + if ($owner_info) { + $owner = $owner_info; + } + } $group_id = filegroup($path . '/' . $f); $group_info = posix_getgrgid($group_id); if ($group_info) { - $group = $group_info; - } - - } catch(Exception $e){ - error_log("exception:" . $e->getMessage()); + $group = $group_info; + } + } catch (Exception $e) { + error_log("exception:" . $e->getMessage()); } } - ?> @@ -2284,7 +2520,7 @@ class="edit-file"> ..." href="?p=&copy="> @@ -2308,26 +2544,23 @@ class="edit-file"> '?'); $group = array('name' => '?'); if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) { - try{ + try { $owner_id = fileowner($path . '/' . $f); - if($owner_id != 0) { + if ($owner_id != 0) { $owner_info = posix_getpwuid($owner_id); - if ($owner_info) { - $owner = $owner_info; - } - } - + if ($owner_info) { + $owner = $owner_info; + } + } $group_id = filegroup($path . '/' . $f); $group_info = posix_getgrgid($group_id); if ($group_info) { - $group = $group_info; - } - - } catch(Exception $e){ - error_log("exception:" . $e->getMessage()); + $group = $group_info; + } + } catch (Exception $e) { + error_log("exception:" . $e->getMessage()); } } - ?> @@ -2747,12 +2980,13 @@ function fm_get_display_path($file_path) /** * Check file is in exclude list - * @param string $file + * @param string $name The name of the file/folder + * @param string $path The full path of the file/folder * @return bool */ -function fm_is_exclude_items($file) +function fm_is_exclude_items($name, $path) { - $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if (isset($exclude_items) and sizeof($exclude_items)) { unset($exclude_items); } @@ -2761,7 +2995,7 @@ function fm_is_exclude_items($file) if (version_compare(PHP_VERSION, '7.0.0', '<')) { $exclude_items = unserialize($exclude_items); } - if (!in_array($file, $exclude_items) && !in_array("*.$ext", $exclude_items)) { + if (!in_array($name, $exclude_items) && !in_array("*.$ext", $exclude_items) && !in_array($path, $exclude_items)) { return true; } return false; @@ -3840,6 +4074,9 @@ function fm_show_nav_path($path) +