简介
-
PHP文件上传实现规范为RFC1867
-
实验环境为PHP 7.3.4 + nginx 1.20.1,关于上传部分的相关源码在github,PHP解析
multipart/form-data
请求体的入口函数在SAPI_POST_HANDLER_FUNC
-
PHP 调试环境参考
-
PHP 示例代码
<?php var_dump ( $_FILES ); ?>
-
文件解析的简要流程如下
技巧
前向截断
-
和
/
名处理文件名进行类似向截断info.txt/info.php
的文件经php后会info.php
-
调用栈如下
-
其中有一段注释如下,其本意是为了解决IE上传文件时所有路径名的问题
/* 只有在* 它是有效路径分隔符的情况下,win32 系统才需要在技术上进行 检查。然而,IE 总是 在用户的文件系统上发送文件的完整路径,这意味着除非 用户执行 basename(),否则他们会得到一个虚假的文件名。在 IE 的用户群将 * 降至零或问题得到修复之前,此代码必须为所有系统保持启用状态。*/
-
关键函数在php_ap_basename,该函数会寻找
和
/
显示最后出现的位置,并从该位置截断断字,导致造成了前向的截断
static char * php_ap_basename ( const zend_encoding * encoding , char * path ) {
char * s = strrchr ( path , '\' );
char * s2 = strrchr (路径, '/' );
if ( s && s2 ) {
if ( s > s2 ) {
++ s ;
} 其他 {
s = ++ s2 ;
}
返回 s ;
} else if ( s ) {
return ++ s ;
} else if ( s2 ) {
return ++ s2 ;
}
返回 路径;}
后向截断
-
00
的名字处理文件名进行后向截断类似info.php(00)xxx
的文件经php之后会变成info.php
-
在解析
header
的时候,只是对内存进行了拷贝,内存视图变成了
-
解析了中的时间长度,即表示表示,在
filename
使用时,内存中的字符串结束了,导致造成的断断续续strlen
filename
strlen
评论