diff --git a/src/shared/uapi16-manifest.c b/src/shared/uapi16-manifest.c index bff48145756..974fd7e1753 100644 --- a/src/shared/uapi16-manifest.c +++ b/src/shared/uapi16-manifest.c @@ -536,7 +536,7 @@ static int json_dispatch_contents(const char *name, sd_json_variant *variant, sd if (r < 0) return r; - if (!!c.file + !!c.url + !!iovec_is_set(&c.literal) > 1) + if (!!c.file + !!c.url + uapi16_contents_has_literal(&c) > 1) return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "Only one of 'file', 'url', 'literal' may be set for '%s'.", strna(name)); if (c.encoding) { diff --git a/src/shared/uapi16-manifest.h b/src/shared/uapi16-manifest.h index 55d6a7b1dcd..38746e17661 100644 --- a/src/shared/uapi16-manifest.h +++ b/src/shared/uapi16-manifest.h @@ -26,6 +26,13 @@ typedef struct Uapi16Contents { .original_size = UINT64_MAX, \ } +static inline bool uapi16_contents_has_literal(const Uapi16Contents *c) { + /* An empty "literal" field is valid (it encodes empty data), hence check whether the field was set, + * not whether it carries data: when decoding Base64 we always allocate a buffer, even for empty + * data. */ + return c->literal.iov_base; +} + /* An extended attribute in the "user" namespace */ typedef struct Uapi16Xattr { char *name; /* The attribute name, without the "user." prefix */