ゆず日記

戦う Vimmer 兼 Dvorakユーザ 兼 Kinesisユーザ 兼 おぺらー が戦わないブログ

file, Fileinfo に依る Office 2007+ ファイルの MIME TYPE 判定のバージョン差異について

システムコマンドの file と、PHP の Fileinfo のバージョン差異に依る Office 2007+ ファイル(docx, xlsx, pptxとか)の MIME TYPE について。

結論

長いので結論から。

file - 5.06 5.07 - 5.12 5.13 -
docx application/zip application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document
xlsx application/zip application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
pptx application/zip application/vnd.ms-powerpoint application/vnd.openxmlformats-officedocument.presentationml.presentation


php 5.4.14, 5.5.0 (libmagic 5.14) 5.4.x, 5.5.x, 5.6.0 (libmagic 5.17)
docx application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document
xlsx application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
pptx application/vnd.ms-powerpoint application/vnd.openxmlformats-officedocument.presentationml.presentation

5.4系と5.5系のどのマイナーバージョンで libmagic 5.17に変わってるのかまで追ってないが、最新の ver. では5.17相当だった。

MIME TYPE 判定を行う fileコマンド や PHP の Fileinfo は、バージョンアップの際に Office 2007+ ファイルの判定に変化がある可能性がある。 MIME TYPE チェックを行っている環境では、docx, xlsx, pptx のテストファイルとテスト実行するコードを用意して置いて、バージョンアップ前後で変化が無いか確認できる体制を整えていた方が良さそうだ。

file コマンド

システムコマンドから MIME TYPE が調べられる file コマンド ( The Fine Free File Command )*1

Vagrant 上で試してみた。 file-5.11 は CentOS 6 用の yum パッケージが配布されてなかったので CentOS 7 でテスト。

# CentOS 6
[vagrant@localhost ~]$ file -v
file-5.04
magic file from /etc/magic:/usr/share/misc/magic

[vagrant@localhost ~]$ file --mime-type test.xlsx
test.xlsx: application/zip

# CentOS 7
[vagrant@localhost ~]$ file -v
file-5.11
magic file from /etc/magic:/usr/share/misc/magic

[vagrant@localhost ~]$ file --mime-type test.xlsx
test.xlsx: application/vnd.ms-excel

file 5.04 - 5.11間で magic データベースが更新された模様。

file/file · GitHub を見て調べてみた結果、5.07 で add msooxml stuff. · 726ddc3 · file/file · GitHub が追加されており、Office 2007+ の MIME TYPE が変わっている。

ちなみに、 fix mime types. (Thomas Ledoux) · 55feed3 · file/file · GitHub を見る限り 5.13 からはまた Office 周りの MIME TYPE が変わっているハズ。 CentOS 6 標準の yum リポジトリでは file-5.04 が最新なので、これからCentOS 7 に環境を変えた際にハマる人が多いのではないか。

とはいえ Webサービスなどで直接システムコマンドを実行することは基本やらないと思う。

PHP

PHP 5.4.14 と 5.4.29 で挙動が違う。

[vagrant@localhost ~]$ php -a
Interactive mode enabled

php > $finfo = new finfo(FILEINFO_MIME_TYPE);
php > $finfofile = $finfo->file('test.xlsx');
php > print $finfofile;
// PHP 5.4.14: "application/vnd.ms-excel"
// PHP 5.4.29: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

PHP の Fileinfo 関数使用時の挙動と magic データベースの参照先

PHP の Fileinfo 関数で使用される magic データベースの参照先は、以下の順で変更される。

  1. 引数指定した場合: 指定された magic データベースファイル
  2. 引数指定しなかった場合: 環境変数$MAGIC に設定されたパスの先にある magic データベースファイル
  3. 引数指定せず、$MAGIC 未使用の場合: PHP 組み込みの magic データベース

PHP: finfo_open - Manual

基本的には引数も環境変数も使用せず、PHP組み込みの magic データベースを使っていることと思う。

PHP の libmagic について

PHP の magic データベース (libmagic) の更新は PHP: PHP 5 ChangeLog 内にも記載の通り、マイナーバージョンのアップでも頻繁に行われている様子。

で、PHP の libmagic だが php-src/create_data_file.php at master · php/php-src · GitHub を見るとどうやらコミッターの環境で file に含まれる magic を元に PHP 向けにカスタマイズして生成した data_file.c なるものを、 PHP 組み込みの libmagic として扱ってる模様。

しかし php-src/data_file.c at master · php/php-src · GitHub を見てもなんのこっちゃなので、どのバージョンで何が変わったのかリポジトリから追うのは難しそう。

ところが data_file.c 単体の git 履歴は殆どなく、libmagic 5.14アップデート時, 5.17アップデート時のgitコメントログがある程度である。 これは PHP: PHP 5 ChangeLog 内の libmagic 関連の記述とピッタリあってるので、丁度 libmagic 5.14, 5.17 変更時に Office 2007+ 関連の出力がこの時に変更されたとみて良さそうだ。

git コメントログ記載の libmagic ver. と ChangeLog 記載の libmagic ver. を関連付けた結果は冒頭の結論の通り。

libmagic 5.17については ChangeLog には書いてないが 5.4系, 5.5系 でも最新の MIME TYPE 判別に変更されてるようなのだが、もしどのマイナーアップデート時に変更があったかまで知りたい場合には、該当 Commit Log がどのバージョンで merge されたのか tig とか git log -p data_file.c で追えば分かりそうだが不毛なのでここまで。

ちなみに PHP では組み込みで libmagic を持っていたが、他言語ではどのようにして MIME TYPE 判別を行うライブラリの管理をしているのか非常に気になる所である。

*1:ググラビリティが低いのが特徴