From 296027122b0a2946bd6936a8128bb3cec5d1eda2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 27 May 2024 22:31:09 +0200 Subject: [PATCH] varlink: add helper that validates a qualified Varlink symbol name Qualified Varlink symbol names are the combination of an interface name, followed by a dot, followed by a symbol name. It's a primary concept, after all it's what we send over the wire for method calls and get back for error returns. hence, let's add an explicit validator for it. --- src/shared/varlink-idl.c | 22 ++++++++++++++++++++++ src/shared/varlink-idl.h | 2 ++ src/test/test-varlink-idl.c | 11 +++++++++++ 3 files changed, 35 insertions(+) diff --git a/src/shared/varlink-idl.c b/src/shared/varlink-idl.c index 57765b18c29..f81c38c53dd 100644 --- a/src/shared/varlink-idl.c +++ b/src/shared/varlink-idl.c @@ -1452,6 +1452,28 @@ static bool varlink_idl_comment_is_valid(const char *comment) { return utf8_is_valid(comment); } +int varlink_idl_qualified_symbol_name_is_valid(const char *name) { + const char *dot; + + /* Validates a qualified symbol name (i.e. interface name, followed by a dot, followed by a symbol name) */ + + if (!name) + return false; + + dot = strrchr(name, '.'); + if (!dot) + return false; + + if (!varlink_idl_symbol_name_is_valid(dot + 1)) + return false; + + _cleanup_free_ char *iface = strndup(name, dot - name); + if (!iface) + return -ENOMEM; + + return varlink_idl_interface_name_is_valid(iface); +} + static int varlink_idl_symbol_consistent(const VarlinkInterface *interface, const VarlinkSymbol *symbol, int level); static int varlink_idl_field_consistent( diff --git a/src/shared/varlink-idl.h b/src/shared/varlink-idl.h index 03a1a2b2e48..ffb55f30663 100644 --- a/src/shared/varlink-idl.h +++ b/src/shared/varlink-idl.h @@ -170,6 +170,8 @@ bool varlink_idl_field_name_is_valid(const char *name); bool varlink_idl_symbol_name_is_valid(const char *name); bool varlink_idl_interface_name_is_valid(const char *name); +int varlink_idl_qualified_symbol_name_is_valid(const char *name); + int varlink_idl_consistent(const VarlinkInterface *interface, int level); const VarlinkSymbol* varlink_idl_find_symbol(const VarlinkInterface *interface, VarlinkSymbolType type, const char *name); diff --git a/src/test/test-varlink-idl.c b/src/test/test-varlink-idl.c index f14622bd581..c2be1dfec04 100644 --- a/src/test/test-varlink-idl.c +++ b/src/test/test-varlink-idl.c @@ -261,6 +261,17 @@ TEST(field_name_is_valid) { assert_se(varlink_idl_field_name_is_valid("foo0foo")); } +TEST(qualified_symbol_name_is_valid) { + assert_se(varlink_idl_qualified_symbol_name_is_valid(NULL) == 0); + assert_se(varlink_idl_qualified_symbol_name_is_valid("") == 0); + assert_se(varlink_idl_qualified_symbol_name_is_valid("x") == 0); + assert_se(varlink_idl_qualified_symbol_name_is_valid("xxx") == 0); + assert_se(varlink_idl_qualified_symbol_name_is_valid("xxx.xxx") == 0); + assert_se(varlink_idl_qualified_symbol_name_is_valid("xxx.Xxx") > 0); + assert_se(varlink_idl_qualified_symbol_name_is_valid("xxx.xxx.XXX") > 0); + assert_se(varlink_idl_qualified_symbol_name_is_valid("xxx.xxx.0foo") == 0); +} + TEST(validate_json) { _cleanup_(varlink_interface_freep) VarlinkInterface *parsed = NULL;