sd-varlink: Return empty object for missing params
Previously, sd-varlink was inconsistent about what it did with empty/missing/null parameters in a Varlink call or reply: when dispatching to a callback, it would always construct an empty object and hand over the empty object to the handler (good!). But when returning the value directly (i.e. with sd_varlink_call), it would return NULL when parameters were omitted and a JSON null when the paramerters were null. This inconsistency is a violation of UAPI.20, which states that receivers of Varlink messages MUST treat omitted/null/empty parameters on Varlink calls and replies equivalently, where senders only SHOULD prefer to omit the parameters. This commit makes sd-varlink normalize the parameters to an empty object whenever it is null or omitted, which brings sd-varlink into compliance with this rule in UAPI.20 (cherry picked from commit 34db99971e728e2c4f155c01d43d24f3fe313bef)
This commit is contained in:
committed by
Luca Boccassi
parent
adc93a4ad5
commit
ffcf226c7f
@@ -380,5 +380,24 @@ echo "$result" | grep "untrusted data decompressed safely" >/dev/null
|
||||
kill "$SERVE_PID" 2>/dev/null || true
|
||||
wait "$SERVE_PID" 2>/dev/null || true
|
||||
|
||||
# Verify consistent handling of omitted/null/empty parameters
|
||||
check_output_is_empty_object() {
|
||||
REPLY="$1"
|
||||
# This is a "Varlink server" that reads the incoming call, discards it, and
|
||||
# directly sends the contents of $REPLY as the reply. This lets us exercise
|
||||
# sd-varlink's client-side parsing of the Varlink call/reply framing
|
||||
# shellcheck disable=SC2016
|
||||
SERVE_PID=$(systemd-notify --fork -- \
|
||||
systemd-socket-activate -l "$SERVE_SOCKET" --inetd -a -- \
|
||||
bash -c 'read -r -d "" _; printf "%s\0" "$0"' "$REPLY")
|
||||
varlinkctl call "unix:$SERVE_SOCKET" com.example.Test '{}' | grep "^{}$"
|
||||
varlinkctl --exec call "unix:$SERVE_SOCKET" com.example.Test '{}' -- grep "^{}$"
|
||||
kill "$SERVE_PID" 2>/dev/null || true
|
||||
wait "$SERVE_PID" 2>/dev/null || true
|
||||
}
|
||||
check_output_is_empty_object '{}'
|
||||
check_output_is_empty_object '{"parameters": null}'
|
||||
check_output_is_empty_object '{"parameters": {}}'
|
||||
|
||||
rm -f "$SERVE_SOCKET"
|
||||
rm -rf "$(dirname "$SERVE_SOCKET")" "$SERVE_TMPDIR"
|
||||
|
||||
Reference in New Issue
Block a user