[vlc-commits] [Git][videolan/vlc][master] 15 commits: core: do not free plugin->conf.params on realloc failure

Steve Lhomme (@robUx4) gitlab at videolan.org
Sat Sep 5 09:39:21 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
0b702bfe by Steve Lhomme at 2026-09-05T11:29:09+02:00
core: do not free plugin->conf.params on realloc failure

If there was a reallocation failure, it would free plugin->conf.params.
But the pointer itself was not set to NULL and could be reused.

It will be properly free'd in vlc_plugin_destroy().

If for some reason the integer overflows we don't allocate and
keep the old pointer alive.

- - - - -
83b75c15 by Steve Lhomme at 2026-09-05T11:29:09+02:00
mmdevice: reset the counter of ids/names when realloc fail

One of the pointer list is not valid anymore and has been free'd.
The counter should be reset, and thus the other pointer should be free'd as well.

It's very unlikely to happen, but in that case we should probably just keep the
elements that were added and not add any more.

- - - - -
30d362bd by Steve Lhomme at 2026-09-05T11:29:09+02:00
demux: mp4: reset the counter of context runs when realloc fail

One of the pointer list is not valid anymore and has been free'd.
The counter should be reset.

It's very unlikely to happen, but in that case we should probably just keep the
elements that were added and not add any more.

- - - - -
58b88505 by Steve Lhomme at 2026-09-05T11:29:09+02:00
video_filter: gaussian_blur: don't call realloc on NULL pointer

We just need a malloc.

- - - - -
72101186 by Steve Lhomme at 2026-09-05T11:29:09+02:00
video_filter: gaussian_blur: don't call allocate a buffer of size 0

The behavior is implementation defined and we are not going to process
anything anyway.

- - - - -
3cdbfeab by Steve Lhomme at 2026-09-05T11:29:09+02:00
json_helper: explicitly free the source buffer on realloc error

So we don't rely on realloc_or_free().

- - - - -
c86c96d1 by Steve Lhomme at 2026-09-05T11:29:09+02:00
dvbsub: explicitly free the pixbuf on realloc error

So we don't rely on realloc_or_free().

- - - - -
044d7f02 by Steve Lhomme at 2026-09-05T11:29:09+02:00
dvbsub: explicitly free region text on realloc error

So we don't rely on realloc_or_free().

- - - - -
310e22a3 by Steve Lhomme at 2026-09-05T11:29:09+02:00
demux: ogg: explicitly free header buffer on realloc error

So we don't rely on realloc_or_free().
And we can avoid a cast.

- - - - -
bd62d0c8 by Steve Lhomme at 2026-09-05T11:29:09+02:00
opengl: sub_renderer: explicitly free object array on realloc error

So we don't rely on realloc_or_free().

- - - - -
3a9891d2 by Steve Lhomme at 2026-09-05T11:29:09+02:00
opengl: interop_sw: explicitly free temporary texture buffer on realloc error

So we don't rely on realloc_or_free().

- - - - -
1b6b05ba by Steve Lhomme at 2026-09-05T11:29:09+02:00
demux: avi: explicitly free temporary texture buffer on realloc error

So we don't rely on realloc_or_free().

- - - - -
8e776abe by Steve Lhomme at 2026-09-05T11:29:09+02:00
demux: subtitle: explicitly free expanding text on realloc error

So we don't rely on realloc_or_free().

- - - - -
c280d482 by Steve Lhomme at 2026-09-05T11:29:09+02:00
demux: subtitle: explicitly free SSA header text on realloc error

So we don't rely on realloc_or_free().

- - - - -
f290d0f1 by Steve Lhomme at 2026-09-05T11:29:09+02:00
include: remove realloc_or_free()

It is not safe to call realloc with a size of 0 [^1] as it is implementation defined/undefined and
may or may not free the buffer. We can't tell.

It's up to each caller of realloc() to prevent calls with a size of 0.

[^1]: https://open-std.org/JTC1/SC22/WG14/www/docs/n2396.htm#dr_400 ↩

- - - - -


12 changed files:

- include/vlc_arrays.h
- modules/audio_output/mmdevice.c
- modules/codec/dvbsub.c
- modules/demux/avi/avi.c
- modules/demux/mp4/mp4.c
- modules/demux/ogg.c
- modules/demux/subtitle.c
- modules/misc/webservices/json_helper.h
- modules/video_filter/gaussianblur.c
- modules/video_output/opengl/interop_sw.c
- modules/video_output/opengl/sub_renderer.c
- src/modules/entry.c


Changes:

=====================================
include/vlc_arrays.h
=====================================
@@ -38,21 +38,6 @@ static inline void *realloc_down( void *ptr, size_t size )
     return ret ? ret : ptr;
 }
 
-/**
- * This wrapper around realloc() will free the input pointer when
- * realloc() returns NULL. The use case ptr = realloc(ptr, newsize) will
- * cause a memory leak when ptr pointed to a heap allocation before,
- * leaving the buffer allocated but unreferenced. vlc_realloc() is a
- * drop-in replacement for that use case (and only that use case).
- */
-static inline void *realloc_or_free( void *p, size_t sz )
-{
-    void *n = realloc(p,sz);
-    if( !n )
-        free(p);
-    return n;
-}
-
 #define TAB_INIT( count, tab )                  \
   do {                                          \
     (count) = 0;                                \


=====================================
modules/audio_output/mmdevice.c
=====================================
@@ -1449,24 +1449,34 @@ static void Reload_DevicesEnum_Added(void *data, LPCWSTR wid, IMMDevice *dev)
     struct mm_list *list = data;
 
     size_t new_count = list->count + 1;
-    list->ids = realloc_or_free(list->ids, new_count * sizeof(char *));
-    list->names = realloc_or_free(list->names, new_count * sizeof(char *));
-    if (!list->ids || !list->names)
+    void *r_ids = vlc_reallocarray(list->ids, new_count, sizeof(char *));
+    if ( unlikely( r_ids == NULL ) )
+        return;
+    void *r_names = vlc_reallocarray(list->names, new_count, sizeof(char *));
+    if ( unlikely( r_names == NULL ) )
     {
-        free(list->ids);
+        free( r_ids );
         return;
     }
 
     char *id = FromWide(wid);
     if (!id)
+    {
+        free( r_ids );
+        free( r_names );
         return;
+    }
 
     char *name = DeviceGetFriendlyName(dev);
     if (!name && !(name = strdup(id)))
     {
         free(id);
+        free( r_ids );
+        free( r_names );
         return;
     }
+    list->ids = r_ids;
+    list->names = r_names;
     list->ids[list->count] = id;
     list->names[list->count] = name;
 


=====================================
modules/codec/dvbsub.c
=====================================
@@ -972,7 +972,14 @@ static void decode_region_composition( decoder_t *p_dec, bs_t *s, uint16_t i_seg
         }
         else
         {
-            p_region->p_pixbuf = realloc_or_free( p_region->p_pixbuf, i_alloc );
+            void *r_pixbuf = realloc( p_region->p_pixbuf, i_alloc );
+            if( unlikely( r_pixbuf == NULL ) )
+            {
+                free( p_region->p_pixbuf );
+                p_region->p_pixbuf = NULL;
+            }
+            else
+                p_region->p_pixbuf = r_pixbuf;
             p_region->i_depth = 0;
         }
 
@@ -1355,13 +1362,14 @@ static void decode_object( decoder_t *p_dec, bs_t *s, uint16_t i_segment_length
 
                 if( p_region->p_object_defs[i].i_id != i_id ) continue;
 
-                char *psz_text = p_region->p_object_defs[i].psz_text;
-
-                p_region->p_object_defs[i].psz_text = psz_text =
-                        realloc_or_free( psz_text, i_number_of_codes + 1 );
-
-                if( !psz_text )
+                char *psz_text = realloc( p_region->p_object_defs[i].psz_text, i_number_of_codes + 1 );
+                if( unlikely( psz_text == NULL ) )
+                {
+                    free( p_region->p_object_defs[i].psz_text );
+                    p_region->p_object_defs[i].psz_text = NULL;
                     continue;
+                }
+                p_region->p_object_defs[i].psz_text = psz_text;
 
                 /* FIXME 16bits -> char ??? See Preamble */
                 for( j = 0; j < i_number_of_codes; j++ )


=====================================
modules/demux/avi/avi.c
=====================================
@@ -2491,13 +2491,15 @@ static int64_t avi_index_Append( avi_index_t *p_index, uint64_t *pi_last_pos,
             p_index->i_max += INDEX_EXTENT;
         else
             p_index->i_max = MAX_INDEX_ENTRIES;
-        p_index->p_entry = realloc_or_free( p_index->p_entry,
-                                            p_index->i_max * sizeof(avi_entry_t) );
-        if( !p_index->p_entry )
+        void *r_entry = vlc_reallocarray( p_index->p_entry,
+                                          p_index->i_max, sizeof(avi_entry_t) );
+        if( unlikely( r_entry == NULL ) )
         {
+            free( p_index->p_entry );
             avi_index_Init( p_index );
             return -1;
         }
+        p_index->p_entry = r_entry;
     }
     /* calculate cumulate length */
     if( p_index->i_size > 0 )


=====================================
modules/demux/mp4/mp4.c
=====================================
@@ -5282,10 +5282,16 @@ static int FragCreateTrunIndex( demux_t *p_demux, MP4_Box_t *p_moof,
         if( !p_track )
             continue;
 
-        p_track->context.runs.p_array = realloc_or_free(p_track->context.runs.p_array,
-            (i_trun_count + p_track->context.runs.i_count) * sizeof(mp4_run_t));
-        if(!p_track->context.runs.p_array)
+        void *r_array = vlc_reallocarray( p_track->context.runs.p_array,
+            i_trun_count + p_track->context.runs.i_count, sizeof(mp4_run_t) );
+        if ( unlikely( r_array == NULL ))
+        {
+            free( p_track->context.runs.p_array );
+            p_track->context.runs.p_array = NULL;
+            p_track->context.runs.i_count = 0;
             continue;
+        }
+        p_track->context.runs.p_array = r_array;
         memset(&p_track->context.runs.p_array[p_track->context.runs.i_count], 0, i_trun_count * sizeof(mp4_run_t));
         i_trun_count += p_track->context.runs.i_count;
 


=====================================
modules/demux/ogg.c
=====================================
@@ -1404,15 +1404,20 @@ static void Ogg_DecodePacket( demux_t *p_demux,
         if( !b_xiph && p_oggpacket->bytes > 0 &&
             (size_t)p_oggpacket->bytes < SIZE_MAX - p_stream->i_headers )
         {
-            p_stream->p_headers = realloc_or_free( p_stream->p_headers,
-                                                   p_stream->i_headers + p_oggpacket->bytes );
-            if( p_stream->p_headers )
+            uint8_t *r_headers = realloc( p_stream->p_headers,
+                                          p_stream->i_headers + p_oggpacket->bytes );
+            if( likely( r_headers != NULL ) )
             {
-                memcpy( (uint8_t*)p_stream->p_headers + p_stream->i_headers, p_oggpacket->packet, p_oggpacket->bytes );
+                p_stream->p_headers = r_headers;
+                memcpy( r_headers + p_stream->i_headers, p_oggpacket->packet, p_oggpacket->bytes );
                 p_stream->i_headers += p_oggpacket->bytes;
             }
             else
+            {
+                free( p_stream->p_headers );
+                p_stream->p_headers = NULL;
                 p_stream->i_headers = 0;
+            }
         }
         else if( b_xiph &&
                  xiph_AppendHeaders( &p_stream->i_headers, &p_stream->p_headers,


=====================================
modules/demux/subtitle.c
=====================================
@@ -1111,9 +1111,13 @@ static int ParseSubRipSubViewer( vlc_object_t *p_obj, subs_properties_t *p_props
             return VLC_SUCCESS;
         }
 
-        psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
-        if( !psz_text )
+        void *r_text = realloc( psz_text, i_old + i_len + 1 + 1 );
+        if( unlikely( r_text == NULL ) )
+        {
+            free( psz_text );
             return VLC_ENOMEM;
+        }
+        psz_text = r_text;
 
         memcpy( &psz_text[i_old], s, i_len );
         psz_text[i_old + i_len + 0] = '\n';
@@ -1324,9 +1328,13 @@ static int  ParseSSA( vlc_object_t *p_obj, subs_properties_t *p_props,
             header_len = strlen( p_props->psz_header );
 
         size_t s_len = strlen( s );
-        p_props->psz_header = realloc_or_free( p_props->psz_header, header_len + s_len + 2 );
-        if( !p_props->psz_header )
+        void *r_header = realloc( p_props->psz_header, header_len + s_len + 2 );
+        if ( unlikely( r_header == NULL) )
+        {
+            free( p_props->psz_header );
             return VLC_ENOMEM;
+        }
+        p_props->psz_header = r_header;
         snprintf( p_props->psz_header + header_len, s_len + 2, "%s\n", s );
         header_len += s_len + 1;
     }
@@ -1553,9 +1561,13 @@ static int ParseDVDSubtitle(vlc_object_t *p_obj, subs_properties_t *p_props,
             return VLC_SUCCESS;
         }
 
-        psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
-        if( !psz_text )
+        void *r_text = realloc( psz_text, i_old + i_len + 1 + 1 );
+        if( unlikely( r_text == NULL ) )
+        {
+            free( psz_text );
             return VLC_ENOMEM;
+        }
+        psz_text = r_text;
 
         memcpy( &psz_text[i_old], s, i_len );
         psz_text[i_old + i_len + 0] = '\n';
@@ -1661,9 +1673,13 @@ static int ParseAQT(vlc_object_t *p_obj, subs_properties_t *p_props, text_t *txt
         else
         {
             i_len = strlen( s );
-            psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
-            if( !psz_text )
-                 return VLC_ENOMEM;
+            void *r_text = realloc( psz_text, i_old + i_len + 1 + 1 );
+            if( unlikely( r_text == NULL ) )
+            {
+                free( psz_text );
+                return VLC_ENOMEM;
+            }
+            psz_text = r_text;
 
             memcpy( &psz_text[i_old], s, i_len );
             psz_text[i_old + i_len + 0] = '\n';
@@ -1801,9 +1817,13 @@ static int ParseMPSub( vlc_object_t *p_obj, subs_properties_t *p_props,
         if( i_len == 0 )
             break;
 
-        psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
-        if( !psz_text )
-             return VLC_ENOMEM;
+        void *r_text = realloc( psz_text, i_old + i_len + 1 + 1 );
+        if( unlikely( r_text == NULL ) )
+        {
+            free( psz_text );
+            return VLC_ENOMEM;
+        }
+        psz_text = r_text;
 
         memcpy( &psz_text[i_old], s, i_len );
         psz_text[i_old + i_len + 0] = '\n';
@@ -1953,9 +1973,13 @@ static int ParseJSS( vlc_object_t *p_obj, subs_properties_t *p_props,
 
         size_t i_old = strlen( psz_text );
 
-        psz_text = realloc_or_free( psz_text, i_old + i_len + 1 );
-        if( !psz_text )
-             return VLC_ENOMEM;
+        void *r_text = realloc( psz_text, i_old + i_len + 1 );
+        if( unlikely( r_text == NULL ) )
+        {
+            free( psz_text );
+            return VLC_ENOMEM;
+        }
+        psz_text = r_text;
 
         psz_orig = psz_text;
         strcat( psz_text, s2 );
@@ -2215,9 +2239,13 @@ static int ParseRealText( vlc_object_t *p_obj, subs_properties_t *p_props,
             break;
         }
 
-        psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
-        if( !psz_text )
+        void *r_text = realloc( psz_text, i_old + i_len + 1 + 1 );
+        if( unlikely( r_text == NULL ) )
+        {
+            free( psz_text );
             return VLC_ENOMEM;
+        }
+        psz_text = r_text;
 
         memcpy( &psz_text[i_old], s, i_len );
         psz_text[i_old + i_len + 0] = '\n';
@@ -2386,9 +2414,13 @@ static int ParseCommonSBV( vlc_object_t *p_obj, subs_properties_t *p_props,
             return VLC_SUCCESS;
         }
 
-        psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
-        if( !psz_text )
+        void *r_text = realloc( psz_text, i_old + i_len + 1 + 1 );
+        if( unlikely( r_text == NULL ) )
+        {
+            free( psz_text );
             return VLC_ENOMEM;
+        }
+        psz_text = r_text;
 
         memcpy( &psz_text[i_old], s, i_len );
         psz_text[i_old + i_len + 0] = '\n';


=====================================
modules/misc/webservices/json_helper.h
=====================================
@@ -60,12 +60,14 @@ void * json_retrieve_document(vlc_object_t *p_obj, const char *psz_url, size_t *
         if(*buf_size >= (SIZE_MAX - i_read - 1))
             break;
 
-        p_buffer = realloc_or_free(p_buffer, 1 + *buf_size + i_read);
-        if(unlikely(p_buffer == NULL))
+        void *rbuffer = realloc(p_buffer, 1 + *buf_size + i_read);
+        if(unlikely(rbuffer == NULL))
         {
+            free(p_buffer);
             vlc_stream_Delete(p_stream);
             return NULL;
         }
+        p_buffer = rbuffer;
 
         i_read = vlc_stream_Read(p_stream, &p_buffer[*buf_size], i_read);
         if(i_read <= 0)
@@ -97,7 +99,7 @@ size_t json_read(void *data, void *buf, size_t size)
     struct json_helper_sys *sys = data;
 
     /* Read the smallest number of byte between size and the string length */
-    size_t s = size < sys->size ? size : sys->size; 
+    size_t s = size < sys->size ? size : sys->size;
     memcpy(buf, sys->buffer, s);
 
     sys->buffer += s;


=====================================
modules/video_filter/gaussianblur.c
=====================================
@@ -198,12 +198,13 @@ static void Filter( filter_t *p_filter, picture_t *p_pic, picture_t *p_outpic )
 
     size_t i_y_plane_bytes;
     if( ckd_mul( &i_y_plane_bytes, p_pic->p[Y_PLANE].i_visible_lines, p_pic->p[Y_PLANE].i_pitch ) ||
-        ckd_mul( &i_y_plane_bytes, i_y_plane_bytes, sizeof( type_t ) ) )
+        ckd_mul( &i_y_plane_bytes, i_y_plane_bytes, sizeof( type_t ) ) ||
+        i_y_plane_bytes == 0 )
         return; // FIXME: nullify output ?
 
     if( !p_sys->pt_buffer )
     {
-        p_sys->pt_buffer = realloc_or_free( p_sys->pt_buffer, i_y_plane_bytes );
+        p_sys->pt_buffer = malloc( i_y_plane_bytes );
         if( !p_sys->pt_buffer )
             return;
     }


=====================================
modules/video_output/opengl/interop_sw.c
=====================================
@@ -292,13 +292,15 @@ upload_plane(const struct vlc_gl_interop *interop, unsigned tex_idx,
             uint8_t *destination;
             if (priv->texture_temp_buf_size < buf_size)
             {
-                priv->texture_temp_buf =
-                    realloc_or_free(priv->texture_temp_buf, buf_size);
-                if (priv->texture_temp_buf == NULL)
+                void *r_texture_buf = realloc(priv->texture_temp_buf, buf_size);
+                if (r_texture_buf == NULL)
                 {
+                    free(priv->texture_temp_buf);
+                    priv->texture_temp_buf = NULL;
                     priv->texture_temp_buf_size = 0;
                     return VLC_ENOMEM;
                 }
+                priv->texture_temp_buf = r_texture_buf;
                 priv->texture_temp_buf_size = buf_size;
             }
             destination = priv->texture_temp_buf;


=====================================
modules/video_output/opengl/sub_renderer.c
=====================================
@@ -386,9 +386,14 @@ vlc_gl_sub_renderer_Draw(struct vlc_gl_sub_renderer *sr)
         sr->buffer_object_count = 0;
 
         int new_count = 2 * sr->region_count;
-        sr->buffer_objects = realloc_or_free(sr->buffer_objects, new_count * sizeof(GLuint));
-        if (!sr->buffer_objects)
+        void *r_objects = vlc_reallocarray(sr->buffer_objects, new_count, sizeof(GLuint));
+        if ( unlikely( r_objects == NULL ) )
+        {
+            free( sr->buffer_objects );
+            sr->buffer_objects = NULL;
             return VLC_ENOMEM;
+        }
+        sr->buffer_objects = r_objects;
 
         sr->buffer_object_count = new_count;
         vt->GenBuffers(sr->buffer_object_count, sr->buffer_objects);


=====================================
src/modules/entry.c
=====================================
@@ -147,8 +147,8 @@ static struct vlc_param *vlc_config_create(vlc_plugin_t *plugin, int type)
 
     if ((confsize & 0xf) == 0)
     {
-        tab = realloc_or_free (tab, (confsize + 17) * sizeof (*tab));
-        if (tab == NULL)
+        tab = vlc_reallocarray( tab, (confsize + 17), sizeof (*tab) );
+        if (unlikely(tab == NULL))
             return NULL;
 
         plugin->conf.params = tab;



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2bff8fc626fe2b38639a23849fc4a12ec4add4f3...f290d0f1419d7b0d60c97c0df7138f72301b3c9f

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2bff8fc626fe2b38639a23849fc4a12ec4add4f3...f290d0f1419d7b0d60c97c0df7138f72301b3c9f
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list