在CentOS Linux上以二进制模式编写的疯狂PHP fopen/fwrite/file_put_contents/move_uploaded_file错误 [英] Crazy PHP fopen / fwrite / file_put_contents / move_uploaded_file bug with binary mode writing on CentOS Linux Adding 0x0D to every 0x0A

查看:130
本文介绍了在CentOS Linux上以二进制模式编写的疯狂PHP fopen/fwrite/file_put_contents/move_uploaded_file错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Seems the file keeps adding 0x0D to my saved binary files no matter what setting I put in the fopen mode flag.

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

It's not only affecting fopen/fwrite.. but also file_put_contents.

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

file_get_contents I thought was the problem to begin with.. but it turns out this one is actually working okay.. because when I dumped the file using bin2hex() it came out good.

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

I was blaming at first the std::string in C++ for this bug.. but it turns out it doesn't even have anything to do with C++ but it's in fact a bug with PHP or maybe with only CentOS linux and I have yet to find a solution to store my file in binary.. best I could do is hexstring dump file which works..

看看我的代码和屏幕截图.

Look at my code and screenshots.

$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问题.

Here are my screenshots (proof of what is happening from running the code above), and initiating a file upload using C++ application (which cannot be bugged because at first I sent using raw binary mode.. then after this 0x0D 0x0A bug I changed it to base64 encoding to fix the transfer problem.. and it turns out that wasn't even the problem, but in fact a PHP problem I believe..

这是原始二进制文件(未更改),这是我上传的文件(如您所见,我停在0x0A 0x40处,以显示错误).

Here is the original binary file (not altered) this is what I upload (as you can see I stop at 0x0A 0x40 to show you the bug).

这里是wtf1.bin(只需将base64_decode的一个简单1衬里文件)放在相同的偏移量处.

Here is wtf1.bin (Just a simple 1 liner of base64_decode to file) at same offset.

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

Here is wtf2.bin (Some hackery I tried to do to fix this problem using bin2hex which dumps it good) at same offset.

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

Here is wtf3.bin (bin2hex) which works good at same offset. (0x846 / 2 = 0x423) (same offset confirmed!)

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

Even this simple upload script, uploads corrupted files with 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!";
    }
  }
?>

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

Bug happens when I just upload these bytes in binary format

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 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

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

推荐答案

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

Thanks CBroe and IVO GELOV, The issue was in my FTP/SFTP Client WinSCP. I attached a screenshot which setting you need to turn off so this problem doesn't happen.

这篇关于在CentOS Linux上以二进制模式编写的疯狂PHP fopen/fwrite/file_put_contents/move_uploaded_file错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆