Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 比较两条路径的开头并不';我不能正常工作_Php - Fatal编程技术网

Php 比较两条路径的开头并不';我不能正常工作

Php 比较两条路径的开头并不';我不能正常工作,php,Php,我正在创建一个简单的网站,允许我的用户上传和下载文件。我创建了一个简单的检查,以避免用户在/srv/public/目录之外“疑惑”,但是该检查只阻止人们退出/srv/目录(当用户导航到/srv/或/srv/private/等时,它会忽略) 检查用户指定的路径是否正确的代码是: $dir = "/srv/public/"; if(!isset($_POST['path'])){ $_POST['path'] = '/'; } $path = realpath($dir . $_POST[

我正在创建一个简单的网站,允许我的用户上传和下载文件。我创建了一个简单的检查,以避免用户在
/srv/public/
目录之外“疑惑”,但是该检查只阻止人们退出
/srv/
目录(当用户导航到
/srv/
/srv/private/
等时,它会忽略)

检查用户指定的路径是否正确的代码是:

$dir = "/srv/public/";

if(!isset($_POST['path'])){
    $_POST['path'] = '/';
}
$path = realpath($dir . $_POST['path']);
if(!substr($path, 0, 12) === $dir){ //This seems to never get executed
    $path = realpath($dir);
}
if(!file_exists($path)){
    $path = realpath($dir);
}
$path = rtrim($path, '/') . '/';
如果用户在允许的
/srv/public/
范围之外好奇,我想将他们的路径设置回
/srv/public/

以下是网站的完整代码:

<?php

include("../functions.php");

if(!isLoggedIn($db)){
    header("location: /custom/403.php", true, 403);
    die();
}

$stmt = $db->prepare("SELECT permission FROM permissions WHERE userid=? AND permission='file.public.download'");
$stmt->bind_param("i", $_SESSION['userid']);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows == 0){
    header("location: /custom/403.php", true, 403);
    die();
}
$stmt->close();
$dir = "/srv/public/";

if(isset($_GET['action'])){
    if($_GET['action'] == 'download' && isset($_GET['path'])){
        $filepath = realpath($dir . $_GET['path']);
        if(substr($filepath, 0, 12) === $dir){
            if(file_exists($filepath)){
                ini_set("auto_detect_line_endings", true);
                header('Content-Description: File Transfer');
                header('Content-Type: application/octet-stream');
                header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
                header('Expires: 0');
                header('Cache-Control: must-revalidate');
                header('Pragma: public');
                header('Content-Length: ' . filesize($filepath));
                readfile($filepath);
                die();
            }else{
                header("location /custom/404.php", true, 404);
            }
        }else{
            //the location is outside the allowed path.
            header("location /custom/403.php", true, 403);
            die();
        }
    }
}

include("../include/header.php");


if(!isset($_POST['path'])){
    $_POST['path'] = '/';
}
$path = realpath($dir . $_POST['path']);
if(!substr($path, 0, 12) === $dir){
    $path = realpath($dir);
}
if(!file_exists($path)){
    $path = realpath($dir);
}
$path = rtrim($path, '/') . '/';
?>


<link href="/styles/wintools-firefox.css" type="text/css" rel="stylesheet">
<script src="/scripts/wintools.js"></script>

<div id="header">
    <form action="public.php" method="post" style="display: inline-block">
        <input type="hidden" value="<?php echo(substr($path, 11)."../"); ?>" name="path">
        <input type="submit" value="back">
    </form>
    <form action="public.php" method="post" style="display: inline-block">
        <input type="text" value="<?php echo(substr($path, 11)); ?>" name="path">
        <input type="submit" value="Go">
    </form>
</div>
<div id="content">
    <?php


    $files = scandir($path);
    unset($files[array_search(".", $files, true)]);
    unset($files[array_search("..", $files, true)]);
    foreach($files as $file){
        if(is_dir($path.$file."/")){
            echo("<form style='display: inline-block;' name='".$file."' action='public.php' method='post'><input type='hidden' name='path' value='".$_POST['path'].$file."'><div class='folder' onclick='document.forms[\"".$file."\"].submit();'><div class='title'>".$file."</div></div></form>");
        }else{
            echo("<div class='folder' style='background-image: url(\"../images/file.png\")' onclick='window.location=\"public.php?action=download&path=".$file."\"'><div class='title'>".$file."</div></div>");
        }
    }
    ?>
</div>
<?php

include("../include/footer.php");

?>


您需要提取子字符串并将其与
$dir
进行比较:

if(substr($path, 0, 12) != $dir){
您当前的代码是:

if(
!substr($path, 0, 12) /* returns a string and then negates it ! which results in false */
 === $dir){           /* false does NOT === $dir */
要查看,请执行以下操作:

var_dump(substr($path, 0, 12));
var_dump(!substr($path, 0, 12));
var_dump(!substr($path, 0, 12) === $dir);
但只检查
$dir
是否以
$path
开头(包含并从位置0开始)可能更有意义:


你不应该建议strpos吗?哇,我真不敢相信我一个人花了将近两个小时才发现这件事这么简单。感谢您的快速解决方案,添加了@mickmackusa建议。
if(strpos($dir, $path) !== 0) {