php - 在 CentOS Linux 上以二进制模式写入的疯狂 PHP fopen / fwrite / file_put_contents / move_uploaded_file 错误将 0x0D 添加到每个 0x0A
问题描述
似乎无论我在fopen
mode
标志中设置什么设置,该文件都会不断将 0x0D 添加到我保存的二进制文件中。
它不仅影响fopen
/ fwrite
.. 也影响file_put_contents
.
file_get_contents
我以为是问题一开始.. 但事实证明这个实际上工作正常.. 因为当我使用 bin2hex() 转储文件时,结果很好。
起初我将std::string
这个错误归咎于 C++ 中的.. 但事实证明它甚至与 C++ 没有任何关系,但它实际上是 PHP 的错误,或者可能只有 CentOS linux,我还没有找到解决方案将我的文件存储在二进制文件中。我能做的最好的事情是十六进制字符串转储文件。
看看我的代码和截图。
$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 解决此问题的一些hackery,它可以很好地转储它)。
这是 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
解决方案
推荐阅读
- html - 对无序列表中的每一行使用 :not(:last-child):after 伪元素
- sql - UPDATE 语句中的 SQL 案例表达式
- html - 单击表格行 - 选择复选框
- charts - Heatbar,文本的动态位置偏移
- ansible - debian systemd:ceph-osd@x.service:在步骤 LIMITS 生成 /usr/lib/ceph/ceph-osd-prestart.sh 时失败:不允许操作
- javascript - AppModule 中导入的共享模块
- javascript - 如何实现div与另一个div重叠?
- ruby-on-rails - ActiveStorage 和直接上传在开发中不起作用
- php - 使用按钮复制表单
- html - 模式不适用于只读属性