fix(qrcode): fix crash due to buf_unalign modification (#4987)

Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
Neo Xu
2023-12-12 16:12:17 +08:00
committed by GitHub
parent 2b53325f49
commit f1e021e7b3
3 changed files with 66 additions and 6 deletions
+7 -6
View File
@@ -63,11 +63,12 @@ void lv_qrcode_set_size(lv_obj_t * obj, int32_t size)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_image_dsc_t * img_dsc = lv_canvas_get_image(obj);
void * buf = (void *)img_dsc->data;
void * buf = (void *)lv_canvas_get_buf(obj);
if(buf) lv_draw_buf_free(buf);
uint32_t buf_size = LV_CANVAS_BUF_SIZE(size, size, 1, LV_DRAW_BUF_STRIDE_ALIGN);
buf = lv_realloc(buf, buf_size);
size_t buf_size = lv_draw_buf_width_to_stride(size, LV_COLOR_FORMAT_I1) * size;
buf_size += 8; /*palette*/
buf = lv_draw_buf_malloc(buf_size, LV_COLOR_FORMAT_I1);
LV_ASSERT_MALLOC(buf);
if(buf == NULL) {
LV_LOG_ERROR("malloc failed for canvas buffer");
@@ -155,7 +156,7 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le
/* Copy the qr code canvas:
* A simple `lv_canvas_set_px` would work but it's slow for so many pixels.
* So buffer 1 byte (8 px) from the qr code and set it in the canvas image */
uint32_t row_byte_cnt = (img_dsc->header.w + 7) >> 3;
uint32_t row_byte_cnt = img_dsc->header.stride;
int y;
for(y = margin; y < scaled + margin; y += scale) {
uint8_t b = 0;
@@ -234,7 +235,7 @@ static void lv_qrcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
return;
}
lv_free((void *)lv_canvas_get_image(obj));
lv_draw_buf_free((void *)lv_canvas_get_buf(obj));
img_dsc->data = NULL;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

+59
View File
@@ -0,0 +1,59 @@
#if LV_BUILD_TEST
#include "../lvgl.h"
#include "unity/unity.h"
#if LV_USE_QRCODE
static lv_obj_t * active_screen = NULL;
void setUp(void)
{
active_screen = lv_screen_active();
}
void tearDown(void)
{
lv_obj_clean(active_screen);
}
void test_barcode_normal(void)
{
lv_color_t bg_color = lv_palette_lighten(LV_PALETTE_LIGHT_BLUE, 5);
lv_color_t fg_color = lv_palette_darken(LV_PALETTE_BLUE, 4);
lv_obj_t * qr = lv_qrcode_create(active_screen);
TEST_ASSERT_NOT_NULL(qr);
lv_qrcode_set_size(qr, 150);
lv_qrcode_set_dark_color(qr, fg_color);
lv_qrcode_set_light_color(qr, bg_color);
/*Set data*/
const char * data = "https://lvgl.io";
lv_result_t res = lv_qrcode_update(qr, data, strlen(data));
TEST_ASSERT_EQUAL(res, LV_RESULT_OK);
lv_obj_center(qr);
/*Add a border with bg_color*/
lv_obj_set_style_border_color(qr, bg_color, 0);
lv_obj_set_style_border_width(qr, 5, 0);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/qrcode_1.png");
}
#else
void setUp(void)
{
}
void tearDown(void)
{
}
void test_barcode_normal(void)
{
}
#endif
#endif