[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