@@ -324,6 +324,98 @@ public function testBomRemovalExactSequence()
324324 $ this ->assertTrue ( $ validatorWithSvg ->isValid ( $ svgEfBase64 ) );
325325 }
326326
327+ /**
328+ * Test data URI with line-wrapped base64 (common in email/MIME).
329+ */
330+ public function testDataUriWithLineWrappedBase64 ()
331+ {
332+ // PNG image with base64 wrapped at 76 characters (common MIME format)
333+ $ pngBase64Wrapped = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChw \nGA60e6kgAAAABJRU5ErkJggg== " ;
334+
335+ // Test with newline in base64 data
336+ $ dataUriWithNewline = 'data:image/png;base64, ' . $ pngBase64Wrapped ;
337+
338+ $ validator = new IsImage ();
339+ // Should pass - newlines are valid in base64 data URIs
340+ $ this ->assertTrue ( $ validator ->isValid ( $ dataUriWithNewline ) );
341+
342+ // Test with multiple newlines and spaces (also valid)
343+ $ pngBase64MultiLine = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJ \n" .
344+ "AAAADUlEQVR42mNkYPhfDwAChw \n" .
345+ "GA60e6kgAAAABJRU5ErkJggg== " ;
346+
347+ $ dataUriMultiLine = 'data:image/png;base64, ' . $ pngBase64MultiLine ;
348+ $ this ->assertTrue ( $ validator ->isValid ( $ dataUriMultiLine ) );
349+
350+ // Test with carriage return + newline (Windows style)
351+ $ pngBase64CRLF = str_replace ("\n" , "\r\n" , $ pngBase64Wrapped );
352+ $ dataUriCRLF = 'data:image/png;base64, ' . $ pngBase64CRLF ;
353+ $ this ->assertTrue ( $ validator ->isValid ( $ dataUriCRLF ) );
354+ }
355+
356+ /**
357+ * Test MIME type restrictions work for raw base64 input.
358+ */
359+ public function testMimeTypeRestrictionsForRawBase64 ()
360+ {
361+ // PNG image as raw base64
362+ $ pngBase64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg== ' ;
363+
364+ // JPEG image as raw base64
365+ $ jpegBase64 = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAr/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCdABmX/9k= ' ;
366+
367+ // Validator that only allows JPEG, even with checkImageData=false
368+ $ jpegOnlyValidator = new IsImage ( [ 'image/jpeg ' ], null , false );
369+
370+ // JPEG should pass
371+ $ this ->assertTrue ( $ jpegOnlyValidator ->isValid ( $ jpegBase64 ) );
372+
373+ // PNG should fail even with checkImageData=false
374+ $ this ->assertFalse ( $ jpegOnlyValidator ->isValid ( $ pngBase64 ) );
375+
376+ // Validator that only allows PNG
377+ $ pngOnlyValidator = new IsImage ( [ 'image/png ' ], null , false );
378+
379+ // PNG should pass
380+ $ this ->assertTrue ( $ pngOnlyValidator ->isValid ( $ pngBase64 ) );
381+
382+ // JPEG should fail
383+ $ this ->assertFalse ( $ pngOnlyValidator ->isValid ( $ jpegBase64 ) );
384+ }
385+
386+ /**
387+ * Test empty allowedMimeTypes with SVG doesn't restrict to SVG only.
388+ */
389+ public function testEmptyAllowedMimeTypesWithSvgAllowsAll ()
390+ {
391+ // Empty array means allow all types
392+ $ validatorAllowAll = new IsImage ( [], null , true , true );
393+
394+ // All image types should pass
395+ $ jpegBase64 = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAr/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCdABmX/9k= ' ;
396+ $ this ->assertTrue ( $ validatorAllowAll ->isValid ( $ jpegBase64 ) );
397+
398+ $ pngBase64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg== ' ;
399+ $ this ->assertTrue ( $ validatorAllowAll ->isValid ( $ pngBase64 ) );
400+
401+ $ gifBase64 = 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 ' ;
402+ $ this ->assertTrue ( $ validatorAllowAll ->isValid ( $ gifBase64 ) );
403+
404+ // SVG should also pass
405+ $ svgBase64 = base64_encode ( '<svg xmlns="http://www.w3.org/2000/svg"></svg> ' );
406+ $ this ->assertTrue ( $ validatorAllowAll ->isValid ( $ svgBase64 ) );
407+
408+ // Now test with allowSvg=false but empty allowedMimeTypes
409+ $ validatorNoSvg = new IsImage ( [], null , true , false );
410+
411+ // Non-SVG images should still pass
412+ $ this ->assertTrue ( $ validatorNoSvg ->isValid ( $ jpegBase64 ) );
413+ $ this ->assertTrue ( $ validatorNoSvg ->isValid ( $ pngBase64 ) );
414+
415+ // SVG should fail
416+ $ this ->assertFalse ( $ validatorNoSvg ->isValid ( $ svgBase64 ) );
417+ }
418+
327419 /**
328420 * Test malformed data URI.
329421 */
0 commit comments