mirror of
https://github.com/swaywm/sway.git
synced 2026-06-13 14:33:19 -04:00
tree/load_layout: validate window_type literals strictly
Anchored ^name$ and bare names are accepted; everything else, including regex alternation, returns a clear error instead of silently falling through to ATOM_LAST.
This commit is contained in:
parent
0bb4aba044
commit
93931c37a6
2 changed files with 43 additions and 21 deletions
|
|
@ -426,7 +426,13 @@ runtime.
|
||||||
*class*, *instance*, *title*, *window_role*, and *window_type* keys
|
*class*, *instance*, *title*, *window_role*, and *window_type* keys
|
||||||
(which target xwayland views), each *swallows* entry may include
|
(which target xwayland views), each *swallows* entry may include
|
||||||
*app_id* to match Wayland views. The *machine* key is logged and
|
*app_id* to match Wayland views. The *machine* key is logged and
|
||||||
ignored. All values are PCRE2 regex strings.
|
ignored. *class*, *instance*, *title*, *window_role* and *app_id*
|
||||||
|
are PCRE2 regex strings. *window_type* must be a literal atom name
|
||||||
|
(*normal*, *dialog*, *utility*, *toolbar*, *splash*, *menu*,
|
||||||
|
*dropdown_menu*, *popup_menu*, *tooltip*, *notification*); the
|
||||||
|
i3-save-tree anchored form _^name$_ is accepted, but regex
|
||||||
|
alternation such as _^(normal|dialog)$_ is rejected, split such
|
||||||
|
patterns into multiple swallows entries (which match as OR).
|
||||||
|
|
||||||
A minimal example targeting one Wayland and one xwayland window in
|
A minimal example targeting one Wayland and one xwayland window in
|
||||||
a vertical split:
|
a vertical split:
|
||||||
|
|
|
||||||
|
|
@ -227,27 +227,38 @@ static bool append_bare(char **buf, const char *key, const char *value) {
|
||||||
return written >= 0;
|
return written >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// i3-save-tree emits window_type as a regex-anchored enum name like
|
// window_type is parsed as an enum, not a regex. Accept i3-save-tree's
|
||||||
// "^normal$". The criteria parser treats window_type as a bare enum token,
|
// "^name$" form and bare names; reject anything else (including alternation)
|
||||||
// not a regex, so the anchored form fails. Strip a single leading ^ and a
|
// rather than letting the criteria parser silently fall through to ATOM_LAST.
|
||||||
// single trailing $ before passing through.
|
static const char *known_window_types[] = {
|
||||||
static char *unanchor_enum(const char *value) {
|
"normal", "dialog", "utility", "toolbar", "splash", "menu",
|
||||||
|
"dropdown_menu", "popup_menu", "tooltip", "notification", NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *parse_window_type_value(const char *value, char **error_out) {
|
||||||
size_t n = strlen(value);
|
size_t n = strlen(value);
|
||||||
size_t start = 0;
|
size_t start = (n > 0 && value[0] == '^') ? 1 : 0;
|
||||||
size_t end = n;
|
size_t end = (n > start && value[n - 1] == '$') ? n - 1 : n;
|
||||||
if (n > 0 && value[0] == '^') {
|
size_t bare_len = end - start;
|
||||||
start = 1;
|
char *bare = malloc(bare_len + 1);
|
||||||
}
|
if (!bare) {
|
||||||
if (end > start && value[end - 1] == '$') {
|
*error_out = format_str("append_layout: out of memory");
|
||||||
end--;
|
|
||||||
}
|
|
||||||
char *out = malloc(end - start + 1);
|
|
||||||
if (!out) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(out, value + start, end - start);
|
memcpy(bare, value + start, bare_len);
|
||||||
out[end - start] = '\0';
|
bare[bare_len] = '\0';
|
||||||
return out;
|
for (int i = 0; known_window_types[i]; i++) {
|
||||||
|
if (strcasecmp(bare, known_window_types[i]) == 0) {
|
||||||
|
return bare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*error_out = format_str("append_layout: window_type %s is not a "
|
||||||
|
"supported literal value (use one of: normal, dialog, "
|
||||||
|
"utility, toolbar, splash, menu, dropdown_menu, popup_menu, "
|
||||||
|
"tooltip, notification; regex alternation is not supported, "
|
||||||
|
"split into multiple swallow entries instead)", value);
|
||||||
|
free(bare);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// app_id is a sway extension over i3's swallows schema; machine is ignored.
|
// app_id is a sway extension over i3's swallows schema; machine is ignored.
|
||||||
|
|
@ -287,8 +298,13 @@ static struct criteria *build_swallow_criteria(struct json_object *entry,
|
||||||
"append_layout: swallows.window_type is not a string");
|
"append_layout: swallows.window_type is not a string");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
char *bare = unanchor_enum(json_object_get_string(wt));
|
char *bare = parse_window_type_value(json_object_get_string(wt),
|
||||||
if (!bare || !append_bare(&body, "window_type", bare)) {
|
error_out);
|
||||||
|
if (!bare) {
|
||||||
|
free(body);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!append_bare(&body, "window_type", bare)) {
|
||||||
free(bare);
|
free(bare);
|
||||||
free(body);
|
free(body);
|
||||||
*error_out = format_str("append_layout: out of memory");
|
*error_out = format_str("append_layout: out of memory");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue