PHP разрешен zip mimetypes

Я знаю (из ответа на этот вопрос: .rar, .zip files MIME Type ), что большинство людей проверяют zip-файлы в PHP как application/zip или application/octet-stream , но у меня есть несколько вопросов об этом:

  • безопасно просто проверить application/octet-stream (учитывая, что application/octet-stream можно использовать для описания многих других типов файлов, чем просто zip!). Я знаю, что могу проверить файл и другими способами, но подумал, что я должен попытаться сохранить все как можно проще
  • Я попытался проверить как можно больше различных фактических типов почтовых индексов; но есть некоторые, которые дают неожиданные результаты. Я нашел 1, для которого типом mime является application/x-external-editor , но у PHP есть проблемы с ним (хотя единственная ошибка, которую я получаю, это Warning: ZipArchive::close() [ziparchive.close]: Invalid or unitialized Zip object ) – это где-нибудь документировано? Есть ли список фактических x- mimetypes, с которыми может справиться PHP?

редактировать

В ответ на следующие вопросы:

  • Я проверяю тип mime, используя $_FILES['fileatt']['type'] , но с использованием mime_content_type() дает тот же результат. Различные zip-файлы выглядят как одно из следующих: 'application/zip' , 'application/x-compressed' , 'application/x-zip-compressed' , 'application/x-compressed' , 'multipart/x-zip' . Я не понял, почему у меня возникла ошибка, когда тип mime был обнаружен как application/x-external-editor .
  • У меня установлено расширение zip, и я извлекаю все файлы из zip-файлов при их загрузке. Я не думал о проверке ошибки.

Я также нашел другую вещь, которую я не совсем понимаю: когда я использую следующий код с файлом, который PHP читает как application/x-external-editor :

 if($zip->open($_FILES[fileatt]['tmp_name'])===TRUE) { echo "success"; } else { echo "error"; } 

печатает «ошибку», но проверяет тип файла как

 $res = $zip->open($_FILES[fileatt]['tmp_name']); if($res) { echo "success"; } else { echo "error"; } 

печатает «успех»; в этом коде я предполагаю, что логическое значение эффективно использует == , а не === , но почему это должно иметь значение?

Ошибка:

 $res = $zip->open($_FILES[fileatt]['tmp_name']); if($res===TRUE) { echo "success"; } else { echo $res; } 

печатает 19 – какая ошибка ( http://uk3.php.net/manual/en/ziparchive.open.php ) относится к ?!

Никогда не доверяйте типу mime, это может быть легко подделано клиентом. Они могли бы представить exe и дать ему тип mime text/plain если захотят.

Все zip-файлы начинаются со стандартной сигнатуры заголовка локального файла (0x04034b50), поэтому вы можете проверить, что первые 4 байта файла соответствуют байтам подписи zip. Дополнительную информацию см. В PKZIP Appnote .

Если у вас включено расширение zip , вы можете пойти еще дальше и попытаться открыть и прочитать zip, чтобы убедиться, что это полностью действующий почтовый файл.

Что-то вроде этого хорошо работает:

 $zip = zip_open('/path/to/file.zip'); if (is_int($zip)) { echo "Error $zip encountered reading the file, is it a valid zip?"; } else { echo "Thanks for uploading a valid zip file!"; } 

zip_open возвращает ресурс, если он открыт успешно, в противном случае целое число, представляющее ошибку, которая произошла при чтении файла.

РЕДАКТИРОВАТЬ: Поразмыслить над некоторыми из ваших вопросов:

О application/octet-stream : это, как вы сказали, очень общий тип. Это означает, что любой файл, содержащий 8-битные данные, в основном это все и что угодно. application/zip является стандартным типом mime-типа де-факто, но некоторые клиенты будут использовать другие значения, как вы обнаружили. Также, учитывая тот факт, что клиент может легко подделать любой тип файла для использования application/zip я бы не стал полагаться на $_FILES['fileatt']['type'] поскольку это может быть что угодно.

AFIK, mime_content_type() просто смотрит на расширение файла и сопоставляет его с типом mime из файла mime.types в системе или встроенным в PHP. Если кто-то поставил расширение .zip в exe файл, он все равно будет регистрироваться как application/zip . Я верю, что некоторые расширения могут рассматривать заголовок файла.

Zip::open() возвращает TRUE если файл был успешно открыт, или целочисленный код ошибки. Следовательно, == даст вам ложный положительный результат при ошибке, потому что любое ненулевое целое будет оценивать значение true, используя == поскольку оно будет отличать ненулевое целое число с TRUE . Если вы хотите проверить возврат из Zip::open вы всегда должны использовать $res === true , чтобы проверить успех. Вы можете найти значения кодов ошибок здесь в комментарии в нижней части страницы.

Bottom Line: Поскольку вы сказали, что вы уже извлекаете почтовый индекс, это может быть менее проблематичным для проверки на основе типа mime, но вместо этого было бы проще просто попытаться открыть файл и перейти на основе возвращаемого значения open , Если он вернет true, вы можете увидеть, что файл является допустимым zip (в этом случае, возможно, будут ошибки в файле, но они, по крайней мере, загрузили что-то похожее на zip-файл).

Надеюсь, что это поможет тебе.