From 74f740c975782a35fd2438b73f59ef89bbf64f46 Mon Sep 17 00:00:00 2001 From: Craig Barnes Date: Sun, 16 May 2021 19:38:00 +0100 Subject: [PATCH] vt: limit maximum value of params in vt_param_get() So that the value is clamped to the range [0, 0x7fffffff] and retains the same value, regardless of whether it's interpreted as a signed or unsigned integer. Closes #522 --- CHANGELOG.md | 2 ++ vt.h | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) 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;