diff --git a/CHANGELOG.md b/CHANGELOG.md index 658faa35..8cbe3eba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -108,6 +108,8 @@ * Fonts sometimes not being reloaded with the correct scaling factor when `dpi-aware=no`, or `dpi-aware=auto` with monitor(s) with a scaling factor > 1 (https://codeberg.org/dnkl/foot/issues/509). +* Crash caused by certain CSI sequences with very large parameter + values (https://codeberg.org/dnkl/foot/issues/522). ### Security diff --git a/vt.h b/vt.h index 0e85a75b..66958462 100644 --- a/vt.h +++ b/vt.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -10,9 +11,17 @@ void vt_from_slave(struct terminal *term, const uint8_t *data, size_t len); static inline int vt_param_get(const struct terminal *term, size_t idx, int default_value) { + /* + * We zero excess bits in parsed param values. In most cases this will + * effectively be a no-op; but it prevents negative returns for edge + * cases involving unusually large values. + */ + static_assert(INT_MAX >= 0x7fffffff, "POSIX requires INT_MAX >= 0x7fffffff"); + const unsigned value_mask = 0x7fffffff; + if (term->vt.params.idx > idx) { - int value = term->vt.params.v[idx].value; - return value != 0 ? value : default_value; + unsigned value = term->vt.params.v[idx].value & value_mask; + return value != 0 ? (int)value : default_value; } return default_value;