Skip to content

Commit

Permalink
fix out of bounds write in diff
Browse files Browse the repository at this point in the history
  • Loading branch information
vroland committed Feb 11, 2024
1 parent dfddfb7 commit 3c16dfd
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 28 deletions.
9 changes: 9 additions & 0 deletions src/board/pca9555.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ static esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t* data_rd, siz
return ESP_OK;
}
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
if (cmd == NULL) {
ESP_LOGE("epdiy", "insufficient memory for I2C transaction");
}
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( EPDIY_PCA9555_ADDR << 1 ) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg, true);
Expand All @@ -37,6 +40,9 @@ static esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t* data_rd, siz
i2c_cmd_link_delete(cmd);

cmd = i2c_cmd_link_create();
if (cmd == NULL) {
ESP_LOGE("epdiy", "insufficient memory for I2C transaction");
}
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( EPDIY_PCA9555_ADDR << 1 ) | I2C_MASTER_READ, true);
if (size > 1) {
Expand All @@ -57,6 +63,9 @@ static esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t* data_rd, siz
static esp_err_t i2c_master_write_slave(i2c_port_t i2c_num, uint8_t ctrl, uint8_t* data_wr, size_t size)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
if (cmd == NULL) {
ESP_LOGE("epdiy", "insufficient memory for I2C transaction");
}
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( EPDIY_PCA9555_ADDR << 1 ) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, ctrl, true);
Expand Down
2 changes: 1 addition & 1 deletion src/epdiy.h
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ enum EpdDrawError epd_draw_base(
* The positions corresponding to lines where `to` and `from` differ
* are set to `true`, otherwise to `false`.
* @param col_dirtyness: An array of at least `epd_width() / 2`.
* If a byte is set to non-zero, the pixel column is marked as changed, aka "dirty."
* If a nibble is set to non-zero, the pixel column is marked as changed, aka "dirty."
* The buffer must be 16 byte aligned.
* @returns The smallest rectangle containing all changed pixels.
*/
Expand Down
20 changes: 5 additions & 15 deletions src/highlevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,9 @@ enum EpdDrawError epd_hl_update_area(EpdiyHighlevelState* state, enum EpdDrawMod
area.width = rotated_area.width;
area.height = rotated_area.height;

uint8_t* col_dirtyness = heap_caps_aligned_alloc(16, epd_width(), MALLOC_CAP_INTERNAL);

uint32_t ts = esp_timer_get_time() / 1000;

ESP_LOGI("epdiy", "calculating diff..");
//FIXME: use crop information here, if available
// FIXME: use crop information here, if available
EpdRect diff_area = epd_difference_image_cropped(
state->front_fb,
state->back_fb,
Expand All @@ -126,9 +123,7 @@ enum EpdDrawError epd_hl_update_area(EpdiyHighlevelState* state, enum EpdDrawMod
state->dirty_lines,
state->dirty_columns
);

ESP_LOGI("epdiy", "highlevel diff area: x: %d, y: %d, w: %d, h: %d", diff_area.x, diff_area.y, diff_area.width, diff_area.height);


if (diff_area.height == 0 || diff_area.width == 0) {
return EPD_DRAW_SUCCESS;
}
Expand All @@ -140,13 +135,10 @@ enum EpdDrawError epd_hl_update_area(EpdiyHighlevelState* state, enum EpdDrawMod
diff_area.width = epd_width();
diff_area.height = epd_height();

enum EpdDrawError err;
enum EpdDrawError err = EPD_DRAW_SUCCESS;
err = epd_draw_base(epd_full_screen(), state->difference_fb, diff_area, MODE_PACKING_1PPB_DIFFERENCE | mode, temperature, state->dirty_lines, state->dirty_columns, state->waveform);

uint32_t t2 = esp_timer_get_time() / 1000;
printf("actual draw took %dms.\n", t2 - t1);

t1 = esp_timer_get_time() / 1000;

diff_area.x = 0;
diff_area.y = 0;
Expand Down Expand Up @@ -177,11 +169,9 @@ enum EpdDrawError epd_hl_update_area(EpdiyHighlevelState* state, enum EpdDrawMod
}
}

t2 = esp_timer_get_time() / 1000;
printf("buffer update took %dms.\n", t2 - t1);
uint32_t te = esp_timer_get_time() / 1000;
printf("full update took %dms.\n", te - ts);
uint32_t t3 = esp_timer_get_time() / 1000;

ESP_LOGI("epdiy", "diff: %dms, draw: %dms, buffer update: %dms, total: %dms", t1 - ts, t2 - t1, t3 - t2, t3 - ts);
return err;
}

Expand Down
13 changes: 1 addition & 12 deletions src/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,9 @@ enum EpdDrawError IRAM_ATTR epd_draw_base(
render_context.phase_times = waveform_phases->phase_times;
}

ESP_LOGI("epdiy", "starting update, phases: %d", frame_count);

#ifdef RENDER_METHOD_I2S
i2s_do_update(&render_context);
#elif defined(RENDER_METHOD_LCD)
// int line_start_x = area.x + (horizontally_cropped ? crop_to.x : 0);
// int line_end_x = line_start_x + (horizontally_cropped ? crop_to.width : area.width);
// line_start_x = min(max(line_start_x, 0), ctx->display_width);
// line_end_x = min(max(line_end_x, 0), ctx->display_width);

for (int i = 0; i < NUM_RENDER_THREADS; i++) {
LineQueue_t* queue = &render_context.line_queues[i];
Expand Down Expand Up @@ -415,14 +409,12 @@ EpdRect epd_difference_image_base(
assert((fb_width * fb_height) % 32 == 0);
assert(col_dirtyness != NULL);

memset(col_dirtyness, 0, fb_width);
memset(col_dirtyness, 0, fb_width / 2);
memset(dirty_lines, 0, sizeof(bool) * fb_height);

int x_end = min(fb_width, crop_to.x + crop_to.width);
int y_end = min(fb_height, crop_to.y + crop_to.height);

uint32_t t1 = esp_timer_get_time() / 1000;

for (int y = crop_to.y; y < y_end; y++) {
uint32_t offset = y * fb_width / 2;
int dirty = interlace_line(
Expand Down Expand Up @@ -451,9 +443,6 @@ EpdRect epd_difference_image_base(
break;
}

uint32_t t2 = esp_timer_get_time() / 1000;
printf("diff time: %dms.\n", t2 - t1);

EpdRect crop_rect = {
.x = min_x,
.y = min_y,
Expand Down

0 comments on commit 3c16dfd

Please sign in to comment.