]> git.sesse.net Git - vlc/blobdiff - src/libvlc-common.c
- mozilla: possible heap corruption when parsing options as string
[vlc] / src / libvlc-common.c
index 855045bdca4911e82599aa84c891b5779128a56e..e2ba1cf66ea1b95d4b9f721da4a963faff5ba555 100644 (file)
@@ -101,9 +101,8 @@ static volatile unsigned int i_instances = 0;
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-void LocaleInit( vlc_object_t * );
-void LocaleDeinit( void );
 static void SetLanguage   ( char const * );
+static inline int LoadMessages (void);
 static int  GetFilenames  ( libvlc_int_t *, int, char *[] );
 static void Help          ( libvlc_int_t *, char const *psz_help_name );
 static void Usage         ( libvlc_int_t *, char const *psz_module_name );
@@ -270,13 +269,11 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
     /*
      * Support for gettext
      */
-    SetLanguage( "" );
-
-    /*
-     * Global iconv, must be done after setlocale()
-     * so that vlc_current_charset() works.
-     */
-    LocaleInit( (vlc_object_t *)p_libvlc );
+#ifdef HAVE_LC_MESSAGES
+    setlocale( LC_MESSAGES, "" );
+#endif
+    setlocale( LC_CTYPE, "" );
+    LoadMessages ();
 
     /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
     msg_Dbg( p_libvlc, "translation test: code is \"%s\"", _("C") );
@@ -1007,19 +1004,20 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc, vlc_bool_t b_release )
 #ifndef WIN32
     char* psz_pidfile = NULL;
 
+    if( p_libvlc->p_libvlc_global->p_module_bank )
     if( config_GetInt( p_libvlc, "daemon" ) )
     {
-      psz_pidfile = config_GetPsz( p_libvlc, "pidfile" );
-      if( psz_pidfile != NULL )
-      {
-        msg_Dbg( p_libvlc, "removing pid file %s", psz_pidfile );
-        if( unlink( psz_pidfile ) == -1 )
+        psz_pidfile = config_GetPsz( p_libvlc, "pidfile" );
+        if( psz_pidfile != NULL )
         {
-          msg_Dbg( p_libvlc, "removing pid file %s: failed: %s",
-              psz_pidfile, strerror(errno) );
+            msg_Dbg( p_libvlc, "removing pid file %s", psz_pidfile );
+            if( unlink( psz_pidfile ) == -1 )
+            {
+                msg_Dbg( p_libvlc, "removing pid file %s: failed: %s",
+                        psz_pidfile, strerror(errno) );
+            }
         }
-      }
-      free ( psz_pidfile );
+        free ( psz_pidfile );
     }
 #endif
 
@@ -1046,9 +1044,6 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc, vlc_bool_t b_release )
     {
         /* System specific cleaning code */
         system_End( p_libvlc );
-
-       /* Destroy global iconv */
-        LocaleDeinit();
     }
     vlc_mutex_unlock( lockval.p_address );
     var_Destroy( p_libvlc_global, "libvlc" );
@@ -1125,6 +1120,7 @@ int libvlc_InternalAddIntf( libvlc_int_t *p_libvlc,
     return VLC_SUCCESS;
 };
 
+#if defined (__APPLE__) || defined (WIN32)
 /*****************************************************************************
  * SetLanguage: set the interface language.
  *****************************************************************************
@@ -1132,61 +1128,70 @@ int libvlc_InternalAddIntf( libvlc_int_t *p_libvlc,
  * as well as the LC_CTYPE category for string sorting and possible wide
  * character support.
  *****************************************************************************/
-static void SetLanguage ( char const *psz_lang )
+static void SetLanguage ( const char *psz_lang )
 {
-#if defined( ENABLE_NLS ) \
-     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
+#ifdef __APPLE__
+    /* I need that under Darwin, please check it doesn't disturb
+     * other platforms. --Meuuh */
+    setenv( "LANG", psz_lang, 1 );
 
-    const char *    psz_path = NULL;
-#if defined( __APPLE__ ) || defined ( WIN32 ) || defined( SYS_BEOS )
-    char            psz_tmp[1024];
+#else
+    /* We set LC_ALL manually because it is the only way to set
+     * the language at runtime under eg. Windows. Beware that this
+     * makes the environment unconsistent when libvlc is unloaded and
+     * should probably be moved to a safer place like vlc.c. */
+    static char psz_lcall[20];
+    snprintf( psz_lcall, 19, "LC_ALL=%s", psz_lang );
+    psz_lcall[19] = '\0';
+    putenv( psz_lcall );
 #endif
 
-    if( psz_lang && !*psz_lang )
-    {
-#   if defined( HAVE_LC_MESSAGES )
-        setlocale( LC_MESSAGES, psz_lang );
-#   endif
-        setlocale( LC_CTYPE, psz_lang );
-    }
-    else if( psz_lang )
-    {
-#ifdef __APPLE__
-        /* I need that under Darwin, please check it doesn't disturb
-         * other platforms. --Meuuh */
-        setenv( "LANG", psz_lang, 1 );
-
-#elif defined( SYS_BEOS ) || defined( WIN32 )
-        /* We set LC_ALL manually because it is the only way to set
-         * the language at runtime under eg. Windows. Beware that this
-         * makes the environment unconsistent when libvlc is unloaded and
-         * should probably be moved to a safer place like vlc.c. */
-        static char psz_lcall[20];
-        snprintf( psz_lcall, 19, "LC_ALL=%s", psz_lang );
-        psz_lcall[19] = '\0';
-        putenv( psz_lcall );
+    setlocale( LC_ALL, psz_lang );
+}
 #endif
 
-        setlocale( LC_ALL, psz_lang );
-    }
 
+static inline int LoadMessages (void)
+{
+#if defined( ENABLE_NLS ) \
+     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
     /* Specify where to find the locales for current domain */
 #if !defined( __APPLE__ ) && !defined( WIN32 ) && !defined( SYS_BEOS )
-    psz_path = LOCALEDIR;
+    static const char psz_path[] = LOCALEDIR;
 #else
-    snprintf( psz_tmp, sizeof(psz_tmp), "%s/%s", libvlc_global.psz_vlcpath,
-              "locale" );
-    psz_path = psz_tmp;
+    char psz_path[1024];
+    if (snprintf (psz_path, sizeof (psz_path), "%s/%s",
+                  libvlc_global.psz_vlcpath, "locale")
+                     >= (int)sizeof (psz_path))
+        return -1;
+
 #endif
-    if( !bindtextdomain( PACKAGE_NAME, psz_path ) )
+    if (bindtextdomain (PACKAGE_NAME, psz_path) == NULL)
     {
-        fprintf( stderr, "warning: couldn't bind domain %s in directory %s\n",
-                 PACKAGE_NAME, psz_path );
+        fprintf (stderr, "Warning: cannot bind text domain "PACKAGE_NAME
+                         " to directory %s\n", psz_path);
+        return -1;
     }
 
-    /* Set the default domain */
-    bind_textdomain_codeset( PACKAGE_NAME, "UTF-8" );
+    /* LibVLC wants all messages in UTF-8.
+     * Unfortunately, we cannot ask UTF-8 for strerror(), strsignal()
+     * and other functions that are not part of our text domain.
+     */
+    if (bind_textdomain_codeset (PACKAGE_NAME, "UTF-8") == NULL)
+    {
+        fprintf (stderr, "Error: cannot set Unicode encoding for text domain "
+                         PACKAGE_NAME"\n");
+        // Unbinds the text domain to avoid broken encoding
+        bindtextdomain (PACKAGE_NAME, "DOES_NOT_EXIST");
+        return -1;
+    }
+
+    /* LibVLC does NOT set the default textdomain, since it is a library.
+     * This could otherwise break programs using LibVLC (other than VLC).
+     * textdomain (PACKAGE_NAME);
+     */
 #endif
+    return 0;
 }
 
 /*****************************************************************************
@@ -1203,7 +1208,6 @@ static int GetFilenames( libvlc_int_t *p_vlc, int i_argc, char *ppsz_argv[] )
      * and their input options */
     for( i_opt = i_argc - 1; i_opt >= optind; i_opt-- )
     {
-        const char *psz_target;
         i_options = 0;
 
         /* Count the input options */
@@ -1215,26 +1219,11 @@ static int GetFilenames( libvlc_int_t *p_vlc, int i_argc, char *ppsz_argv[] )
 
         /* TODO: write an internal function of this one, to avoid
          *       unnecessary lookups. */
-        /* FIXME: should we convert options to UTF-8 as well ?? */
 
-#ifdef WIN32
-        if( GetVersion() < 0x80000000 )
-        {
-            VLC_AddTarget( p_vlc->i_object_id, ppsz_argv[i_opt],
-                       (char const **)( i_options ? &ppsz_argv[i_opt + 1] :
-                                        NULL ), i_options,
-                       PLAYLIST_INSERT, 0 );
-        }
-        else
-#endif
-        {
-            psz_target = FromLocale( ppsz_argv[ i_opt ] );
-            VLC_AddTarget( p_vlc->i_object_id, psz_target,
+        VLC_AddTarget( p_vlc->i_object_id, ppsz_argv[i_opt],
                        (char const **)( i_options ? &ppsz_argv[i_opt + 1] :
                                         NULL ), i_options,
                        PLAYLIST_INSERT, 0 );
-            LocaleFree( psz_target );
-        }
     }
 
     return VLC_SUCCESS;
@@ -1330,7 +1319,15 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
         if( psz_module_name && strcmp( psz_module_name,
                                        p_parser->psz_object_name ) )
         {
-            continue;
+            char **pp_shortcut = p_parser->pp_shortcuts;
+            while( *pp_shortcut )
+            {
+                if( !strcmp( psz_module_name, *pp_shortcut ) )
+                    break;
+                pp_shortcut ++;
+            }
+            if( !*pp_shortcut )
+                continue;
         }
 
         /* Ignore modules without config options */
@@ -1765,6 +1762,11 @@ static void InitDeviceValues( libvlc_int_t *p_vlc )
     p_connection = dbus_bus_get ( DBUS_BUS_SYSTEM, &error );
     if( dbus_error_is_set( &error ) )
     {
+#ifdef HAVE_HAL_1
+        libhal_ctx_shutdown( ctx, NULL );
+#else
+        hal_shutdown( ctx );
+#endif
         dbus_error_free( &error );
         return;
     }