Skip to content

Commit

Permalink
Gui text box: fix formatted string memory reservation (flipperdevices…
Browse files Browse the repository at this point in the history
…#3447)

* text box: reserve correct memory size to avoid reallocation
* Furi: change string reset behavior to release memory, prevent realloc call. Gui: fix NULL-ptr dereference in TextBox.

Co-authored-by: あく <alleteam@gmail.com>
  • Loading branch information
gornekich and skotopes authored Feb 14, 2024
1 parent 3c77dc7 commit a46038a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
16 changes: 12 additions & 4 deletions applications/services/gui/modules/text_box.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include <furi.h>
#include <stdint.h>

#define TEXT_BOX_MAX_SYMBOL_WIDTH (10)
#define TEXT_BOX_LINE_WIDTH (120)

struct TextBox {
View* view;

Expand Down Expand Up @@ -78,13 +81,11 @@ static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) {
const char* str = model->text;
size_t line_num = 0;

const size_t text_width = 120;

while(str[i] != '\0') {
char symb = str[i++];
if(symb != '\n') {
size_t glyph_width = canvas_glyph_width(canvas, symb);
if(line_width + glyph_width > text_width) {
if(line_width + glyph_width > TEXT_BOX_LINE_WIDTH) {
line_num++;
line_width = 0;
furi_string_push_back(model->text_formatted, '\n');
Expand Down Expand Up @@ -116,6 +117,10 @@ static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) {
static void text_box_view_draw_callback(Canvas* canvas, void* _model) {
TextBoxModel* model = _model;

if(!model->text) {
return;
}

canvas_clear(canvas);
if(model->font == TextBoxFontText) {
canvas_set_font(canvas, FontSecondary);
Expand Down Expand Up @@ -211,21 +216,24 @@ void text_box_reset(TextBox* text_box) {
furi_string_set(model->text_formatted, "");
model->font = TextBoxFontText;
model->focus = TextBoxFocusStart;
model->formatted = false;
},
true);
}

void text_box_set_text(TextBox* text_box, const char* text) {
furi_assert(text_box);
furi_assert(text);
size_t str_length = strlen(text);
size_t formating_margin = str_length * TEXT_BOX_MAX_SYMBOL_WIDTH / TEXT_BOX_LINE_WIDTH;

with_view_model(
text_box->view,
TextBoxModel * model,
{
model->text = text;
furi_string_reset(model->text_formatted);
furi_string_reserve(model->text_formatted, strlen(text));
furi_string_reserve(model->text_formatted, str_length + formating_margin);
model->formatted = false;
},
true);
Expand Down
3 changes: 2 additions & 1 deletion furi/core/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ void furi_string_reserve(FuriString* s, size_t alloc) {
}

void furi_string_reset(FuriString* s) {
string_reset(s->string);
string_clear(s->string);
string_init(s->string);
}

void furi_string_swap(FuriString* v1, FuriString* v2) {
Expand Down

0 comments on commit a46038a

Please sign in to comment.