diff options
| author | Simon Ser <contact@emersion.fr> | 2022-09-17 10:53:56 +0200 |
|---|---|---|
| committer | Simon Ser <contact@emersion.fr> | 2024-04-23 09:17:02 +0000 |
| commit | b258d5f36137088e5cb5ae097db7964290da7d55 (patch) | |
| tree | 2f59d6061156e64e8c5797942fe4818ab69529be /src | |
| parent | Clarify behavior of buffer transformations (diff) | |
| download | wayland-b258d5f36137088e5cb5ae097db7964290da7d55.tar wayland-b258d5f36137088e5cb5ae097db7964290da7d55.tar.gz wayland-b258d5f36137088e5cb5ae097db7964290da7d55.tar.bz2 wayland-b258d5f36137088e5cb5ae097db7964290da7d55.tar.lz wayland-b258d5f36137088e5cb5ae097db7964290da7d55.tar.xz wayland-b258d5f36137088e5cb5ae097db7964290da7d55.tar.zst wayland-b258d5f36137088e5cb5ae097db7964290da7d55.zip | |
scanner: add validators for enums
Right now compositors need to manually check that enum values sent
by the client are valid. In particular:
- Check that the value sent by the client is not outside of the enum.
- Check that the version of the enum entry is consistent with the
object version.
Automatically generate validator functions to perform these tasks.
Signed-off-by: Simon Ser <contact@emersion.fr>
Closes: https://gitlab.freedesktop.org/wayland/wayland/-/issues/104
Diffstat (limited to 'src')
| -rw-r--r-- | src/scanner.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/src/scanner.c b/src/scanner.c index 3257cb6..3f528f3 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -1344,7 +1344,7 @@ emit_event_wrappers(struct wl_list *message_list, struct interface *interface) } static void -emit_enumerations(struct interface *interface) +emit_enumerations(struct interface *interface, bool with_validators) { struct enumeration *e; struct entry *entry; @@ -1401,6 +1401,33 @@ emit_enumerations(struct interface *interface) } + if (with_validators) { + printf("/**\n" + " * @ingroup iface_%s\n" + " * Validate a %s %s value.\n" + " *\n" + " * @return true on success, false on error.\n" + " * @ref %s_%s\n" + " */\n" + "static inline bool\n" + "%s_%s_is_valid(uint32_t value, uint32_t version) {\n" + " switch (value) {\n", + interface->name, interface->name, e->name, + interface->name, e->name, + interface->name, e->name); + wl_list_for_each(entry, &e->entry_list, link) { + printf(" case %s%s_%s_%s:\n" + " return version >= %d;\n", + entry->value[0] == '-' ? "(uint32_t)" : "", + interface->uppercase_name, e->uppercase_name, + entry->uppercase_name, entry->since); + } + printf(" default:\n" + " return false;\n" + " }\n" + "}\n"); + } + printf("#endif /* %s_%s_ENUM */\n\n", interface->uppercase_name, e->uppercase_name); } @@ -1677,7 +1704,7 @@ emit_header(struct protocol *protocol, enum side side) wl_list_for_each_safe(i, i_next, &protocol->interface_list, link) { - emit_enumerations(i); + emit_enumerations(i, side == SERVER); if (side == SERVER) { emit_structs(&i->request_list, i, side); @@ -1720,7 +1747,7 @@ emit_enum_header(struct protocol *protocol) protocol->uppercase_name); wl_list_for_each_safe(i, i_next, &protocol->interface_list, link) { - emit_enumerations(i); + emit_enumerations(i, false); free_interface(i); } @@ -1849,7 +1876,8 @@ emit_code(struct protocol *protocol, enum visibility vis) if (protocol->copyright) format_text_to_comment(protocol->copyright, true); - printf("#include <stdlib.h>\n" + printf("#include <stdbool.h>\n" + "#include <stdlib.h>\n" "#include <stdint.h>\n" "#include \"wayland-util.h\"\n\n"); |
