@@ -30,6 +30,18 @@ typedef struct coregraphics_animation_probe {
3030#define WEBP_LOOP2_IMAGE_PATH \
3131 "/tests/data/inputs/formats/animated-lossless-8x8-2frame-loop2-min.webp"
3232
33+ /*
34+ * Minimized fuzz payload that previously forced CoreGraphics indexed decoding
35+ * into a 4 GiB provider copy request.
36+ */
37+ static unsigned char const coregraphics_indexed_provider_oom_poc [33 ] = {
38+ 0x42 , 0x4d , 0x28 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
39+ 0x00 , 0x00 , 0x20 , 0x00 , 0x00 , 0x00 , 0x0c , 0x00 ,
40+ 0x00 , 0x00 , 0x02 , 0xff , 0xd8 , 0xff , 0x01 , 0x00 ,
41+ 0x01 , 0x00 , 0x00 , 0xbf , 0xff , 0x40 , 0x00 , 0x00 ,
42+ 0x00
43+ };
44+
3345typedef struct coregraphics_loop_sequence_probe {
3446 int callback_count ;
3547 int expected_count ;
@@ -2136,6 +2148,98 @@ run_coregraphics_cfindex_size_overflow_reject_test(void)
21362148 return SIXEL_FAILED (status ) ? 1 : 0 ;
21372149}
21382150
2151+ static int
2152+ run_coregraphics_indexed_provider_copy_oom_reject_test (void )
2153+ {
2154+ SIXELSTATUS status ;
2155+ sixel_allocator_t * allocator ;
2156+ sixel_loader_component_t * component ;
2157+ sixel_chunk_t chunk ;
2158+ int require_static ;
2159+ int use_palette ;
2160+ int reqcolors ;
2161+ loader_probe_callback_state_t callback_state ;
2162+ coregraphics_callback_count_probe_t probe ;
2163+
2164+ status = SIXEL_FALSE ;
2165+ allocator = NULL ;
2166+ component = NULL ;
2167+ memset (& chunk , 0 , sizeof (chunk ));
2168+ require_static = 0 ;
2169+ use_palette = 1 ;
2170+ reqcolors = 256 ;
2171+ callback_state .loader = NULL ;
2172+ callback_state .fn = NULL ;
2173+ callback_state .context = NULL ;
2174+ probe .callback_count = 0 ;
2175+
2176+ status = sixel_allocator_new (& allocator , NULL , NULL , NULL , NULL );
2177+ if (SIXEL_FAILED (status )) {
2178+ fprintf (stderr , "coregraphics: allocator initialization failed\n" );
2179+ return 1 ;
2180+ }
2181+
2182+ status = new_coregraphics_component (allocator , & component );
2183+ if (SIXEL_FAILED (status )) {
2184+ fprintf (stderr ,
2185+ "coregraphics: component init failed (%d)\n" ,
2186+ (int )status );
2187+ goto cleanup ;
2188+ }
2189+
2190+ status = sixel_loader_component_setopt (component ,
2191+ SIXEL_LOADER_OPTION_REQUIRE_STATIC ,
2192+ & require_static );
2193+ if (SIXEL_FAILED (status )) {
2194+ goto cleanup ;
2195+ }
2196+ status = sixel_loader_component_setopt (component ,
2197+ SIXEL_LOADER_OPTION_USE_PALETTE ,
2198+ & use_palette );
2199+ if (SIXEL_FAILED (status )) {
2200+ goto cleanup ;
2201+ }
2202+ status = sixel_loader_component_setopt (component ,
2203+ SIXEL_LOADER_OPTION_REQCOLORS ,
2204+ & reqcolors );
2205+ if (SIXEL_FAILED (status )) {
2206+ goto cleanup ;
2207+ }
2208+
2209+ chunk .buffer = (unsigned char * )(uintptr_t )
2210+ coregraphics_indexed_provider_oom_poc ;
2211+ chunk .size = sizeof (coregraphics_indexed_provider_oom_poc );
2212+ chunk .max_size = sizeof (coregraphics_indexed_provider_oom_poc );
2213+ chunk .source_path = NULL ;
2214+ chunk .allocator = allocator ;
2215+
2216+ callback_state .fn = capture_coregraphics_callback_count ;
2217+ callback_state .context = & probe ;
2218+ status = sixel_loader_component_load (component ,
2219+ & chunk ,
2220+ capture_frame_trampoline ,
2221+ & callback_state );
2222+ if (status != SIXEL_BAD_INPUT ) {
2223+ fprintf (stderr ,
2224+ "coregraphics: expected bad-input status, got %d\n" ,
2225+ (int )status );
2226+ status = SIXEL_FALSE ;
2227+ goto cleanup ;
2228+ }
2229+ if (probe .callback_count != 0 ) {
2230+ fprintf (stderr ,
2231+ "coregraphics: callback was invoked on indexed oom input\n" );
2232+ status = SIXEL_FALSE ;
2233+ goto cleanup ;
2234+ }
2235+ status = SIXEL_OK ;
2236+
2237+ cleanup :
2238+ sixel_loader_component_unref (component );
2239+ sixel_allocator_unref (allocator );
2240+ return SIXEL_FAILED (status ) ? 1 : 0 ;
2241+ }
2242+
21392243static int
21402244run_coregraphics_cache_invalid_env_reject_test (void )
21412245{
@@ -2227,6 +2331,8 @@ run_coregraphics_loader_test(void)
22272331 run_coregraphics_huge_dimension_metadata_reject_test },
22282332 { "SIXEL_TEST_COREGRAPHICS_CFINDEX_SIZE_OVERFLOW_REJECT" ,
22292333 run_coregraphics_cfindex_size_overflow_reject_test },
2334+ { "SIXEL_TEST_COREGRAPHICS_INDEXED_PROVIDER_COPY_OOM_REJECT" ,
2335+ run_coregraphics_indexed_provider_copy_oom_reject_test },
22302336 { "SIXEL_TEST_COREGRAPHICS_CACHE_INVALID_ENV_REJECT" ,
22312337 run_coregraphics_cache_invalid_env_reject_test }
22322338 };
@@ -2290,6 +2396,10 @@ run_coregraphics_loader_test(void)
22902396 if (result != 0 ) {
22912397 return result ;
22922398 }
2399+ result = run_coregraphics_indexed_provider_copy_oom_reject_test ();
2400+ if (result != 0 ) {
2401+ return result ;
2402+ }
22932403 return 0 ;
22942404}
22952405#endif
0 commit comments