Пытался подделать загруженный файл, создавая временный файл tmpfile, открывая его через fwrite передавая в массив $_FILES все данные об этом файле.
Но функция move_uploaded_file всё равно возвращает false.
Задумываясь об этом, решил посмотреть исходники move_uploaded_file но там сложно что-то разобрать.
Задался вопросом как вообще можно отлаживать функции из ядра, чтоб получить больше сведений почему она возвращает false, причины этого, но не получилось найти чего-либо значимого.
Хотелось бы узнать об этом от многоуважаемой публики.
Для правильного вопроса надо знать половину ответа
tmpfile
...
The file is automatically removed when closed (for example, by calling fclose(), or when there are no remaining references to the file handle returned by tmpfile()), or when the script ends.
Так что, скорее всего, вы закрыли файл и он автоматически удалился. Либо вы держите его открытым на запись и он, соответственно, не перемещается.
Это здесь не при чем. Он пытается подделать загрузку (причем очень смешным и наивным способом, но это не важно). Подделка не будет работать в любом случае - с временным файлом, или постоянным, закрытым, открытым, существующим или отсутствующим - без разницы.
FanatPHP, Угу. Сейчас посмотрел код PHP, там при получении запроса от сервера создаётся хэш (temp_name => temp_name) для всех полученных файлов. При любой операции идёт проверка наличия temp_name в этом хэше.
То есть, свой файл можно попробовать подсунуть только вместо одного из принятых.
Rsa97, все равно не получится. Код я не смотрел, но пробовал много лет назад на место временного файла подсунуть свой с тем же именем - пхп уже не признает за своего :)
Там, видимо, еще какая-то проверка есть.
PHP_FUNCTION(move_uploaded_file)
{
char *path, *new_path;
size_t path_len, new_path_len;
zend_bool successful = 0;
// Здесь проверка на наличие самого хэша
if (!SG(rfc1867_uploaded_files)) {
RETURN_FALSE;
}
ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_STRING(path, path_len)
Z_PARAM_PATH(new_path, new_path_len)
ZEND_PARSE_PARAMETERS_END();
// Здесь проверяется, что в хэше есть путь к временному файлу
if (!zend_hash_str_exists(SG(rfc1867_uploaded_files), path, path_len)) {
RETURN_FALSE;
}
// Проверяется наличие каталога для записи файла
if (php_check_open_basedir(new_path)) {
RETURN_FALSE;
}
// Попытка переместить или скопировать файл
if (VCWD_RENAME(path, new_path) == 0) {
successful = 1;
} else if (php_copy_file_ex(path, new_path, STREAM_DISABLE_OPEN_BASEDIR) == SUCCESS) {
VCWD_UNLINK(path);
successful = 1;
}
// При успешной попытке файл удаляется из хэша, при неудачной - записывается ошибка
if (successful) {
zend_hash_str_del(SG(rfc1867_uploaded_files), path, path_len);
} else {
php_error_docref(NULL, E_WARNING, "Unable to move '%s' to '%s'", path, new_path);
}
RETURN_BOOL(successful);
}
Спасибо. Я утром искал свою заметку про те свои мучения, но не нашел и бросил. А зря, потому что тогда бы ерунды не писал. Сейчас напрягся и нашел - я, оказывается, хотел сделать прозрачную загрузку архивов, и подсовывать в move_uploaded_file файлы по одному. И там у меня первый как раз копировался, а остальные - нет, и теперь понятно почему - из хэша удаляются.
8 лет назад было :)