mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-31 22:25:25 -04:00
scanner: enforce correct argument type for enums
The scanner now checks whether arguments that have an associated <enum> have the right type. An argument with an enum attribute must be of type int or uint, and if the <enum> with that name has the bitfield attribute set to true, then the argument must be of type uint. Changes since v3: - Remove useless allow_null check - Switch to using bool - Clearer message on errorous input - Minor formatting fix Signed-off-by: Auke Booij <auke@tulcod.com> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com> Reviewed-by: Nils Chr. Brause <nilschrbrause@googlemail.com>
This commit is contained in:
parent
851614fa78
commit
1771299a5a
1 changed files with 69 additions and 0 deletions
|
|
@ -128,6 +128,7 @@ struct arg {
|
|||
char *interface_name;
|
||||
struct wl_list link;
|
||||
char *summary;
|
||||
char *enumeration_name;
|
||||
};
|
||||
|
||||
struct enumeration {
|
||||
|
|
@ -136,6 +137,7 @@ struct enumeration {
|
|||
struct wl_list entry_list;
|
||||
struct wl_list link;
|
||||
struct description *description;
|
||||
bool bitfield;
|
||||
};
|
||||
|
||||
struct entry {
|
||||
|
|
@ -540,6 +542,8 @@ start_element(void *data, const char *element_name, const char **atts)
|
|||
const char *summary = NULL;
|
||||
const char *since = NULL;
|
||||
const char *allow_null = NULL;
|
||||
const char *enumeration_name = NULL;
|
||||
const char *bitfield = NULL;
|
||||
int i, version = 0;
|
||||
|
||||
ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
|
||||
|
|
@ -562,6 +566,10 @@ start_element(void *data, const char *element_name, const char **atts)
|
|||
since = atts[i + 1];
|
||||
if (strcmp(atts[i], "allow-null") == 0)
|
||||
allow_null = atts[i + 1];
|
||||
if (strcmp(atts[i], "enum") == 0)
|
||||
enumeration_name = atts[i + 1];
|
||||
if (strcmp(atts[i], "bitfield") == 0)
|
||||
bitfield = atts[i + 1];
|
||||
}
|
||||
|
||||
ctx->character_data_length = 0;
|
||||
|
|
@ -655,6 +663,11 @@ start_element(void *data, const char *element_name, const char **atts)
|
|||
"allow-null is only valid for objects, strings, and arrays");
|
||||
}
|
||||
|
||||
if (enumeration_name == NULL || strcmp(enumeration_name, "") == 0)
|
||||
arg->enumeration_name = NULL;
|
||||
else
|
||||
arg->enumeration_name = xstrdup(enumeration_name);
|
||||
|
||||
if (summary)
|
||||
arg->summary = xstrdup(summary);
|
||||
|
||||
|
|
@ -665,6 +678,16 @@ start_element(void *data, const char *element_name, const char **atts)
|
|||
fail(&ctx->loc, "no enum name given");
|
||||
|
||||
enumeration = create_enumeration(name);
|
||||
|
||||
if (bitfield == NULL || strcmp(bitfield, "false") == 0)
|
||||
enumeration->bitfield = false;
|
||||
else if (strcmp(bitfield, "true") == 0)
|
||||
enumeration->bitfield = true;
|
||||
else
|
||||
fail(&ctx->loc,
|
||||
"invalid value (%s) for bitfield attribute (only true/false are accepted)",
|
||||
bitfield);
|
||||
|
||||
wl_list_insert(ctx->interface->enumeration_list.prev,
|
||||
&enumeration->link);
|
||||
|
||||
|
|
@ -700,6 +723,46 @@ start_element(void *data, const char *element_name, const char **atts)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
verify_arguments(struct parse_context *ctx, struct wl_list *messages, struct wl_list *enumerations)
|
||||
{
|
||||
struct message *m;
|
||||
wl_list_for_each(m, messages, link) {
|
||||
struct arg *a;
|
||||
wl_list_for_each(a, &m->arg_list, link) {
|
||||
struct enumeration *e, *f;
|
||||
|
||||
if (!a->enumeration_name)
|
||||
continue;
|
||||
|
||||
f = NULL;
|
||||
wl_list_for_each(e, enumerations, link) {
|
||||
if(strcmp(e->name, a->enumeration_name) == 0)
|
||||
f = e;
|
||||
}
|
||||
|
||||
if (f == NULL)
|
||||
fail(&ctx->loc,
|
||||
"could not find enumeration %s",
|
||||
a->enumeration_name);
|
||||
|
||||
switch (a->type) {
|
||||
case INT:
|
||||
if (f->bitfield)
|
||||
fail(&ctx->loc,
|
||||
"bitfield-style enum must only be referenced by uint");
|
||||
break;
|
||||
case UNSIGNED:
|
||||
break;
|
||||
default:
|
||||
fail(&ctx->loc,
|
||||
"enumeration-style argument has wrong type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
end_element(void *data, const XML_Char *name)
|
||||
{
|
||||
|
|
@ -723,6 +786,12 @@ end_element(void *data, const XML_Char *name)
|
|||
ctx->enumeration->name);
|
||||
}
|
||||
ctx->enumeration = NULL;
|
||||
} else if (strcmp(name, "interface") == 0) {
|
||||
struct interface *i = ctx->interface;
|
||||
|
||||
verify_arguments(ctx, &i->request_list, &i->enumeration_list);
|
||||
verify_arguments(ctx, &i->event_list, &i->enumeration_list);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue