mirror of
https://github.com/flipperdevices/flipperzero-firmware.git
synced 2025-12-12 04:41:26 +04:00
Gui text box: fix formatted string memory reservation (#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>
This commit is contained in:
@@ -4,6 +4,9 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define TEXT_BOX_MAX_SYMBOL_WIDTH (10)
|
||||||
|
#define TEXT_BOX_LINE_WIDTH (120)
|
||||||
|
|
||||||
struct TextBox {
|
struct TextBox {
|
||||||
View* view;
|
View* view;
|
||||||
|
|
||||||
@@ -78,13 +81,11 @@ static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) {
|
|||||||
const char* str = model->text;
|
const char* str = model->text;
|
||||||
size_t line_num = 0;
|
size_t line_num = 0;
|
||||||
|
|
||||||
const size_t text_width = 120;
|
|
||||||
|
|
||||||
while(str[i] != '\0') {
|
while(str[i] != '\0') {
|
||||||
char symb = str[i++];
|
char symb = str[i++];
|
||||||
if(symb != '\n') {
|
if(symb != '\n') {
|
||||||
size_t glyph_width = canvas_glyph_width(canvas, symb);
|
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_num++;
|
||||||
line_width = 0;
|
line_width = 0;
|
||||||
furi_string_push_back(model->text_formatted, '\n');
|
furi_string_push_back(model->text_formatted, '\n');
|
||||||
@@ -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) {
|
static void text_box_view_draw_callback(Canvas* canvas, void* _model) {
|
||||||
TextBoxModel* model = _model;
|
TextBoxModel* model = _model;
|
||||||
|
|
||||||
|
if(!model->text) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
if(model->font == TextBoxFontText) {
|
if(model->font == TextBoxFontText) {
|
||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
@@ -211,6 +216,7 @@ void text_box_reset(TextBox* text_box) {
|
|||||||
furi_string_set(model->text_formatted, "");
|
furi_string_set(model->text_formatted, "");
|
||||||
model->font = TextBoxFontText;
|
model->font = TextBoxFontText;
|
||||||
model->focus = TextBoxFocusStart;
|
model->focus = TextBoxFocusStart;
|
||||||
|
model->formatted = false;
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
@@ -218,6 +224,8 @@ void text_box_reset(TextBox* text_box) {
|
|||||||
void text_box_set_text(TextBox* text_box, const char* text) {
|
void text_box_set_text(TextBox* text_box, const char* text) {
|
||||||
furi_assert(text_box);
|
furi_assert(text_box);
|
||||||
furi_assert(text);
|
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(
|
with_view_model(
|
||||||
text_box->view,
|
text_box->view,
|
||||||
@@ -225,7 +233,7 @@ void text_box_set_text(TextBox* text_box, const char* text) {
|
|||||||
{
|
{
|
||||||
model->text = text;
|
model->text = text;
|
||||||
furi_string_reset(model->text_formatted);
|
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;
|
model->formatted = false;
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ void furi_string_reserve(FuriString* s, size_t alloc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_string_reset(FuriString* s) {
|
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) {
|
void furi_string_swap(FuriString* v1, FuriString* v2) {
|
||||||
|
|||||||
Reference in New Issue
Block a user