mirror of
https://github.com/swaywm/sway.git
synced 2026-06-13 14:33:19 -04:00
tree/load_layout: escape quotes in swallow values
Swallow values were embedded directly into the synthesised criteria string; a value containing " produced a malformed [key="..."..."] that the criteria tokenizer could not parse, so layouts with quoted titles failed to load. Escape " as \" before embedding so the value survives the tokenizer and is recovered by the existing criteria unescape.
This commit is contained in:
parent
bc357224b8
commit
d882281cde
1 changed files with 28 additions and 7 deletions
|
|
@ -140,21 +140,42 @@ static enum sway_container_border parse_border_name(const char *s) {
|
||||||
return B_NORMAL;
|
return B_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append a key="value" fragment to a malloc'd, null-terminated buffer. The
|
// Escape `"` so the value survives the criteria tokenizer. Backslashes are
|
||||||
// value is the raw regex from the swallows entry; we trust json-c to give us
|
// left alone since PCRE consumes them and criteria's unescape only collapses
|
||||||
// a NUL-terminated string and we do NOT escape internal quotes, i3-save-tree
|
// `\"`.
|
||||||
// already escapes them in its output and hand-written layouts must follow the
|
static char *escape_criteria_value(const char *value) {
|
||||||
// same rule.
|
size_t n = strlen(value);
|
||||||
|
char *out = malloc(n * 2 + 1);
|
||||||
|
if (!out) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size_t pos = 0;
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
if (value[i] == '"') {
|
||||||
|
out[pos++] = '\\';
|
||||||
|
}
|
||||||
|
out[pos++] = value[i];
|
||||||
|
}
|
||||||
|
out[pos] = '\0';
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
static bool append_key_value(char **buf, const char *key, const char *value) {
|
static bool append_key_value(char **buf, const char *key, const char *value) {
|
||||||
|
char *escaped = escape_criteria_value(value);
|
||||||
|
if (!escaped) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
size_t old = *buf ? strlen(*buf) : 0;
|
size_t old = *buf ? strlen(*buf) : 0;
|
||||||
size_t add = strlen(key) + strlen(value) + 5; // ` k="v"`
|
size_t add = strlen(key) + strlen(escaped) + 5; // ` k="v"`
|
||||||
char *grown = realloc(*buf, old + add + 1);
|
char *grown = realloc(*buf, old + add + 1);
|
||||||
if (!grown) {
|
if (!grown) {
|
||||||
|
free(escaped);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*buf = grown;
|
*buf = grown;
|
||||||
int written = snprintf(grown + old, add + 1, "%s%s=\"%s\"",
|
int written = snprintf(grown + old, add + 1, "%s%s=\"%s\"",
|
||||||
old ? " " : "", key, value);
|
old ? " " : "", key, escaped);
|
||||||
|
free(escaped);
|
||||||
if (written < 0) {
|
if (written < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue