ui: Manage menu_ with std::vector.
Prior to this CL, menu_ is allocated with a fixed length of text_rows_. However, because we support scrollable menu in wear_ui, there might be more menu entries than text_rows_, which would lead to out-of-bounds array access. This CL addresses the issue by switching to std::vector. Bug: 65416558 Test: Run 'View recovery logs' on angler. Test: Set large margin height that leaves text_rows less than 21. Then run 'View recovery logs' with 21 menu entries. Change-Id: I5d4e3a0a097039e1104eda7d494c6269053dc894
This commit is contained in:
parent
8c753f6253
commit
e15d7a5104
3 changed files with 15 additions and 17 deletions
|
@ -69,7 +69,7 @@ ScreenRecoveryUI::ScreenRecoveryUI()
|
||||||
text_top_(0),
|
text_top_(0),
|
||||||
show_text(false),
|
show_text(false),
|
||||||
show_text_ever(false),
|
show_text_ever(false),
|
||||||
menu_(nullptr),
|
menu_headers_(nullptr),
|
||||||
show_menu(false),
|
show_menu(false),
|
||||||
menu_items(0),
|
menu_items(0),
|
||||||
menu_sel(0),
|
menu_sel(0),
|
||||||
|
@ -356,10 +356,10 @@ void ScreenRecoveryUI::draw_screen_locked() {
|
||||||
DrawHighlightBar(0, y - 2, gr_fb_width(), char_height_ + 4);
|
DrawHighlightBar(0, y - 2, gr_fb_width(), char_height_ + 4);
|
||||||
// Bold white text for the selected item.
|
// Bold white text for the selected item.
|
||||||
SetColor(MENU_SEL_FG);
|
SetColor(MENU_SEL_FG);
|
||||||
y += DrawTextLine(x, y, menu_[i], true);
|
y += DrawTextLine(x, y, menu_[i].c_str(), true);
|
||||||
SetColor(MENU);
|
SetColor(MENU);
|
||||||
} else {
|
} else {
|
||||||
y += DrawTextLine(x, y, menu_[i], false);
|
y += DrawTextLine(x, y, menu_[i].c_str(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
y += DrawHorizontalRule(y);
|
y += DrawHorizontalRule(y);
|
||||||
|
@ -508,7 +508,6 @@ bool ScreenRecoveryUI::Init(const std::string& locale) {
|
||||||
|
|
||||||
text_ = Alloc2d(text_rows_, text_cols_ + 1);
|
text_ = Alloc2d(text_rows_, text_cols_ + 1);
|
||||||
file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1);
|
file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1);
|
||||||
menu_ = Alloc2d(text_rows_, text_cols_ + 1);
|
|
||||||
|
|
||||||
text_col_ = text_row_ = 0;
|
text_col_ = text_row_ = 0;
|
||||||
text_top_ = 1;
|
text_top_ = 1;
|
||||||
|
@ -771,12 +770,11 @@ void ScreenRecoveryUI::StartMenu(const char* const* headers, const char* const*
|
||||||
pthread_mutex_lock(&updateMutex);
|
pthread_mutex_lock(&updateMutex);
|
||||||
if (text_rows_ > 0 && text_cols_ > 0) {
|
if (text_rows_ > 0 && text_cols_ > 0) {
|
||||||
menu_headers_ = headers;
|
menu_headers_ = headers;
|
||||||
size_t i = 0;
|
menu_.clear();
|
||||||
for (; i < text_rows_ && items[i] != nullptr; ++i) {
|
for (size_t i = 0; i < text_rows_ && items[i] != nullptr; ++i) {
|
||||||
strncpy(menu_[i], items[i], text_cols_ - 1);
|
menu_.emplace_back(std::string(items[i], strnlen(items[i], text_cols_ - 1)));
|
||||||
menu_[i][text_cols_ - 1] = '\0';
|
|
||||||
}
|
}
|
||||||
menu_items = i;
|
menu_items = static_cast<int>(menu_.size());
|
||||||
show_menu = true;
|
show_menu = true;
|
||||||
menu_sel = initial_selection;
|
menu_sel = initial_selection;
|
||||||
update_screen_locked();
|
update_screen_locked();
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
|
||||||
|
@ -127,7 +128,7 @@ class ScreenRecoveryUI : public RecoveryUI {
|
||||||
bool show_text;
|
bool show_text;
|
||||||
bool show_text_ever; // has show_text ever been true?
|
bool show_text_ever; // has show_text ever been true?
|
||||||
|
|
||||||
char** menu_;
|
std::vector<std::string> menu_;
|
||||||
const char* const* menu_headers_;
|
const char* const* menu_headers_;
|
||||||
bool show_menu;
|
bool show_menu;
|
||||||
int menu_items, menu_sel;
|
int menu_items, menu_sel;
|
||||||
|
|
13
wear_ui.cpp
13
wear_ui.cpp
|
@ -127,11 +127,11 @@ void WearRecoveryUI::draw_screen_locked() {
|
||||||
// white text of selected item
|
// white text of selected item
|
||||||
SetColor(MENU_SEL_FG);
|
SetColor(MENU_SEL_FG);
|
||||||
if (menu_[i][0]) {
|
if (menu_[i][0]) {
|
||||||
gr_text(gr_sys_font(), x + 4, y, menu_[i], 1);
|
gr_text(gr_sys_font(), x + 4, y, menu_[i].c_str(), 1);
|
||||||
}
|
}
|
||||||
SetColor(MENU);
|
SetColor(MENU);
|
||||||
} else if (menu_[i][0]) {
|
} else if (menu_[i][0]) {
|
||||||
gr_text(gr_sys_font(), x + 4, y, menu_[i], 0);
|
gr_text(gr_sys_font(), x + 4, y, menu_[i].c_str(), 0);
|
||||||
}
|
}
|
||||||
y += char_height_ + 4;
|
y += char_height_ + 4;
|
||||||
}
|
}
|
||||||
|
@ -199,17 +199,16 @@ void WearRecoveryUI::StartMenu(const char* const* headers, const char* const* it
|
||||||
pthread_mutex_lock(&updateMutex);
|
pthread_mutex_lock(&updateMutex);
|
||||||
if (text_rows_ > 0 && text_cols_ > 0) {
|
if (text_rows_ > 0 && text_cols_ > 0) {
|
||||||
menu_headers_ = headers;
|
menu_headers_ = headers;
|
||||||
size_t i = 0;
|
menu_.clear();
|
||||||
// "i < text_rows_" is removed from the loop termination condition,
|
// "i < text_rows_" is removed from the loop termination condition,
|
||||||
// which is different from the one in ScreenRecoveryUI::StartMenu().
|
// which is different from the one in ScreenRecoveryUI::StartMenu().
|
||||||
// Because WearRecoveryUI supports scrollable menu, it's fine to have
|
// Because WearRecoveryUI supports scrollable menu, it's fine to have
|
||||||
// more entries than text_rows_. The menu may be truncated otherwise.
|
// more entries than text_rows_. The menu may be truncated otherwise.
|
||||||
// Bug: 23752519
|
// Bug: 23752519
|
||||||
for (; items[i] != nullptr; i++) {
|
for (size_t i = 0; items[i] != nullptr; i++) {
|
||||||
strncpy(menu_[i], items[i], text_cols_ - 1);
|
menu_.emplace_back(std::string(items[i], strnlen(items[i], text_cols_ - 1)));
|
||||||
menu_[i][text_cols_ - 1] = '\0';
|
|
||||||
}
|
}
|
||||||
menu_items = i;
|
menu_items = static_cast<int>(menu_.size());
|
||||||
show_menu = true;
|
show_menu = true;
|
||||||
menu_sel = initial_selection;
|
menu_sel = initial_selection;
|
||||||
menu_start = 0;
|
menu_start = 0;
|
||||||
|
|
Loading…
Reference in a new issue