疯狂的PHP fopen / fwrite / file_put_contents / move_uploaded_file错误,在CentOS Linux上以二进制模式编写,向每个0x0A添加0x0D

问题描述 投票:1回答:1

[无论我在fopen mode标志中设置了什么设置,文件似乎都在向保存的二进制文件中添加0x0D。

不仅影响fopen /fwrite..而且还影响file_put_contents

file_get_contents我以为是开始的问题..但事实证明,这实际上是可以的..因为当我使用bin2hex()转储文件时,它表现很好。

我最初将此错误归咎于C ++中的std::string。但事实证明,它甚至与C ++无关,但实际上是PHP或仅CentOS linux的错误,我有尚未找到将文件存储在二进制文件中的解决方案。最好的办法是有效的hexstring转储文件。

查看我的代码和屏幕截图。

$target_file = "/privatefiles/" . basename($_FILES["a"]["name"]);
$fileTypeExtension = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

//Check file extension.
if($fileTypeExtension != "dll" && $fileTypeExtension != "exe" ) die("ER");

// Check file size
if ($_FILES["a"]["size"] > 10*(1024*1024)) //10 MB cap
  die("ER");

//To decode a base64 encoded file (this was a quickfix to fix binary file encoding in C++ part).
$fileContent = file_get_contents($_FILES['a']['tmp_name']);
$fileContent = base64_decode($fileContent);

//fail
$fh = fopen("wtf1.bin", "wb");
fwrite($fh, $fileContent, strlen($fileContent));
fclose($fh);

//fail (exact result as top)
$fh = fopen("wtf2.bin", "wb");
$fileContent = bin2hex($fileContent);
for($i=0;$i<strlen($fileContent);$i+=2)
    fwrite($fh, chr(hexdec(substr($fileContent,$i,2))));
fclose($fh);

//good result.. but not binary
$fh = fopen("wtf3.bin", "w");
$fileContent = bin2hex(base64_decode(file_get_contents($_FILES['a']['tmp_name'])));
fwrite($fh, $fileContent);
fclose($fh);

//good result but not binary
file_put_contents($target_file, $fileContent); //good bin2hex.

//fail same as the top 2 fail's.
file_put_contents($target_file."_", file_get_contents($_FILES['a']['tmp_name'])); //bad same as wtf1.bin or wtf2.bin

[这是我的屏幕截图(证明了运行上述代码后发生的情况),并使用C ++应用程序启动了文件上传(无法进行错误处理,因为一开始我是使用原始二进制模式发送的。。然后在发生此0x0D 0x0A错误之后,我将其更改为base64编码以解决传输问题..事实证明这甚至不是问题,但实际上我相信是PHP问题。]

这里是原始二进制文件(未更改),这是我上传的文件(如您所见,我在0x0A 0x40停下来向您展示错误)。“原始”

这里是wtf1.bin(只需将base64_decode的一个简单的1衬线写入文件)就处于相同的偏移量。“

这里是wtf2.bin(我曾尝试使用bin2hex来解决此问题,从而很好地解决了此问题),偏移量相同。“

这里是wtf3.bin(bin2hex),在相同的偏移量下效果很好。 (0x846 / 2 = 0x423)(已确认相同的偏移量!)“

“

即使是这个简单的上传脚本,也使用0xA,0xD上传损坏的文件

<!DOCTYPE html>
<html>
<head>
  <title>Upload your files</title>
</head>
<body>
  <form enctype="multipart/form-data" action="test.php" method="POST">
    <p>Upload your file</p>
    <input type="file" name="uploaded_file"></input><br />
    <input type="submit" value="Upload"></input>
  </form>
</body>
</html>
<?php
  if(!empty($_FILES['uploaded_file']))
  {
    $path = basename( $_FILES['uploaded_file']['name']);
    print_r($_FILES);
    $size = filesize($_FILES['uploaded_file']['tmp_name']);
    echo "<br>size uploaded = " . $size . "<br>";
    if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $path)) {
      echo "The file ".  basename( $_FILES['uploaded_file']['name']). 
      " has been uploaded<br>";
      echo "path = " . $path . "<br>";
      echo "size stored = " . filesize($path);
    } else{
        echo "There was an error uploading the file, please try again!";
    }
  }
?>

当我以二进制格式上传这些字节时发生错误

BC 09 00 00 83 C4 04 BA E8 57 40 00 8D 64 24 00 8A 08 88 0A 40 42 84 C9

我回到服务器上

BC 09 00 00 83 C4 04 BA E8 57 40 00 8D 64 24 00 8A 08 88 0D 0A 40 42 84 C9

似乎无论我在fopen模式标志中进行什么设置,文件都会不断向保存的二进制文件中添加0x0D。它不仅影响fopen / fwrite ..而且还影响file_put_contents。 file_get_contents I ...

php fopen fwrite line-endings file-put-contents
1个回答
0
投票

感谢CBroe和IVO GELOV,问题出在我的FTP / SFTP客户端WinSCP中。我附上了一个屏幕截图,您需要关闭该设置以免出现此问题。

© www.soinside.com 2019 - 2024. All rights reserved.