@@ -251,6 +251,13 @@ int png_wasm_encode_buffer(
251251 png_set_IHDR (png , info , width , height , 8 , color_type ,
252252 PNG_INTERLACE_NONE , PNG_COMPRESSION_TYPE_DEFAULT , PNG_FILTER_TYPE_DEFAULT );
253253
254+ // Set compression parameters for better stability
255+ png_set_compression_level (png , Z_DEFAULT_COMPRESSION );
256+ png_set_compression_method (png , Z_DEFLATED );
257+ png_set_compression_strategy (png , Z_DEFAULT_STRATEGY );
258+ png_set_compression_window_bits (png , 15 );
259+ png_set_compression_mem_level (png , 8 );
260+
254261 // Write header
255262 png_write_info (png , info );
256263
@@ -362,20 +369,46 @@ static void png_static_read_callback(png_structp png, png_bytep data, size_t len
362369static void png_static_write_callback (png_structp png , png_bytep data , size_t length ) {
363370 png_write_state_t * state = (png_write_state_t * )png_get_io_ptr (png );
364371
372+ // Validate state and input parameters
373+ if (!state || !data || length == 0 ) {
374+ png_error (png , "Invalid write callback parameters" );
375+ return ;
376+ }
377+
378+ // Prevent unreasonably large allocations (> 100MB for safety)
379+ if (length > 100 * 1024 * 1024 || state -> size > 100 * 1024 * 1024 ) {
380+ png_error (png , "PNG output too large - possible corruption" );
381+ return ;
382+ }
383+
384+ // Check for integer overflow
385+ if (state -> size + length < state -> size ) {
386+ png_error (png , "Size overflow in PNG write callback" );
387+ return ;
388+ }
389+
365390 // Grow buffer if needed
366391 if (state -> size + length > state -> capacity ) {
367392 size_t new_capacity = (state -> capacity == 0 ) ? 8192 : state -> capacity * 2 ;
368393 while (new_capacity < state -> size + length ) {
369394 new_capacity *= 2 ;
395+ // Prevent runaway growth
396+ if (new_capacity > 100 * 1024 * 1024 ) {
397+ png_error (png , "PNG buffer grew too large - possible corruption" );
398+ return ;
399+ }
370400 }
371401
372- state -> buffer = (unsigned char * )realloc (state -> buffer , new_capacity );
373- if (!state -> buffer ) {
374- png_error (png , "Memory allocation failed" );
402+ unsigned char * new_buffer = (unsigned char * )realloc (state -> buffer , new_capacity );
403+ if (!new_buffer ) {
404+ png_error (png , "Memory allocation failed in PNG write callback" );
405+ return ;
375406 }
407+ state -> buffer = new_buffer ;
376408 state -> capacity = new_capacity ;
377409 }
378410
411+ // Safe memory copy
379412 memcpy (state -> buffer + state -> size , data , length );
380413 state -> size += length ;
381414}
0 commit comments