[dvblast-devel] [Git][videolan/dvblast][master] fix segfault when dvb_charset != native_charset

Massiot gitlab at videolan.org
Sat Apr 29 22:51:36 CEST 2017


Massiot pushed to branch master at videolan / dvblast


Commits:
00b7515a by Christophe Massiot at 2017-04-29T22:43:42+02:00
fix segfault when dvb_charset != native_charset

Also add /charset= option, and use ISO 6937 for ASCII strings.

- - - - -


2 changed files:

- NEWS
- dvblast.c


Changes:

=====================================
NEWS
=====================================
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,9 @@ Changes between 3.1 and 3.2:
   * Fix HEVC support
   * Fix memory leak on loading the configuration
   * Also remap ONID in EIT
+  * Fix segmentation fault when using output charset different from native
+  * Use default charset ISO 6937 for ASCII strings
+  * Add /charset= output option
 
 Changes between 3.0 and 3.1:
 ----------------------------


=====================================
dvblast.c
=====================================
--- a/dvblast.c
+++ b/dvblast.c
@@ -205,54 +205,70 @@ char *config_stropt( const char *psz_string )
     return ret;
 }
 
-static char *config_striconv( const char *psz_string )
+static uint8_t *config_striconv( const char *psz_string,
+                                 const char *psz_charset, size_t *pi_length )
 {
     char *psz_input = config_stropt(psz_string);
+    *pi_length = strlen(psz_input);
 
-    if ( !strcasecmp( psz_native_charset, psz_dvb_charset ) )
-        return psz_input;
+    /* do not convert ASCII strings */
+    const char *c = psz_string;
+    while (*c)
+        if (!isascii(*c++))
+            break;
+    if (!*c)
+        return (uint8_t *)psz_input;
+
+    if ( !strcasecmp( psz_native_charset, psz_charset ) )
+        return (uint8_t *)psz_input;
 
 #ifdef HAVE_ICONV
     if ( conf_iconv == (iconv_t)-1 )
     {
-        conf_iconv = iconv_open( psz_dvb_charset, psz_native_charset );
+        conf_iconv = iconv_open( psz_charset, psz_native_charset );
         if ( conf_iconv == (iconv_t)-1 )
-            return psz_input;
+            return (uint8_t *)psz_input;
     }
 
-    size_t i_input = strlen( psz_input );
+    char *psz_tmp = psz_input;
+    size_t i_input = *pi_length;
     size_t i_output = i_input * 6;
-    char *psz_output = malloc( i_output );
-    char *p = psz_output;
-    if ( iconv( conf_iconv, &psz_input, &i_input, &p, &i_output ) == -1 )
+    size_t i_available = i_output;
+    char *p_output = malloc( i_output );
+    char *p = p_output;
+    if ( iconv( conf_iconv, &psz_tmp, &i_input, &p, &i_available ) == -1 )
     {
-        free( psz_output );
-        return psz_input;
+        free( p_output );
+
+        return (uint8_t *)psz_input;
     }
 
     free(psz_input);
-    return psz_output;
+    *pi_length = i_output - i_available;
+    return (uint8_t *)p_output;
 #else
     msg_Warn( NULL,
               "unable to convert from %s to %s (iconv is not available)",
-              psz_native_charset, psz_dvb_charset );
-    return psz_input;
+              psz_native_charset, psz_charset );
+    return (uint8_t *)psz_input;
 #endif
 }
 
-static void config_strdvb( dvb_string_t *p_dvb_string, const char *psz_string )
+static void config_strdvb( dvb_string_t *p_dvb_string, const char *psz_string,
+                           const char *psz_charset )
 {
     if (psz_string == NULL)
     {
         dvb_string_init(p_dvb_string);
         return;
     }
-
-    char *psz_iconv = config_striconv(psz_string);
     dvb_string_clean(p_dvb_string);
-    p_dvb_string->p = dvb_string_set((uint8_t *)psz_iconv, strlen(psz_iconv),
-                                     psz_dvb_charset, &p_dvb_string->i);
-    free(psz_iconv);
+
+    size_t i_iconv;
+    uint8_t *p_iconv = config_striconv(psz_string, psz_charset, &i_iconv);
+    p_dvb_string->p = dvb_string_set(p_iconv, i_iconv, psz_charset,
+                                     &p_dvb_string->i);
+    free(p_iconv);
 }
 
 static bool config_ParseHost( output_config_t *p_config, char *psz_string )
@@ -283,6 +299,11 @@ static bool config_ParseHost( output_config_t *p_config, char *psz_string )
         freeaddrinfo( p_ai );
     }
 
+    const char *psz_charset = psz_dvb_charset;
+    const char *psz_network_name = NULL;
+    const char *psz_service_name = NULL;
+    const char *psz_provider_name = NULL;
+
     while ( (psz_string = strchr( psz_string, '/' )) != NULL )
     {
         *psz_string++ = '\0';
@@ -316,18 +337,14 @@ static bool config_ParseHost( output_config_t *p_config, char *psz_string )
             p_config->i_network_id = strtol( ARG_OPTION("networkid="), NULL, 0 );
         else if ( IS_OPTION("onid=") )
             p_config->i_onid = strtol( ARG_OPTION("onid="), NULL, 0 );
+        else if ( IS_OPTION("charset=")  )
+            psz_charset = ARG_OPTION("charset=");
         else if ( IS_OPTION("networkname=")  )
-        {
-            config_strdvb( &p_config->network_name, ARG_OPTION("networkname=") );
-        }
+            psz_network_name = ARG_OPTION("networkname=");
         else if ( IS_OPTION("srvname=")  )
-        {
-            config_strdvb( &p_config->service_name, ARG_OPTION("srvname=") );
-        }
+            psz_service_name = ARG_OPTION("srvname=");
         else if ( IS_OPTION("srvprovider=") )
-        {
-            config_strdvb( &p_config->provider_name, ARG_OPTION("srvprovider=") );
-        }
+            psz_provider_name = ARG_OPTION("srvprovider=");
         else if ( IS_OPTION("srcaddr=") )
         {
             if ( p_config->i_family != AF_INET ) {
@@ -370,6 +387,14 @@ static bool config_ParseHost( output_config_t *p_config, char *psz_string )
 #undef ARG_OPTION
     }
 
+    if (psz_network_name != NULL)
+        config_strdvb( &p_config->network_name, psz_network_name, psz_charset );
+    if (psz_service_name != NULL)
+        config_strdvb( &p_config->service_name, psz_service_name, psz_charset );
+    if (psz_provider_name != NULL)
+        config_strdvb( &p_config->provider_name, psz_provider_name,
+                       psz_charset );
+
 end:
     i_mtu = p_config->i_family == AF_INET6 ? DEFAULT_IPV6_MTU :
             DEFAULT_IPV4_MTU;
@@ -1189,8 +1214,8 @@ int main( int i_argc, char **pp_argv )
         config_Free( &config );
     }
 
-    config_strdvb( &network_name, psz_network_name );
-    config_strdvb( &provider_name, psz_provider_name );
+    config_strdvb( &network_name, psz_network_name, psz_dvb_charset );
+    config_strdvb( &provider_name, psz_provider_name, psz_dvb_charset );
 
     /* Set signal handlers */
     signal_watcher_init(&sigint_watcher, event_loop, sighandler, SIGINT);



View it on GitLab: https://code.videolan.org/videolan/dvblast/commit/00b7515a314d773cb5ae3e80599a4fbbd87007fe


More information about the dvblast-devel mailing list