What changed, and why it matters
This commit is a routine code cleanup that turns the screen drawing code into a generic interface so the same code can run on both the real device and a software simulator. It does not fix or introduce any security issue.
No security action required; treat as normal refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change abstracts OLED-specific functions behind function pointers passed to screen_init(). It replaces direct calls to UG_ClearBuffer() with a new screen_clear() wrapper, guards simulator-only code with #ifndef TESTING, and adds bounds checks for negative coordinates in sh1107_set_pixel() and ssd1312_set_pixel() after changing their parameters from uint16_t to int16_t. These are defensive correctness improvements, not vulnerability fixes.
Changed components
src/screen.csrc/screen.hsrc/ui/oled/oled.csrc/ui/oled/sh1107.csrc/ui/oled/ssd1312.ctest/unit-test/framework/mock_screen.cInspect captured patch +58 / −30
diff --git a/src/bootloader/startup.c b/src/bootloader/startup.c
index ea960b2..5295977 100644
--- a/src/bootloader/startup.c
+++ b/src/bootloader/startup.c
@@ -22,6 +22,7 @@
#include <rust/rust.h>
#include <screen.h>
#include <string.h>
+#include <ui/oled/oled.h>
#include <usb/class/hid/hww/hid_hww.h>
#include <usb/usb_processing.h>
@@ -82,7 +83,7 @@ int main(void)
bootloader_init();
platform_init();
__stack_chk_guard = rand_sync_read32(&RAND_0);
- screen_init();
+ screen_init(oled_set_pixel, oled_mirror, oled_clear_buffer);
#if defined(BOOTLOADER_DEVDEVICE) || PLATFORM_BITBOX02PLUS == 1
qtouch_init();
#endif
diff --git a/src/factorysetup.c b/src/factorysetup.c
index 8f99de6..2af7fed 100644
--- a/src/factorysetup.c
+++ b/src/factorysetup.c
@@ -33,6 +33,7 @@
#include "usb/usb_processing.h"
#include "utils_ringbuffer.h"
#include <secp256k1.h>
+#include <ui/oled/oled.h>
#include <wally_crypto.h>
@@ -581,7 +582,7 @@ int main(void)
system_init();
platform_init();
__stack_chk_guard = common_stack_chk_guard();
- screen_init();
+ screen_init(oled_set_pixel, oled_mirror, oled_clear_buffer);
screen_splash();
common_main();
diff --git a/src/firmware.c b/src/firmware.c
index ff0813d..6af86f8 100644
--- a/src/firmware.c
+++ b/src/firmware.c
@@ -27,6 +27,7 @@
#include "usb/usb_processing.h"
#include <hww.h>
#include <memory/memory_spi.h>
+#include <ui/oled/oled.h>
#if APP_U2F == 1
#include <u2f.h>
@@ -40,7 +41,7 @@ int main(void)
system_init();
platform_init();
__stack_chk_guard = common_stack_chk_guard();
- screen_init();
+ screen_init(oled_set_pixel, oled_mirror, oled_clear_buffer);
screen_splash();
qtouch_init();
common_main();
diff --git a/src/reset.c b/src/reset.c
index 4b222e2..f860fd4 100644
--- a/src/reset.c
+++ b/src/reset.c
@@ -22,6 +22,7 @@
#include "memory/smarteeprom.h"
#include "system.h"
#include "uart.h"
+#include <screen.h>
#ifndef TESTING
#include "securechip/securechip.h"
@@ -40,7 +41,7 @@ static void _show_reset_label(bool status)
{
const char* msg = "Device reset";
component_t* comp = status_create(msg, status, NULL, NULL);
- UG_ClearBuffer();
+ screen_clear();
comp->f->render(comp);
UG_SendBuffer();
comp->f->cleanup(comp);
diff --git a/src/screen.c b/src/screen.c
index 5ca2a8b..f0fbecd 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -14,7 +14,6 @@
#include "screen.h"
-#include <hal_delay.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
@@ -24,9 +23,16 @@
#include <ui/oled/oled.h>
#include <ui/ugui/ugui.h>
#include <util.h>
+#include <utils_assert.h>
+
+#ifndef TESTING
+#include <hal_delay.h>
+#endif
static UG_GUI guioled; // Global GUI structure for OLED screen
static bool screen_upside_down = false;
+static void (*_mirror_fn)(bool);
+static void (*_clear_fn)(void);
UG_COLOR screen_front_color = C_WHITE;
UG_COLOR screen_back_color = C_BLACK;
@@ -39,11 +45,13 @@ void screen_print_debug(const char* message, int duration)
{
char print[100];
snprintf(print, sizeof(print), "%s", message);
- UG_ClearBuffer();
+ screen_clear();
UG_FontSelect(&font_font_a_9X9);
UG_PutString(0, 0, print, false);
UG_SendBuffer();
+#ifndef TESTING
if (duration > 0) delay_ms(duration);
+#endif
}
void screen_sprintf_debug(int duration, const char* fmt, ...)
@@ -71,7 +79,7 @@ void screen_print_debug_hex(const uint8_t* bytes, size_t len, int duration)
// Careful, this function is used in both the bootloader and the firmware.
void screen_splash(void)
{
- UG_ClearBuffer();
+ screen_clear();
int height = IMAGE_DEFAULT_ARROW_HEIGHT;
int x = 0;
@@ -80,7 +88,7 @@ void screen_splash(void)
image_arrow(SCREEN_WIDTH - x - 2, y, height, ARROW_LEFT);
UG_SendBuffer();
- UG_ClearBuffer();
+ screen_clear();
}
void screen_rotate(void)
@@ -88,7 +96,8 @@ void screen_rotate(void)
screen_upside_down = !screen_upside_down;
top_slider = 1 - top_slider;
bottom_slider = 1 - bottom_slider;
- oled_mirror(screen_upside_down);
+ ASSERT(_mirror_fn);
+ _mirror_fn(screen_upside_down);
}
bool screen_is_upside_down(void)
@@ -96,12 +105,18 @@ bool screen_is_upside_down(void)
return screen_upside_down;
}
-void screen_init(void)
+void screen_init(
+ void (*pixel_fn)(UG_S16, UG_S16, UG_COLOR),
+ void (*mirror_fn)(bool),
+ void (*clear_fn)(void))
+{
+ _mirror_fn = mirror_fn;
+ _clear_fn = clear_fn;
+ UG_Init(&guioled, pixel_fn, &font_font_a_11X10, SCREEN_WIDTH, SCREEN_HEIGHT);
+}
+
+void screen_clear(void)
{
- UG_Init(
- &guioled,
- (void (*)(UG_S16, UG_S16, UG_COLOR))oled_set_pixel,
- &font_font_a_11X10,
- SCREEN_WIDTH,
- SCREEN_HEIGHT);
+ ASSERT(_clear_fn);
+ _clear_fn();
}
diff --git a/src/screen.h b/src/screen.h
index 836e160..a2f4388 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -34,7 +34,10 @@ extern slider_location_t bottom_slider;
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
-void screen_init(void);
+void screen_init(
+ void (*pixel_fn)(UG_S16, UG_S16, UG_COLOR),
+ void (*mirror_fn)(bool),
+ void (*clear_fn)(void));
void screen_print_debug(const char* message, int duration);
void screen_sprintf_debug(int duration, const char* fmt, ...) __attribute__((format(printf, 2, 0)));
void screen_print_debug_hex(const uint8_t* bytes, size_t len, int duration);
@@ -45,4 +48,6 @@ void screen_rotate(void);
bool screen_is_upside_down(void);
+void screen_clear(void);
+
#endif
diff --git a/src/ui/graphics/lock_animation.c b/src/ui/graphics/lock_animation.c
index fdadcd1..e7a1b96 100644
--- a/src/ui/graphics/lock_animation.c
+++ b/src/ui/graphics/lock_animation.c
@@ -165,7 +165,7 @@ static void _animation_timer_cb(const struct timer_task* const timer_task)
}
/* Draw the frame. */
- UG_ClearBuffer();
+ screen_clear();
position_t pos = {
.left = (SCREEN_WIDTH - LOCK_ANIMATION_FRAME_WIDTH) / 2,
.top = (SCREEN_HEIGHT - LOCK_ANIMATION_FRAME_HEIGHT) / 2};
diff --git a/src/ui/oled/oled.c b/src/ui/oled/oled.c
index 9fbf817..713547e 100644
--- a/src/ui/oled/oled.c
+++ b/src/ui/oled/oled.c
@@ -84,7 +84,7 @@ static volatile bool _enabled = false;
struct bb02_display {
void (*configure)(uint8_t*);
- void (*set_pixel)(uint16_t x, uint16_t y, uint8_t c);
+ void (*set_pixel)(int16_t x, int16_t y, uint8_t c);
void (*update)(void);
void (*off)(void);
void (*mirror)(bool);
@@ -146,7 +146,7 @@ void oled_mirror(bool mirror)
bb02_display.mirror(mirror);
}
-void oled_set_pixel(uint16_t x, uint16_t y, uint8_t c)
+void oled_set_pixel(int16_t x, int16_t y, uint8_t c)
{
bb02_display.set_pixel(x, y, c);
_frame_buffer_updated = true;
diff --git a/src/ui/oled/oled.h b/src/ui/oled/oled.h
index 43217c1..c73faed 100644
--- a/src/ui/oled/oled.h
+++ b/src/ui/oled/oled.h
@@ -94,7 +94,7 @@ void oled_off(void);
* Set a screen pixel. This fills the frame buffer
* prior to it being sent to the screen by oled_send_buffer().
*/
-void oled_set_pixel(uint16_t x, uint16_t y, uint8_t c);
+void oled_set_pixel(int16_t x, int16_t y, uint8_t c);
/**
* Set brightness (0x00..0xff).
diff --git a/src/ui/oled/sh1107.c b/src/ui/oled/sh1107.c
index de2da75..544e672 100644
--- a/src/ui/oled/sh1107.c
+++ b/src/ui/oled/sh1107.c
@@ -97,11 +97,11 @@ void sh1107_configure(uint8_t* buf)
}
/* pixels can be accessed via buf[y*16+x/8] >> x%8 */
-void sh1107_set_pixel(uint16_t x, uint16_t y, uint8_t c)
+void sh1107_set_pixel(int16_t x, int16_t y, uint8_t c)
{
uint32_t p;
- if (x > 127) return;
- if (y > 63) return;
+ if (x < 0 || x > 127) return;
+ if (y < 0 || y > 63) return;
p = y * 16;
p += x / 8;
if (c) {
diff --git a/src/ui/oled/sh1107.h b/src/ui/oled/sh1107.h
index df76f32..f6f0c42 100644
--- a/src/ui/oled/sh1107.h
+++ b/src/ui/oled/sh1107.h
@@ -24,7 +24,7 @@
*/
void sh1107_configure(uint8_t* buf);
-void sh1107_set_pixel(uint16_t x, uint16_t y, uint8_t c);
+void sh1107_set_pixel(int16_t x, int16_t y, uint8_t c);
void sh1107_update(void);
void sh1107_mirror(bool mirror);
void sh1107_off(void);
diff --git a/src/ui/oled/ssd1312.c b/src/ui/oled/ssd1312.c
index ea51755..3d11f3e 100644
--- a/src/ui/oled/ssd1312.c
+++ b/src/ui/oled/ssd1312.c
@@ -102,11 +102,11 @@ void ssd1312_configure(uint8_t* buf)
oled_writer_write_cmd(SSD1312_CMD_SET_DISPLAY_ON);
}
-void ssd1312_set_pixel(uint16_t x, uint16_t y, uint8_t c)
+void ssd1312_set_pixel(int16_t x, int16_t y, uint8_t c)
{
uint32_t p;
- if (x > 127) return;
- if (y > 63) return;
+ if (x < 0 || x > 127) return;
+ if (y < 0 || y > 63) return;
p = (y / 8) * 128;
p += x;
if (c) {
diff --git a/src/ui/oled/ssd1312.h b/src/ui/oled/ssd1312.h
index c5ae64a..2a0318e 100644
--- a/src/ui/oled/ssd1312.h
+++ b/src/ui/oled/ssd1312.h
@@ -23,7 +23,7 @@
*/
void ssd1312_configure(uint8_t* buf);
-void ssd1312_set_pixel(uint16_t x, uint16_t y, uint8_t c);
+void ssd1312_set_pixel(int16_t x, int16_t y, uint8_t c);
void ssd1312_update(void);
void ssd1312_mirror(bool mirror);
void ssd1312_off(void);
diff --git a/src/ui/screen_process.c b/src/ui/screen_process.c
index 74cec51..4320401 100644
--- a/src/ui/screen_process.c
+++ b/src/ui/screen_process.c
@@ -25,7 +25,7 @@ static uint8_t screen_frame_cnt = 0;
void ui_screen_render_component(component_t* component)
{
- UG_ClearBuffer();
+ screen_clear();
component->position.left = 0;
component->position.top = 0;
component->f->render(component);
@@ -91,12 +91,14 @@ void screen_process(void)
component_t* component = screen_process_get_top_component();
_screen_draw(component);
+#ifndef TESTING
/*
* If we have changed activity, the gestures
* detection must start over.
*/
bool screen_new = _screen_has_changed(component);
gestures_detect(screen_new, component->emit_without_release);
+#endif
ui_screen_stack_cleanup();
}
diff --git a/test/unit-test/framework/mock_screen.c b/test/unit-test/framework/mock_screen.c
index 7e0e8fa..45d81ca 100644
--- a/test/unit-test/framework/mock_screen.c
+++ b/test/unit-test/framework/mock_screen.c
@@ -42,3 +42,5 @@ bool screen_is_upside_down(void)
{
return false;
}
+
+void screen_clear(void) {}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.