symfony/http-kernelをアップデートしたらJPEGファイルのLaravel MIMEバリデーションが通らなくなった
発生した事象
Laravelアプリケーションにて、symfony/http-kernel ライブラリをアップデートしたら
ファイルアップロード時のバリデーションで、JPEGファイルがバリデーションで落ちるようになった。
原因
該当箇所は Illuminate\Foundation\Http\FormRequest
を継承したクラスにて
public function rules()
{
return [
'file' => 'required|mimes:jpeg,png',
];
}
と記載していた。
symfony/http-kernel
ライブラリをアップデートしたところ
依存ライブラリとして、symfony/mime
もバージョンが上がり
以下コミットが含まれていた。
[Mime] Prefer .jpg instead of .jpeg · symfony/mime@aa1d922
@@ -1320,7 +1320,7 @@ public function guessMimeType(string $path): ?string
'image/ief' => ['ief'],
'image/jls' => ['jls'],
'image/jp2' => ['jp2', 'jpg2'],
- 'image/jpeg' => ['jpeg', 'jpg', 'jpe'],
+ 'image/jpeg' => ['jpg', 'jpeg', 'jpe'],
'image/jpeg2000' => ['jp2', 'jpg2'],
'image/jpeg2000-image' => ['jp2', 'jpg2'],
'image/jph' => ['jph'],
このコミットが入ったのは、v5.2.0
これがなぜ影響するかというと、ファイルアップロード時のMIMEの判定は
以下の場所で行っている。
return MimeTypes::getDefault()->getExtensions($this->getClientMimeType())[0] ?? null;
MimeTypes::getDefault()->getExtensions()
で返ってきた配列の最初の要素([0]でデリファレンスしている)で判定している。
で、この実装はどうなっているかというと
public function getExtensions(string $mimeType): array
{
if ($this->extensions) {
$extensions = $this->extensions[$mimeType] ?? $this->extensions[$lcMimeType = strtolower($mimeType)] ?? null;
}
return $extensions ?? self::$map[$mimeType] ?? self::$map[$lcMimeType ?? strtolower($mimeType)] ?? [];
}
となっていて、通常は self::$map[$mimeType]
が返る。
この MimeTypes::$map
配列が、冒頭であげたコミットで image/jpeg
キーの配列の最初の要素が jpeg
から jpg
に変わってしまったため
LaravelのRule定義で required|mimes:jpeg,png
を満たさなくなり、バリデーションエラーになってしまっていた。
対応方法
rule定義を jpeg
から jpg
に変えるか、併記する。
public function rules()
{
return [
'file' => 'required|mimes:jpeg,jpg,png',
];
}
蛇足
該当のコミット、コミッターを見ると、Fabien Potencier。
お・・・おぅ・・・
そんな「.jpegより.jpgの方がいいよね」なんて軽いノリで変えないでくれよ… 😭
Discussion