[vlc-commits] [Git][videolan/vlc][master] 5 commits: modules: early-continue if cb == NULL

Steve Lhomme (@robUx4) gitlab at videolan.org
Tue Jul 2 09:46:47 UTC 2024



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
c3c40f68 by Alexandre Janniaux at 2024-07-02T09:33:44+00:00
modules: early-continue if cb == NULL

If cb == NULL, ret will keep the VLC_EGENERIC value and the next item
will be loaded without additional effects. Better discard the current
module and early-continue to avoid the additional indentation level and
make it clearer that a cb == NULL will lead to the module being skipped.

- - - - -
a809e649 by Alexandre Janniaux at 2024-07-02T09:33:44+00:00
filter_chain: remove usage of VLA

- - - - -
74004507 by Alexandre Janniaux at 2024-07-02T09:33:44+00:00
filter_chain: factor module loading

Factor the call to module_need() so it can be changed into
vlc_module_match in one shot. No functional changes.

- - - - -
62fdad12 by Alexandre Janniaux at 2024-07-02T09:33:44+00:00
filter_chain: rework module loading with vlc_module_match

vlc_module_match will allow replacing the module activation function,
but more importantly allows setting the filter->p_module member
attribute so that filters can actually know which filter is being loaded
when names are supplied to the loading function.

For instance:

    filter_t *filter = filter_chain_AppendFilter(
        chain, "filter1,fallback1", cfg, fmt_out);

would try filter1, then fallback1, with `filter->psz_name` being set to
filter1,fallback1, and `filter->p_module` to `NULL`.

By setting `filter->p_module` beforehand, an activation function can
check which (sub)module is being loaded and adapt its behaviour
accordingly.

- - - - -
ea5fb3c2 by Alexandre Janniaux at 2024-07-02T09:33:44+00:00
filter_chain: fix activation function type

Before the previous commit, the activation function was implicitely of
type int (*)(vlc_object_t *) because module_need was used. But the 
following commits changed the activation function for the modules:

 - 95c4582681a994a5c2a9301b20015151eec7a101
 - c9f42135fb5c9eeb740a522116036707ce921eb7
 - f9ab141d20fe03fd06fbb8ab2f08849e9c35afe3
 - b027f1a6c792da764bec4290b2510bbc14dc18a3
 - 94e23d51bb91cff1c14ef1079193920f04f48fd1
 - 0d5d447d704644f425727a86404ba1646b06062a
 - 1c87e2904259201f0c0b08c44a30e38003c36848

It led to the activation function being called with non-matching
parameters, which is UB and crashes on some platforms where types are
checked, like when executing from WASM VMs.

This commit explicitely changes the type to a matching one for every
filter type.

- - - - -


2 changed files:

- src/misc/filter_chain.c
- src/modules/modules.c


Changes:

=====================================
src/misc/filter_chain.c
=====================================
@@ -240,21 +240,64 @@ static filter_t *filter_chain_AppendInner( filter_chain_t *chain,
     else
         filter->owner.sub = NULL;
 
+    char *name_chained = NULL;
+    const char *module_name = name;
     assert( capability != NULL );
-    if( name != NULL && chain->b_allow_fmt_out_change )
+    if (name != NULL && name[0] != '\0' && chain->b_allow_fmt_out_change )
     {
         /* Append the "chain" video filter to the current list.
          * This filter will be used if the requested filter fails to load.
          * It will then try to add a video converter before. */
-        char name_chained[strlen(name) + sizeof(",chain")];
-        sprintf( name_chained, "%s,chain", name );
-        filter->p_module = module_need( filter, capability, name_chained, true );
+        if (asprintf(&name_chained, "%s,chain", name) == -1)
+            goto error;
+        module_name = name_chained;
     }
-    else
-        filter->p_module = module_need( filter, capability, name, name != NULL );
+    else if (name == NULL || name[0] != '\0')
+        module_name = "any";
 
-    if( filter->p_module == NULL )
+    struct vlc_logger *logger = vlc_object_logger(chain->obj);
+    module_t **modules;
+    size_t strict_total;
+    ssize_t count = vlc_module_match(capability, module_name, name != NULL,
+                                     &modules, &strict_total);
+
+    if (count < 0)
+    {
+        free(name_chained);
         goto error;
+    }
+
+    vlc_debug(logger, "looking for %s module matching \"%s\": %zd candidates",
+              capability, module_name, count);
+    free(name_chained);
+
+    int ret = VLC_ENOTSUP;
+    for (size_t i = 0; i < (size_t)count; ++i)
+    {
+        module_t *mod = modules[i];
+        int (*activate)(filter_t *) = vlc_module_map(logger, mod);
+        if (activate == NULL)
+            continue;
+
+        filter->p_module = mod;
+        filter->obj.force = i < strict_total;
+        ret = (*activate)(filter);
+        switch (ret)
+        {
+            case VLC_SUCCESS:
+                goto done;
+            case VLC_ENOMEM:
+                goto error;
+            default:
+                vlc_objres_clear(&filter->obj);
+                continue;
+        }
+    }
+
+   if (ret != VLC_SUCCESS)
+      goto error;
+
+done:
     assert( filter->ops != NULL );
 
     vlc_list_append( &chained->node, &chain->filter_list );
@@ -272,6 +315,7 @@ error:
         msg_Err( chain->obj, "Failed to create %s '%s'", capability, name );
     else
         msg_Err( chain->obj, "Failed to create %s", capability );
+    vlc_objres_clear(&filter->obj);
     es_format_Clean( &filter->fmt_out );
     es_format_Clean( &filter->fmt_in );
     vlc_object_delete(filter);


=====================================
src/modules/modules.c
=====================================
@@ -221,13 +221,14 @@ module_t *(vlc_module_load)(struct vlc_logger *log, const char *capability,
         int ret = VLC_EGENERIC;
         void *cb = vlc_module_map(log, cand);
 
-        if (cb != NULL) {
-            va_list ap;
+        if (cb == NULL)
+            continue;
 
-            va_copy(ap, args);
-            ret = probe(cb, i < strict_total, ap);
-            va_end(ap);
-        }
+        va_list ap;
+
+        va_copy(ap, args);
+        ret = probe(cb, i < strict_total, ap);
+        va_end(ap);
 
         switch (ret) {
             case VLC_SUCCESS:



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/14dfdfa01e5bff7814c31867eb8f59261d69d38b...ea5fb3c2b5ab51632c46103d99cf5c50377d13df

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/14dfdfa01e5bff7814c31867eb8f59261d69d38b...ea5fb3c2b5ab51632c46103d99cf5c50377d13df
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