auto_profiles: try to distinguish invalid properties better

6e4a76db08 attemped to reject invalid
properties and print an error for users so they actually know that
something is going wrong. This worked by simply checking if the property
not found error is returned, but it is actually perfectly possible for a
property to not be found (different than being unavailable just to be
clear here) at first and then show up later. An example would be
user-data which can be created at any time. It's also possible with
subproperties of things like track-list where a new track could be added
later.

In light of this, let's soften the error checking logic here with a
simple trick. mpv already keeps track of all toplevel properties and it
can be easily retrieved with the "property-list" property, so just cache
that. When we get a property not found error, instead of rejecting it,
try to match it something in the property-list first. If we have a
match, then consider the property valid and allow the script to behavior
normally. If not, we reject it. This approach means property names that
are obviously wrong like "fake-property-here" will reliably get rejected
and something like "user-data/test" works as usual. The downside is that
errors in the subproperty level are not caught, so something like
"track-list/0/fake-property" would still be considered valid and the
user gets no warning that this won't work. We'll just accept the
compromise and hope this isn't too common.

Fixes #11550.
This commit is contained in:
Dudemanguy 2023-04-05 19:49:07 -05:00
parent 41372c5e1f
commit 7ae7fc0112
1 changed files with 10 additions and 1 deletions

View File

@ -14,6 +14,12 @@ local pending_hooks = {} -- as set (keys only, meaningless values)
-- profile the condition is evaluated for.
local current_profile = nil
-- Cached set of all top-level mpv properities. Only used for extra validation.
local property_set = {}
for _, property in pairs(mp.get_property_native("property-list")) do
property_set[property] = true
end
local function evaluate(profile)
msg.verbose("Re-evaluating auto profile " .. profile.name)
@ -85,7 +91,10 @@ function get(name, default)
if not watched_properties[name] then
watched_properties[name] = true
local res, err = mp.get_property_native(name)
if err == "property not found" then
-- Property has to not exist and the toplevel of property in the name must also
-- not have an existing match in the property set for this to be considered an error.
-- This allows things like user-data/test to still work.
if err == "property not found" and property_set[name:match("^([^/]+)")] == nil then
msg.error("Property '" .. name .. "' was not found.")
return default
end