@@ -18,6 +18,7 @@ import (
1818 "strconv"
1919 "strings"
2020 "testing"
21+ "time"
2122
2223 "github.com/bep/imagemeta"
2324 "github.com/rwcarlsen/goexif/exif"
@@ -61,7 +62,8 @@ func TestDecodeAllImageFormats(t *testing.T) {
6162
6263func TestDecodeWebP (t * testing.T ) {
6364 c := qt .New (t )
64- tags := extractTags (t , "sunrise.webp" , imagemeta .EXIF | imagemeta .IPTC | imagemeta .XMP )
65+ tags , err := extractTags (t , "sunrise.webp" , imagemeta .EXIF | imagemeta .IPTC | imagemeta .XMP )
66+ c .Assert (err , qt .IsNil )
6567
6668 c .Assert (tags .EXIF ()["Copyright" ].Value , qt .Equals , "Bjørn Erik Pedersen" )
6769 c .Assert (tags .EXIF ()["ApertureValue" ].Value , eq , 5.6 )
@@ -83,7 +85,8 @@ func TestDecodeJPEG(t *testing.T) {
8385 return true
8486 }
8587
86- tags := extractTagsWithFilter (t , "sunrise.jpg" , imagemeta .EXIF | imagemeta .IPTC | imagemeta .XMP , shouldInclude )
88+ tags , err := extractTagsWithFilter (t , "sunrise.jpg" , imagemeta .EXIF | imagemeta .IPTC | imagemeta .XMP , shouldInclude )
89+ c .Assert (err , qt .IsNil )
8790
8891 c .Assert (tags .EXIF ()["Copyright" ].Value , qt .Equals , "Bjørn Erik Pedersen" )
8992 c .Assert (tags .EXIF ()["ApertureValue" ].Value , eq , 5.6 )
@@ -99,7 +102,8 @@ func TestDecodePNG(t *testing.T) {
99102 return true
100103 }
101104
102- tags := extractTagsWithFilter (t , "sunrise.png" , imagemeta .EXIF | imagemeta .IPTC | imagemeta .XMP , shouldInclude )
105+ tags , err := extractTagsWithFilter (t , "sunrise.png" , imagemeta .EXIF | imagemeta .IPTC | imagemeta .XMP , shouldInclude )
106+ c .Assert (err , qt .IsNil )
103107
104108 c .Assert (len (tags .EXIF ()), qt .Equals , 61 )
105109 c .Assert (len (tags .IPTC ()), qt .Equals , 14 )
@@ -119,7 +123,8 @@ func TestThumbnailOffset(t *testing.T) {
119123 }
120124
121125 offset := func (filename string ) uint32 {
122- tags := extractTagsWithFilter (t , filename , imagemeta .EXIF , shouldHandle )
126+ tags , err := extractTagsWithFilter (t , filename , imagemeta .EXIF , shouldHandle )
127+ c .Assert (err , qt .IsNil )
123128 return tags .EXIF ()["ThumbnailOffset" ].Value .(uint32 )
124129 }
125130
@@ -132,7 +137,8 @@ func TestThumbnailOffset(t *testing.T) {
132137func TestDecodeTIFF (t * testing.T ) {
133138 c := qt .New (t )
134139
135- tags := extractTags (t , "sunrise.tif" , imagemeta .EXIF | imagemeta .IPTC | imagemeta .XMP )
140+ tags , err := extractTags (t , "sunrise.tif" , imagemeta .EXIF | imagemeta .IPTC | imagemeta .XMP )
141+ c .Assert (err , qt .IsNil )
136142
137143 c .Assert (len (tags .EXIF ()), qt .Equals , 76 )
138144 c .Assert (len (tags .XMP ()), qt .Equals , 146 )
@@ -307,7 +313,8 @@ func TestDecodeNamespace(t *testing.T) {
307313 return true
308314 }
309315
310- tags := extractTagsWithFilter (t , "sunrise.jpg" , imagemeta .EXIF | imagemeta .IPTC | imagemeta .XMP , shouldInclude )
316+ tags , err := extractTagsWithFilter (t , "sunrise.jpg" , imagemeta .EXIF | imagemeta .IPTC | imagemeta .XMP , shouldInclude )
317+ c .Assert (err , qt .IsNil )
311318
312319 c .Assert (tags .EXIF ()["Artist" ].Namespace , qt .Equals , "IFD0" )
313320 c .Assert (tags .EXIF ()["GPSLatitude" ].Namespace , qt .Equals , "IFD0/GPSInfoIFD" )
@@ -376,10 +383,25 @@ func TestDecodeIPTCOrientationOnly(t *testing.T) {
376383 c .Assert (len (tags .IPTC ()), qt .Equals , 1 )
377384}
378385
386+ func TestDecodeLargeExifTimeout (t * testing.T ) {
387+ c := qt .New (t )
388+
389+ withOpts := func (opts * imagemeta.Options ) {
390+ opts .Timeout = time .Duration (500 * time .Millisecond )
391+
392+ // Set the limits to something high to make sure we time out.
393+ opts .LimitNumTags = 1000000
394+ opts .LimitTagSize = 10000000
395+ }
396+ _ , err := extractTags (t , "largeexif.png" , imagemeta .EXIF , withOpts )
397+ c .Assert (err , qt .ErrorMatches , "timed out after 500ms" )
398+ }
399+
379400func TestDecodeXMPJPG (t * testing.T ) {
380401 c := qt .New (t )
381402
382- tags := extractTags (t , "sunrise.jpg" , imagemeta .XMP )
403+ tags , err := extractTags (t , "sunrise.jpg" , imagemeta .XMP )
404+ c .Assert (err , qt .IsNil )
383405
384406 c .Assert (len (tags .EXIF ()) == 0 , qt .IsTrue )
385407 c .Assert (len (tags .IPTC ()) == 0 , qt .IsTrue )
@@ -437,14 +459,15 @@ func TestGoldenTagCountXMP(t *testing.T) {
437459func TestLatLong (t * testing.T ) {
438460 c := qt .New (t )
439461
440- tags := extractTags (t , "sunrise.jpg" , imagemeta .EXIF )
462+ tags , err := extractTags (t , "sunrise.jpg" , imagemeta .EXIF )
441463
442464 lat , long , err := tags .GetLatLong ()
443465 c .Assert (err , qt .IsNil )
444466 c .Assert (lat , eq , float64 (36.59744166 ))
445467 c .Assert (long , eq , float64 (- 4.50846 ))
446468
447- tags = extractTags (t , "goexif/geodegrees_as_string.jpg" , imagemeta .EXIF )
469+ tags , err = extractTags (t , "goexif/geodegrees_as_string.jpg" , imagemeta .EXIF )
470+ c .Assert (err , qt .IsNil )
448471 lat , long , err = tags .GetLatLong ()
449472 c .Assert (err , qt .IsNil )
450473 c .Assert (lat , eq , float64 (52.013888888 ))
@@ -454,7 +477,7 @@ func TestLatLong(t *testing.T) {
454477func TestGetDateTime (t * testing.T ) {
455478 c := qt .New (t )
456479
457- tags := extractTags (t , "sunrise.jpg" , imagemeta .EXIF )
480+ tags , err := extractTags (t , "sunrise.jpg" , imagemeta .EXIF )
458481 d , err := tags .GetDateTime ()
459482 c .Assert (err , qt .IsNil )
460483 c .Assert (d .Format ("2006-01-02" ), qt .Equals , "2017-10-27" )
@@ -512,7 +535,8 @@ func assertGoldenInfoTagCount(t testing.TB, filename string, sources imagemeta.S
512535 return true
513536 }
514537
515- tags := extractTagsWithFilter (t , filename , sources , shouldHandle )
538+ tags , err := extractTagsWithFilter (t , filename , sources , shouldHandle )
539+ c .Assert (err , qt .IsNil )
516540 all := tags .All ()
517541
518542 // Our XMP parsing is currently a little limited so be a little lenient with the assertions.
@@ -587,7 +611,8 @@ func assertGoldenInfoTagCount(t testing.TB, filename string, sources imagemeta.S
587611
588612func compareWithExiftoolOutput (t testing.TB , filename string , sources imagemeta.Source ) {
589613 c := qt .New (t )
590- tags := extractTags (t , filename , sources )
614+ tags , err := extractTags (t , filename , sources )
615+ c .Assert (err , qt .IsNil )
591616 all := tags .All ()
592617 tagsGolden := readGoldenInfo (t , filename )
593618
@@ -731,15 +756,17 @@ func extToFormat(ext string) imagemeta.ImageFormat {
731756 }
732757}
733758
734- func extractTags (t testing.TB , filename string , sources imagemeta.Source ) imagemeta.Tags {
759+ func extractTags (t testing.TB , filename string , sources imagemeta.Source , opts ... withOptions ) ( imagemeta.Tags , error ) {
735760 shouldHandle := func (ti imagemeta.TagInfo ) bool {
736761 // Drop the thumbnail tags.
737762 return ti .Namespace != "IFD1"
738763 }
739- return extractTagsWithFilter (t , filename , sources , shouldHandle )
764+ return extractTagsWithFilter (t , filename , sources , shouldHandle , opts ... )
740765}
741766
742- func extractTagsWithFilter (t testing.TB , filename string , sources imagemeta.Source , shouldHandle func (ti imagemeta.TagInfo ) bool ) imagemeta.Tags {
767+ type withOptions func (opts * imagemeta.Options )
768+
769+ func extractTagsWithFilter (t testing.TB , filename string , sources imagemeta.Source , shouldHandle func (ti imagemeta.TagInfo ) bool , opts ... withOptions ) (imagemeta.Tags , error ) {
743770 t .Helper ()
744771 if ! filepath .IsAbs (filename ) {
745772 filename = filepath .Join ("testdata" , "images" , filename )
@@ -770,9 +797,14 @@ func extractTagsWithFilter(t testing.TB, filename string, sources imagemeta.Sour
770797 panic (errors .New (s ))
771798 }
772799
773- err = imagemeta .Decode (imagemeta.Options {R : f , ImageFormat : imageFormat , ShouldHandleTag : shouldHandle , HandleTag : handleTag , Warnf : warnf , Sources : sources })
800+ imgOpts := imagemeta.Options {R : f , ImageFormat : imageFormat , ShouldHandleTag : shouldHandle , HandleTag : handleTag , Warnf : warnf , Sources : sources }
801+ for _ , opt := range opts {
802+ opt (& imgOpts )
803+ }
804+
805+ err = imagemeta .Decode (imgOpts )
774806 if err != nil {
775- t . Fatal ( fmt . Errorf ( "failed to decode %q: %w" , filename , err ))
807+ return tags , err
776808 }
777809
778810 // See https://github.com/gohugoio/hugo/issues/12741 and https://github.com/golang/go/issues/59627
@@ -788,7 +820,7 @@ func extractTagsWithFilter(t testing.TB, filename string, sources imagemeta.Sour
788820 t .Fatal (fmt .Errorf ("failed to marshal tags in %q to JSON: %w" , filename , err ))
789821 }
790822
791- return tags
823+ return tags , nil
792824}
793825
794826func readGoldenInfo (t testing.TB , filename string ) goldenFileInfo {
0 commit comments