1+ using ImageMagick ;
12using Serilog ;
23
34namespace PrivatePdfConverter . Services ;
45
56public static class FileService
67{
8+ // Conservative defaults chosen to allow typical high-resolution images
9+ // while rejecting obviously pathological dimensions before full decode.
10+ private const ulong MaxWidth = 10_000 ;
11+ private const ulong MaxHeight = 10_000 ;
12+ private const ulong MaxArea = 100_000_000 ;
13+
714 public static IEnumerable < string > ValidExtensions { get ; } =
815 [
916 "jpg" , "jpeg" , "bmp" , "gif" , "png" , "tif" , "tiff" , "webp"
@@ -12,6 +19,35 @@ public static class FileService
1219 public static bool IsImage ( this string ? extension )
1320 => ! string . IsNullOrEmpty ( extension ) && ValidExtensions . Contains ( extension . ToLower ( ) [ 1 ..] ) ;
1421
22+ public static MagickImage ? LoadValidatedImage ( string path )
23+ {
24+ using var headerImage = new MagickImage ( ) ;
25+ headerImage . Ping ( path ) ;
26+
27+ var width = headerImage . Width ;
28+ var height = headerImage . Height ;
29+ var area = ( ulong ) width * height ;
30+
31+ if ( width == 0 || height == 0 )
32+ {
33+ Log . Logger . Error ( "Image '{Path}' has invalid dimensions {Width}x{Height}." , path , width , height ) ;
34+ return null ;
35+ }
36+
37+ if ( width > MaxWidth || height > MaxHeight || area > MaxArea )
38+ {
39+ Log . Logger . Error (
40+ "Image '{Path}' exceeds the supported limits ({Width}x{Height}, area {Area})." ,
41+ path ,
42+ width ,
43+ height ,
44+ area ) ;
45+ return null ;
46+ }
47+
48+ return new MagickImage ( path ) ;
49+ }
50+
1551 public static IEnumerable < string > LoadFilePathsFromDirectory ( this string path , string searchPattern = "*" )
1652 {
1753 var files = Directory . GetFiles ( path , searchPattern ) . ToList ( ) ;
0 commit comments