@@ -262,9 +262,13 @@ impl CpuLimit {
262262}
263263
264264impl MemoryLimit {
265+ // Memory limit bounds: minimum 64KB, maximum 64GB (reasonable for WASM components)
266+ const MIN_MEMORY_BYTES : u64 = 64 * 1024 ; // 64KB
267+ const MAX_MEMORY_BYTES : u64 = 64u64 * 1024 * 1024 * 1024 ; // 64GB
268+
265269 /// Validate and convert memory limit to bytes
266270 pub fn to_bytes ( & self ) -> PolicyResult < u64 > {
267- match self {
271+ let bytes = match self {
268272 MemoryLimit :: String ( s) => {
269273 if s. is_empty ( ) {
270274 bail ! ( "Memory limit string cannot be empty" ) ;
@@ -287,16 +291,41 @@ impl MemoryLimit {
287291 . parse ( )
288292 . map_err ( |_| anyhow:: anyhow!( "Invalid memory value: {}" , s) ) ?;
289293
294+ if value == 0 {
295+ bail ! ( "Memory limit cannot be zero: {}" , s) ;
296+ }
297+
290298 value
291299 . checked_mul ( multiplier)
292- . ok_or_else ( || anyhow:: anyhow!( "Memory value too large: {}" , s) )
300+ . ok_or_else ( || anyhow:: anyhow!( "Memory value too large: {}" , s) ) ?
293301 }
294302 MemoryLimit :: Number ( n) => {
303+ if * n == 0 {
304+ bail ! ( "Memory limit cannot be zero" ) ;
305+ }
295306 // Assume legacy numeric values are in MB
296307 n. checked_mul ( 1024 * 1024 )
297- . ok_or_else ( || anyhow:: anyhow!( "Memory value too large: {}" , n) )
308+ . ok_or_else ( || anyhow:: anyhow!( "Memory value too large: {}" , n) ) ?
298309 }
310+ } ;
311+
312+ // Validate bounds
313+ if bytes < Self :: MIN_MEMORY_BYTES {
314+ bail ! (
315+ "Memory limit {} bytes is below minimum {} KB" ,
316+ bytes,
317+ Self :: MIN_MEMORY_BYTES / 1024
318+ ) ;
299319 }
320+ if bytes > Self :: MAX_MEMORY_BYTES {
321+ bail ! (
322+ "Memory limit {} bytes exceeds maximum {} GB" ,
323+ bytes,
324+ Self :: MAX_MEMORY_BYTES / ( 1024 * 1024 * 1024 )
325+ ) ;
326+ }
327+
328+ Ok ( bytes)
300329 }
301330}
302331
@@ -735,13 +764,16 @@ mod tests {
735764 let memory_gi = MemoryLimit :: String ( "2Gi" . to_string ( ) ) ;
736765 assert_eq ! ( memory_gi. to_bytes( ) . unwrap( ) , 2 * 1024 * 1024 * 1024 ) ;
737766
738- // Test Ti format
739- let memory_ti = MemoryLimit :: String ( "1Ti" . to_string ( ) ) ;
740- assert_eq ! ( memory_ti. to_bytes( ) . unwrap( ) , 1024u64 * 1024 * 1024 * 1024 ) ;
767+ // Test Gi format (larger value)
768+ let memory_gi_large = MemoryLimit :: String ( "32Gi" . to_string ( ) ) ;
769+ assert_eq ! (
770+ memory_gi_large. to_bytes( ) . unwrap( ) ,
771+ 32u64 * 1024 * 1024 * 1024
772+ ) ;
741773
742- // Test plain bytes
743- let memory_bytes = MemoryLimit :: String ( "1024 " . to_string ( ) ) ;
744- assert_eq ! ( memory_bytes. to_bytes( ) . unwrap( ) , 1024 ) ;
774+ // Test plain bytes (above minimum)
775+ let memory_bytes = MemoryLimit :: String ( "131072 " . to_string ( ) ) ; // 128KB
776+ assert_eq ! ( memory_bytes. to_bytes( ) . unwrap( ) , 131072 ) ;
745777
746778 // Test numeric format (legacy, assumes MB)
747779 let memory_numeric = MemoryLimit :: Number ( 512 ) ;
@@ -756,6 +788,21 @@ mod tests {
756788
757789 let invalid_number = MemoryLimit :: String ( "invalidMi" . to_string ( ) ) ;
758790 assert ! ( invalid_number. to_bytes( ) . is_err( ) ) ;
791+
792+ // Test bounds validation - too small
793+ let too_small = MemoryLimit :: String ( "32Ki" . to_string ( ) ) ; // 32KB < 64KB minimum
794+ assert ! ( too_small. to_bytes( ) . is_err( ) ) ;
795+
796+ // Test bounds validation - zero
797+ let zero_bytes = MemoryLimit :: String ( "0" . to_string ( ) ) ;
798+ assert ! ( zero_bytes. to_bytes( ) . is_err( ) ) ;
799+
800+ let zero_numeric = MemoryLimit :: Number ( 0 ) ;
801+ assert ! ( zero_numeric. to_bytes( ) . is_err( ) ) ;
802+
803+ // Test bounds validation - too large (128GB > 64GB maximum)
804+ let too_large = MemoryLimit :: String ( "128Gi" . to_string ( ) ) ;
805+ assert ! ( too_large. to_bytes( ) . is_err( ) ) ;
759806 }
760807
761808 #[ test]
0 commit comments