[vlc-commits] [Git][videolan/vlc][master] 5 commits: demux: subtitle: only allocate internal psz_text when needed

Steve Lhomme (@robUx4) gitlab at videolan.org
Sun Mar 2 06:21:54 UTC 2025


Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
3f110c95 by Steve Lhomme at 2025-03-01T16:37:43+00:00
demux: subtitle: only allocate internal psz_text when needed

- - - - -
e8f7ac27 by Steve Lhomme at 2025-03-01T16:37:43+00:00
demux: subtitle: avoid using strcat when we know the string sizes

We're just concatenating the lines in psz_text.

- - - - -
1e03b716 by Steve Lhomme at 2025-03-01T16:37:43+00:00
demux: subtitle: keep the size of the concatenated string

No need to do a lengthy strlen() call each time the concatenated string grows.

- - - - -
de7e5074 by Steve Lhomme at 2025-03-01T16:37:43+00:00
demux: subtitle: avoid allocating a dummy string

realloc works fine on NULL.
The pointer is set in p_subtitle->psz_text which is free'd later.
It's OK to free a NULL pointer if there wasn't any line to use.

- - - - -
1f9b8484 by Steve Lhomme at 2025-03-01T16:37:43+00:00
demux: subtitle: only set the string terminator on loop exit

No need to set it on each iteration.

- - - - -


1 changed file:

- modules/demux/subtitle.c


Changes:

=====================================
modules/demux/subtitle.c
=====================================
@@ -245,6 +245,9 @@ static char * get_language_from_filename( const char * );
 
 static block_t *ToTextBlock( const subtitle_t *p_subtitle )
 {
+    if ( p_subtitle->psz_text == NULL )
+        return NULL;
+
     block_t *p_block;
     size_t i_len = strlen( p_subtitle->psz_text ) + 1;
 
@@ -258,6 +261,9 @@ static block_t *ToTextBlock( const subtitle_t *p_subtitle )
 
 static block_t *ToEIA608Block( const subtitle_t *p_subtitle )
 {
+    if ( p_subtitle->psz_text == NULL )
+        return NULL;
+
     block_t *p_block;
     const size_t i_len = strlen( p_subtitle->psz_text );
     const size_t i_block = (1 + i_len / 5) * 3;
@@ -1077,31 +1083,29 @@ static int ParseSubRipSubViewer( vlc_object_t *p_obj, subs_properties_t *p_props
     }
 
     /* Now read text until an empty line */
-    psz_text = strdup("");
-    if( !psz_text )
-        return VLC_ENOMEM;
-
+    size_t i_old = 0;
+    psz_text = NULL;
     for( ;; )
     {
         const char *s = TextGetLine( txt );
         size_t i_len;
-        size_t i_old;
 
         i_len = s ? strlen( s ) : 0;
         if( i_len <= 0 )
         {
+            if (psz_text)
+                psz_text[i_old] = '\0';
             p_subtitle->psz_text = psz_text;
             return VLC_SUCCESS;
         }
 
-        i_old = strlen( psz_text );
         psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
         if( !psz_text )
-        {
             return VLC_ENOMEM;
-        }
-        strcat( psz_text, s );
-        strcat( psz_text, "\n" );
+
+        memcpy( &psz_text[i_old], s, i_len );
+        psz_text[i_old + i_len + 0] = '\n';
+        i_old += i_len + 1;
 
         /* replace [br] by \n */
         if( b_replace_br )
@@ -1112,6 +1116,7 @@ static int ParseSubRipSubViewer( vlc_object_t *p_obj, subs_properties_t *p_props
             {
                 *p++ = '\n';
                 memmove( p, &p[3], strlen(&p[3])+1 );
+                i_old -= 3;
             }
         }
     }
@@ -1514,14 +1519,12 @@ static int ParseDVDSubtitle(vlc_object_t *p_obj, subs_properties_t *p_props,
     }
 
     /* Now read text until a line containing "}" */
-    psz_text = strdup("");
-    if( !psz_text )
-        return VLC_ENOMEM;
+    size_t i_old = 0;
+    psz_text = NULL;
     for( ;; )
     {
         const char *s = TextGetLine( txt );
-        int i_len;
-        int i_old;
+        size_t i_len;
 
         if( !s )
         {
@@ -1532,16 +1535,19 @@ static int ParseDVDSubtitle(vlc_object_t *p_obj, subs_properties_t *p_props,
         i_len = strlen( s );
         if( i_len == 1 && s[0] == '}')
         {
+            if (psz_text)
+                psz_text[i_old] = '\0';
             p_subtitle->psz_text = psz_text;
             return VLC_SUCCESS;
         }
 
-        i_old = strlen( psz_text );
         psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
         if( !psz_text )
             return VLC_ENOMEM;
-        strcat( psz_text, s );
-        strcat( psz_text, "\n" );
+
+        memcpy( &psz_text[i_old], s, i_len );
+        psz_text[i_old + i_len + 0] = '\n';
+        i_old += i_len + 1;
     }
 }
 
@@ -1606,8 +1612,9 @@ static int ParseAQT(vlc_object_t *p_obj, subs_properties_t *p_props, text_t *txt
     VLC_UNUSED(p_props);
     VLC_UNUSED( i_idx );
 
-    char *psz_text = strdup( "" );
-    int i_old = 0;
+    char *psz_text = NULL;
+    size_t i_old = 0;
+    size_t i_len;
     int i_firstline = 1;
 
     for( ;; )
@@ -1641,16 +1648,20 @@ static int ParseAQT(vlc_object_t *p_obj, subs_properties_t *p_props, text_t *txt
         /* Text Lines */
         else
         {
-            i_old = strlen( psz_text ) + 1;
-            psz_text = realloc_or_free( psz_text, i_old + strlen( s ) + 1 );
+            i_len = strlen( s );
+            psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
             if( !psz_text )
                  return VLC_ENOMEM;
-            strcat( psz_text, s );
-            strcat( psz_text, "\n" );
+
+            memcpy( &psz_text[i_old], s, i_len );
+            psz_text[i_old + i_len + 0] = '\n';
+            i_old += i_len + 1;
             if( txt->i_line == txt->i_line_count )
                 break;
         }
     }
+    if (psz_text)
+        psz_text[i_old] = '\0';
     p_subtitle->psz_text = psz_text;
     return VLC_SUCCESS;
 }
@@ -1708,8 +1719,6 @@ static int ParseMPSub( vlc_object_t *p_obj, subs_properties_t *p_props,
 {
     VLC_UNUSED( i_idx );
 
-    char *psz_text = strdup( "" );
-
     if( !p_props->mpsub.b_inited )
     {
         p_props->mpsub.f_total = 0.0;
@@ -1726,7 +1735,6 @@ static int ParseMPSub( vlc_object_t *p_obj, subs_properties_t *p_props,
         const char *s = TextGetLine( txt );
         if( !s )
         {
-            free( psz_text );
             return VLC_EGENERIC;
         }
 
@@ -1741,7 +1749,6 @@ static int ParseMPSub( vlc_object_t *p_obj, subs_properties_t *p_props,
             psz_temp = malloc( strlen(s) );
             if( !psz_temp )
             {
-                free( psz_text );
                 return VLC_ENOMEM;
             }
 
@@ -1772,6 +1779,8 @@ static int ParseMPSub( vlc_object_t *p_obj, subs_properties_t *p_props,
         }
     }
 
+    char *psz_text = NULL;
+    size_t i_old = 0;
     for( ;; )
     {
         const char *s = TextGetLine( txt );
@@ -1786,16 +1795,17 @@ static int ParseMPSub( vlc_object_t *p_obj, subs_properties_t *p_props,
         if( i_len == 0 )
             break;
 
-        size_t i_old = strlen( psz_text );
-
         psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
         if( !psz_text )
              return VLC_ENOMEM;
 
-        strcat( psz_text, s );
-        strcat( psz_text, "\n" );
+        memcpy( &psz_text[i_old], s, i_len );
+        psz_text[i_old + i_len + 0] = '\n';
+        i_old += i_len + 1;
     }
 
+    if (psz_text)
+        psz_text[i_old] = '\0';
     p_subtitle->psz_text = psz_text;
     return VLC_SUCCESS;
 }
@@ -2155,6 +2165,7 @@ static int ParseRealText( vlc_object_t *p_obj, subs_properties_t *p_props,
     }
 
     /* Get the following Lines */
+    size_t i_old = strlen( psz_text );
     for( ;; )
     {
         const char *s = TextGetLine( txt );
@@ -2175,16 +2186,16 @@ static int ParseRealText( vlc_object_t *p_obj, subs_properties_t *p_props,
             break;
         }
 
-        size_t i_old = strlen( psz_text );
-
         psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
         if( !psz_text )
             return VLC_ENOMEM;
 
-        strcat( psz_text, s );
-        strcat( psz_text, "\n" );
+        memcpy( &psz_text[i_old], s, i_len );
+        psz_text[i_old + i_len + 0] = '\n';
+        i_old += i_len + 1;
     }
 
+    psz_text[i_old] = '\0';
     /* Remove the starting ">" that remained after the sscanf */
     memmove( &psz_text[0], &psz_text[1], strlen( psz_text ) );
 
@@ -2330,30 +2341,29 @@ static int ParseCommonSBV( vlc_object_t *p_obj, subs_properties_t *p_props,
     }
 
     /* Now read text until an empty line */
-    psz_text = strdup("");
-    if( !psz_text )
-        return VLC_ENOMEM;
-
+    size_t i_old = 0;
+    psz_text = NULL;
     for( ;; )
     {
         const char *s = TextGetLine( txt );
         size_t i_len;
-        size_t i_old;
 
         i_len = s ? strlen( s ) : 0;
         if( i_len <= 0 )
         {
+            if (psz_text)
+                psz_text[i_old] = '\0';
             p_subtitle->psz_text = psz_text;
             return VLC_SUCCESS;
         }
 
-        i_old = strlen( psz_text );
         psz_text = realloc_or_free( psz_text, i_old + i_len + 1 + 1 );
         if( !psz_text )
             return VLC_ENOMEM;
 
-        strcat( psz_text, s );
-        strcat( psz_text, "\n" );
+        memcpy( &psz_text[i_old], s, i_len );
+        psz_text[i_old + i_len + 0] = '\n';
+        i_old += i_len + 1;
     }
 }
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/46cacbe08e804ce82a1396114ea611d61d7ef0bb...1f9b8484003d74e1b1a6e0bd4c8b738bafd8aa9d

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/46cacbe08e804ce82a1396114ea611d61d7ef0bb...1f9b8484003d74e1b1a6e0bd4c8b738bafd8aa9d
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list