Skip to content

Commit fece0fb

Browse files
committed
Fix crash when UART construct fails
After the script stops with the exception thrown the final gc_sweep will call any finalizers and they usually call deinit. deinit on invalid objects can wreak havoc by changing random memory or (hopefully) crashing. This fixes ensures the object is deinited until initialization succeeds and the object is valid. Do the same fix for I2C and SPI too. Fixes #4700 and fixes #5005
1 parent ce73015 commit fece0fb

File tree

4 files changed

+25
-6
lines changed

4 files changed

+25
-6
lines changed

locale/circuitpython.pot

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ msgstr ""
143143
msgid "%q must be between %d and %d"
144144
msgstr ""
145145

146+
#: ports/atmel-samd/common-hal/busio/UART.c
147+
msgid "%q must be power of 2"
148+
msgstr ""
149+
146150
#: py/argcheck.c
147151
msgid "%q must of type %q"
148152
msgstr ""
@@ -389,6 +393,7 @@ msgstr ""
389393
msgid "All event channels in use"
390394
msgstr ""
391395

396+
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
392397
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
393398
msgid "All state machines in use"
394399
msgstr ""
@@ -973,7 +978,7 @@ msgstr ""
973978
msgid "Expected an alarm"
974979
msgstr ""
975980

976-
#: shared-module/_pixelbuf/PixelBuf.c
981+
#: shared-module/adafruit_pixelbuf/PixelBuf.c
977982
#, c-format
978983
msgid "Expected tuple of length %d, got %d"
979984
msgstr ""
@@ -1295,7 +1300,7 @@ msgstr ""
12951300
msgid "Invalid buffer size"
12961301
msgstr ""
12971302

1298-
#: shared-bindings/_pixelbuf/PixelBuf.c
1303+
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
12991304
msgid "Invalid byteorder string"
13001305
msgstr ""
13011306

@@ -1501,7 +1506,7 @@ msgstr ""
15011506
msgid "Missing first_set_pin. Instruction %d sets pin(s)"
15021507
msgstr ""
15031508

1504-
#: shared-bindings/displayio/Group.c
1509+
#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c
15051510
msgid "Must be a %q subclass."
15061511
msgstr ""
15071512

@@ -2348,7 +2353,7 @@ msgstr ""
23482353
msgid "Unknown system firmware error: %04x"
23492354
msgstr ""
23502355

2351-
#: shared-bindings/_pixelbuf/PixelBuf.c
2356+
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
23522357
#, c-format
23532358
msgid "Unmatched number of items on RHS (expected %d, got %d)."
23542359
msgstr ""
@@ -2631,7 +2636,7 @@ msgstr ""
26312636
msgid "buttons must be digitalio.DigitalInOut"
26322637
msgstr ""
26332638

2634-
#: shared-bindings/_pixelbuf/PixelBuf.c
2639+
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
26352640
msgid "byteorder is not a string"
26362641
msgstr ""
26372642

@@ -2681,7 +2686,7 @@ msgid "can't cancel self"
26812686
msgstr ""
26822687

26832688
#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c
2684-
#: shared-module/_pixelbuf/PixelBuf.c
2689+
#: shared-module/adafruit_pixelbuf/PixelBuf.c
26852690
msgid "can't convert %q to %q"
26862691
msgstr ""
26872692

ports/atmel-samd/common-hal/busio/I2C.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
7171
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
7272
uint8_t sercom_index;
7373
uint32_t sda_pinmux, scl_pinmux;
74+
75+
// Ensure the object starts in its deinit state.
76+
self->sda_pin = NO_PIN;
7477
Sercom *sercom = samd_i2c_get_sercom(scl, sda, &sercom_index, &sda_pinmux, &scl_pinmux);
7578
if (sercom == NULL) {
7679
mp_raise_ValueError(translate("Invalid pins"));

ports/atmel-samd/common-hal/busio/SPI.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
9292
uint8_t miso_pad = 0;
9393
uint8_t dopo = 255;
9494

95+
// Ensure the object starts in its deinit state.
96+
self->clock_pin = NO_PIN;
97+
9598
// Special case for SAMR21 boards. (feather_radiofruit_zigbee)
9699
#if defined(PIN_PC19F_SERCOM4_PAD0)
97100
if (miso == &pin_PC19) {

ports/atmel-samd/common-hal/busio/UART.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
7171
uint32_t tx_pinmux = 0;
7272
uint8_t tx_pad = 255; // Unset pad
7373

74+
// Set state so the object is deinited to start.
75+
self->rx_pin = NO_PIN;
76+
self->tx_pin = NO_PIN;
77+
7478
if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) {
7579
mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device"));
7680
}
@@ -85,6 +89,10 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
8589
mp_raise_ValueError(translate("tx and rx cannot both be None"));
8690
}
8791

92+
if (have_rx && receiver_buffer_size > 0 && (receiver_buffer_size & (receiver_buffer_size - 1)) != 0) {
93+
mp_raise_ValueError_varg(translate("%q must be power of 2"), MP_QSTR_receiver_buffer_size);
94+
}
95+
8896
self->baudrate = baudrate;
8997
self->character_bits = bits;
9098
self->timeout_ms = timeout * 1000;

0 commit comments

Comments
 (0)