@@ -316,6 +316,20 @@ public function testExtensionOk(): void
316316 $ this ->assertTrue ($ this ->validation ->run ([]));
317317 }
318318
319+ public function testExtensionOkWithMatchingClientExtensionAndMimeType (): void
320+ {
321+ $ payload = $ this ->createGifPayload ();
322+
323+ try {
324+ $ this ->setUploadedAvatar ($ payload , 'my-avatar.gif ' );
325+
326+ $ this ->validation ->setRules (['avatar ' => 'ext_in[avatar,gif] ' ]);
327+ $ this ->assertTrue ($ this ->validation ->run ([]));
328+ } finally {
329+ unlink ($ payload );
330+ }
331+ }
332+
319333 public function testExtensionNotOk (): void
320334 {
321335 $ this ->validation ->setRules (['avatar ' => 'ext_in[avatar,xls,doc,ppt] ' ]);
@@ -327,4 +341,72 @@ public function testExtensionImpossible(): void
327341 $ this ->validation ->setRules (['avatar ' => 'ext_in[unknown,xls,doc,ppt] ' ]);
328342 $ this ->assertFalse ($ this ->validation ->run ([]));
329343 }
344+
345+ public function testExtensionFailsForMismatchedClientExtension (): void
346+ {
347+ $ payload = $ this ->createGifPayload ();
348+
349+ try {
350+ $ this ->setUploadedAvatar ($ payload , 'shell.php ' );
351+
352+ $ this ->validation ->setRules (['avatar ' => 'ext_in[avatar,gif] ' ]);
353+ $ this ->assertFalse ($ this ->validation ->run ([]));
354+ } finally {
355+ unlink ($ payload );
356+ }
357+ }
358+
359+ public function testExtensionFailsForAllowedButMimeIncompatibleClientExtension (): void
360+ {
361+ $ payload = $ this ->createGifPayload ();
362+
363+ try {
364+ $ this ->setUploadedAvatar ($ payload , 'my-avatar.jpg ' );
365+
366+ $ this ->validation ->setRules (['avatar ' => 'ext_in[avatar,jpg,gif] ' ]);
367+ $ this ->assertFalse ($ this ->validation ->run ([]));
368+ } finally {
369+ unlink ($ payload );
370+ }
371+ }
372+
373+ public function testExtensionFailsForExtensionlessClientFilename (): void
374+ {
375+ $ payload = $ this ->createGifPayload ();
376+
377+ try {
378+ $ this ->setUploadedAvatar ($ payload , 'my-avatar ' );
379+
380+ $ this ->validation ->setRules (['avatar ' => 'ext_in[avatar,gif] ' ]);
381+ $ this ->assertFalse ($ this ->validation ->run ([]));
382+ } finally {
383+ unlink ($ payload );
384+ }
385+ }
386+
387+ private function createGifPayload (): string
388+ {
389+ $ payload = tempnam (sys_get_temp_dir (), 'ci4-upload-poc- ' );
390+ $ this ->assertIsString ($ payload );
391+
392+ $ gif = base64_decode ('R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw== ' , true );
393+ $ this ->assertIsString ($ gif );
394+
395+ file_put_contents ($ payload , $ gif );
396+
397+ return $ payload ;
398+ }
399+
400+ private function setUploadedAvatar (string $ payload , string $ name ): void
401+ {
402+ service ('superglobals ' )->setFilesArray ([
403+ 'avatar ' => [
404+ 'tmp_name ' => $ payload ,
405+ 'name ' => $ name ,
406+ 'size ' => filesize ($ payload ),
407+ 'type ' => 'image/gif ' ,
408+ 'error ' => UPLOAD_ERR_OK ,
409+ ],
410+ ]);
411+ }
330412}
0 commit comments