Strip terminal controls from status fields

183d43a8d2cf7c64d0e0ecf555a1d3381ae987bb
Alexis Sellier committed ago 1 parent 0a5f86f1
swm.c +6 -3
1458 1458
1459 1459
    return (!rule_id || !strcmp(rule_id, "*") || strstr(appid, rule_id)) &&
1460 1460
           (!rule_title || strstr(title, rule_title));
1461 1461
}
1462 1462
1463 -
/* Replace state-file delimiters in a field. */
1463 +
/* Replace delimiters and terminal control bytes in a published field. */
1464 1464
void swm_sanitize_field(char *dst, size_t size, const char *src, const char *fallback) {
1465 1465
    size_t i;
1466 1466
1467 1467
    if (!size)
1468 1468
        return;
1469 1469
1470 1470
    if (!src || !*src)
1471 1471
        src = fallback ? fallback : "";
1472 1472
1473 -
    for (i = 0; src[i] && i + 1 < size; i++)
1474 -
        dst[i] = src[i] == '\t' || src[i] == '\n' || src[i] == '\r' ? ' ' : src[i];
1473 +
    for (i = 0; src[i] && i + 1 < size; i++) {
1474 +
        unsigned char ch = (unsigned char)src[i];
1475 +
1476 +
        dst[i] = ch < ' ' || ch == 0x7f ? ' ' : src[i];
1477 +
    }
1475 1478
1476 1479
    dst[i] = '\0';
1477 1480
}
1478 1481
1479 1482
/* Parse one persisted window-state record. */
test/unit.c +1 -1
155 155
    struct swm_box geometry;
156 156
157 157
    assert(swm_rule_matches("*", nullptr, "anything", "title"));
158 158
    assert(swm_rule_matches("term", "shell", "my-terminal", "a shell"));
159 159
    assert(!swm_rule_matches("browser", nullptr, "terminal", "browser"));
160 -
    swm_sanitize_field(small, sizeof(small), "a\tb\nc", nullptr);
160 +
    swm_sanitize_field(small, sizeof(small), "a\tb\x1b", nullptr);
161 161
    assert(!strcmp(small, "a b "));
162 162
    assert(swm_parse_window_state(
163 163
        "org.app\tWindow\t1\t-2\t300\t200\n", appid, sizeof(appid), title, sizeof(title), &geometry
164 164
    ));
165 165
    assert(!strcmp(appid, "org.app"));