Skip to content

Commit 074fb88

Browse files
dotclockframebuffer: fix gpio_data range validation
The upper-bound expression used `max_bit * 8` instead of `gpio_data_len * 8`. With `gpio_data_len = 1` (the common case), `max_bit` is 7 and the shift becomes `(1 << 56) - 1`, which is undefined behavior on a 32-bit `mp_int_t`. In practice the upper bound wraps to 1, so any `gpio_data` value > 1 raises `ValueError: gpio_data must be 0..1` even though a full byte is legitimate. This blocks initializing displays through `dotclockframebuffer.ioexpander_send_init_sequence(...)` when the init sequence contains real one-byte register writes; e.g. the Adafruit Qualia ESP32-S3 + 4" 480x480 round TFT crashes during display init. The fix is to use `gpio_data_len` (which is already the field width in bytes) directly. For `gpio_data_len = 1` this gives the correct `(1 << 8) - 1 = 255` upper bound.
1 parent 6b4970b commit 074fb88

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

shared-bindings/dotclockframebuffer/__init__.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ static mp_obj_t ioexpander_send_init_sequence(size_t n_args, const mp_obj_t *pos
104104
mp_arg_validate_int_range(cs_bit, 0, max_bit, MP_QSTR_cs_bit);
105105
mp_arg_validate_int_range(mosi_bit, 0, max_bit, MP_QSTR_mosi_bit);
106106
mp_arg_validate_int_range(clk_bit, 0, max_bit, MP_QSTR_clk_bit);
107-
mp_arg_validate_int_range(gpio_data, 0, (1 << (max_bit * 8)) - 1, MP_QSTR_gpio_data);
107+
mp_arg_validate_int_range(gpio_data, 0, (1 << (gpio_data_len * 8)) - 1, MP_QSTR_gpio_data);
108108
mp_int_t reset_mask = 0;
109109
if (args[ARG_reset_bit].u_obj != MP_ROM_NONE) {
110110
mp_int_t reset_bit = mp_arg_validate_int_range(mp_arg_validate_type_int(args[ARG_reset_bit].u_obj, MP_QSTR_reset_bit), 0, max_bit, MP_QSTR_reset_bit);

0 commit comments

Comments
 (0)