Fail on unknown (alphanumerical) specifiers
The code intentionally ignored unknown specifiers, treating them as text. This
needs to change because otherwise we can never add a new specifier in a backwards
compatible way. So just treat an unknown (potential) specifier as an error.
In principle this is a break of backwards compatibility, but the previous
behaviour was pretty much useless, since the expanded value could change every
time we add new specifiers, which we do all the time.
As a compromise for backwards compatibility, only fail on alphanumerical
characters. This should cover the most cases where an unescaped percent
character is used, like size=5% and such, which behave the same as before with
this patch. OTOH, this means that we will not be able to use non-alphanumerical
specifiers without breaking backwards compatibility again. I think that's an
acceptable compromise.
v2:
- add NEWS entry
v3:
- only fail on alphanumerical
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index e0d96d6..4e61528 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -1867,7 +1867,8 @@
&age,
NULL);
if (r < 0) {
- if (r == -EINVAL) /* invalid quoting and such */
+ if (IN_SET(r, -EINVAL, -EBADSLT))
+ /* invalid quoting and such or an unknown specifier */
*invalid_config = true;
return log_error_errno(r, "[%s:%u] Failed to parse line: %m", fname, line);
}
@@ -1916,8 +1917,8 @@
if (r == -ENOKEY)
return log_unresolvable_specifier(fname, line);
if (r < 0) {
- /* ENOMEM is the only return value left after ENOKEY,
- * so *invalid_config should not be set. */
+ if (IN_SET(r, -EINVAL, -EBADSLT))
+ *invalid_config = true;
return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s", fname, line, path);
}
@@ -2028,7 +2029,7 @@
return -EBADMSG;
}
r = parse_attribute_from_arg(&i);
- if (r == -EINVAL)
+ if (IN_SET(r, -EINVAL, -EBADSLT))
*invalid_config = true;
if (r < 0)
return r;
@@ -2054,9 +2055,12 @@
r = specifier_expansion_from_arg(&i);
if (r == -ENOKEY)
return log_unresolvable_specifier(fname, line);
- if (r < 0)
+ if (r < 0) {
+ if (IN_SET(r, -EINVAL, -EBADSLT))
+ *invalid_config = true;
return log_error_errno(r, "[%s:%u] Failed to substitute specifiers in argument: %m",
fname, line);
+ }
if (arg_root) {
char *p;