Skip to content

Commit b01a698

Browse files
committed
Add NULL checks to per-frame allocations
Cover the per-frame allocations in do_update, clear_screen, and dcs_lcd_draw_buffer across all four ESP32 drivers. On failure, skip the frame with a log line and free any already-acquired resources. The caller's reply has already been sent at enqueue time (see the prior pre-ack commit), so there is no reply obligation. Also fix an oled do_update early-return on i2c_driver_acquire failure that leaked both `items` and `buf`. Init-time allocations in *_create_port / display_init / display_spi_init remain unchecked; context-teardown-on-init- failure is tracked as a separate follow-up.
1 parent 9bd2e1e commit b01a698

5 files changed

Lines changed: 45 additions & 0 deletions

File tree

dcs_lcd_commands.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020

2121
#include "dcs_lcd_commands.h"
2222

23+
#include <stdio.h>
2324
#include <stdlib.h>
2425

26+
#include <utils.h>
27+
2528
#include <freertos/FreeRTOS.h>
2629
#include <freertos/task.h>
2730

@@ -62,6 +65,11 @@ void dcs_lcd_draw_buffer(struct SPIDCBus *bus, const struct DCSLCDScreen *screen
6265
if (pixel_bytes == 2) {
6366
int buf_pixel_size = (dest_size > 1024) ? 1024 : dest_size;
6467
uint16_t *tmpbuf = heap_caps_malloc(buf_pixel_size * sizeof(uint16_t), MALLOC_CAP_DMA);
68+
if (UNLIKELY(!tmpbuf)) {
69+
fprintf(stderr, "dcs_lcd_draw_buffer: failed to alloc tmpbuf (rgb565)\n");
70+
spi_device_release_bus(bus->spi_disp.handle);
71+
return;
72+
}
6573

6674
for (int i = 0; i < chunks; i++) {
6775
const uint16_t *data_b = data + 1024 * i;
@@ -86,6 +94,11 @@ void dcs_lcd_draw_buffer(struct SPIDCBus *bus, const struct DCSLCDScreen *screen
8694
// ILI9488: RGB565 -> RGB888 (3 bytes/pixel).
8795
const int chunk_pixels = 512;
8896
uint8_t *tmpbuf = heap_caps_malloc(chunk_pixels * 3, MALLOC_CAP_DMA);
97+
if (UNLIKELY(!tmpbuf)) {
98+
fprintf(stderr, "dcs_lcd_draw_buffer: failed to alloc tmpbuf (rgb888)\n");
99+
spi_device_release_bus(bus->spi_disp.handle);
100+
return;
101+
}
89102

90103
int i = 0;
91104
while (i < dest_size) {

dcs_lcd_display_driver.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ static void do_update(Context *ctx, term display_list)
143143
int len = term_list_length(display_list, &proper);
144144

145145
BaseDisplayItem *items = malloc(sizeof(BaseDisplayItem) * len);
146+
if (UNLIKELY(!items)) {
147+
fprintf(stderr, "do_update: failed to alloc items\n");
148+
return;
149+
}
146150

147151
term t = display_list;
148152
for (int i = 0; i < len; i++) {

epaper_display_driver.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ static void do_update(Context *ctx, term display_list)
186186
int len = term_list_length(display_list, &proper);
187187

188188
BaseDisplayItem *items = malloc(sizeof(BaseDisplayItem) * len);
189+
if (UNLIKELY(!items)) {
190+
fprintf(stderr, "do_update: failed to alloc items\n");
191+
return;
192+
}
189193

190194
term t = display_list;
191195
for (int i = 0; i < len; i++) {
@@ -203,6 +207,11 @@ static void do_update(Context *ctx, term display_list)
203207
spi_dc_write_command(&driver->bus, 0x10);
204208

205209
uint8_t *buf = heap_caps_malloc(screen_width / 2, MALLOC_CAP_DMA);
210+
if (UNLIKELY(!buf)) {
211+
fprintf(stderr, "do_update: failed to alloc buf\n");
212+
display_items_delete(items, len);
213+
return;
214+
}
206215
memset(buf, 0x11, screen_width / 2);
207216

208217
bool transaction_in_progress = false;
@@ -294,6 +303,10 @@ static void clear_screen(Context *ctx, int color)
294303
spi_dc_write_command(&driver->bus, 0x10);
295304

296305
uint8_t *buf = heap_caps_malloc(screen_width / 2, MALLOC_CAP_DMA);
306+
if (UNLIKELY(!buf)) {
307+
fprintf(stderr, "clear_screen: failed to alloc buf\n");
308+
return;
309+
}
297310

298311
bool transaction_in_progress = false;
299312

memory_display_driver.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ static void do_update(Context *ctx, term display_list)
9898
int len = term_list_length(display_list, &proper);
9999

100100
BaseDisplayItem *items = malloc(sizeof(BaseDisplayItem) * len);
101+
if (UNLIKELY(!items)) {
102+
fprintf(stderr, "do_update: failed to alloc items\n");
103+
return;
104+
}
101105

102106
term t = display_list;
103107
for (int i = 0; i < len; i++) {

oled_display_driver.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ static void do_update(Context *ctx, term display_list)
100100
int len = term_list_length(display_list, &proper);
101101

102102
BaseDisplayItem *items = malloc(sizeof(BaseDisplayItem) * len);
103+
if (UNLIKELY(!items)) {
104+
fprintf(stderr, "do_update: failed to alloc items\n");
105+
return;
106+
}
103107

104108
term t = display_list;
105109
for (int i = 0; i < len; i++) {
@@ -113,11 +117,18 @@ static void do_update(Context *ctx, term display_list)
113117

114118
int memsize = (DISPLAY_WIDTH * (PAGE_HEIGHT + 1)) / sizeof(uint8_t);
115119
uint8_t *buf = malloc(memsize);
120+
if (UNLIKELY(!buf)) {
121+
fprintf(stderr, "do_update: failed to alloc buf\n");
122+
display_items_delete(items, len);
123+
return;
124+
}
116125
memset(buf, 0, memsize);
117126

118127
i2c_port_t i2c_num;
119128
if (i2c_driver_acquire(driver->i2c_host, &i2c_num, ctx->global) != I2CAcquireOk) {
120129
fprintf(stderr, "Invalid I2C peripheral\n");
130+
free(buf);
131+
display_items_delete(items, len);
121132
return;
122133
}
123134

0 commit comments

Comments
 (0)