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
This commit is contained in:
Craig Barnes 2021-05-16 19:38:00 +01:00
parent 9fe278388b
commit 74f740c975
2 changed files with 13 additions and 2 deletions

View file

@ -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

13
vt.h
View file

@ -1,5 +1,6 @@
#pragma once
#include <limits.h>
#include <stdint.h>
#include <stddef.h>
@ -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;