fix(promicro): exclude emoji to fit under the warm-store region (#11256)
nrf52_promicro_diy_tcxo has been failing the nrf52 warm-region guard on develop: the image ends at 0xEA0C0, 192 bytes past the 12 KB WarmNodeStore record-ring reserved at 0xEA000. This variant compiles four radio driver families (SX126x/LLCC68, SX127x/RF95, LR11x0/LR1121, LR2021) so any module can be soldered on, which makes it the largest nrf52 image we ship. Building it with -D EXCLUDE_EMOJI saves 6,808 bytes and puts the image at 0xE8618, 6.6 KB clear of the warm region. EXCLUDE_EMOJI was not previously usable: graphics::emotes[] becomes empty, but the canned-message emote picker never checked for that. Entering the picker clamped emotePickerIndex to numEmotes - 1 (i.e. -1), and selecting read emotes[-1].label into a String - an out-of-bounds read of whatever precedes the array in flash. Guard both entry points instead: refuse to open the picker when there are no emotes, and bounce back to freetext if the picker state is somehow reached anyway. Under whole-image LTO those guards fold to constants, so the picker draw and input paths dead-strip entirely on builds that set EXCLUDE_EMOJI - which is where the savings come from beyond the bitmap data itself. Received messages containing emoji render as text on this variant, and the emote-list key is a no-op. Verified rak4631 (emoji enabled) is unaffected: 0xE46D8, 22 KB clear.
This commit is contained in:
@@ -880,8 +880,10 @@ bool CannedMessageModule::handleFreeTextInput(const InputEvent *event)
|
|||||||
// All hardware keys fall through to here (CardKB, physical, etc.)
|
// All hardware keys fall through to here (CardKB, physical, etc.)
|
||||||
|
|
||||||
if (event->kbchar == INPUT_BROKER_MSG_EMOTE_LIST) {
|
if (event->kbchar == INPUT_BROKER_MSG_EMOTE_LIST) {
|
||||||
updateState(CANNED_MESSAGE_RUN_STATE_EMOTE_PICKER);
|
if (graphics::numEmotes > 0) { // no picker on EXCLUDE_EMOJI builds (empty emotes[])
|
||||||
screen->forceDisplay();
|
updateState(CANNED_MESSAGE_RUN_STATE_EMOTE_PICKER);
|
||||||
|
screen->forceDisplay();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Confirm select (Enter)
|
// Confirm select (Enter)
|
||||||
@@ -965,6 +967,11 @@ bool CannedMessageModule::handleFreeTextInput(const InputEvent *event)
|
|||||||
int CannedMessageModule::handleEmotePickerInput(const InputEvent *event)
|
int CannedMessageModule::handleEmotePickerInput(const InputEvent *event)
|
||||||
{
|
{
|
||||||
int numEmotes = graphics::numEmotes;
|
int numEmotes = graphics::numEmotes;
|
||||||
|
if (numEmotes == 0) { // EXCLUDE_EMOJI: emotes[] is empty, any index would read out of bounds
|
||||||
|
updateState(CANNED_MESSAGE_RUN_STATE_FREETEXT, true);
|
||||||
|
screen->forceDisplay();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Override isDown and isSelect ONLY for emote picker behavior
|
// Override isDown and isSelect ONLY for emote picker behavior
|
||||||
bool isUp = isUpEvent(event);
|
bool isUp = isUpEvent(event);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ board = promicro-nrf52840
|
|||||||
build_flags = ${nrf52840_base.build_flags}
|
build_flags = ${nrf52840_base.build_flags}
|
||||||
-I variants/nrf52840/diy/nrf52_promicro_diy_tcxo
|
-I variants/nrf52840/diy/nrf52_promicro_diy_tcxo
|
||||||
-D NRF52_PROMICRO_DIY
|
-D NRF52_PROMICRO_DIY
|
||||||
|
-D EXCLUDE_EMOJI ; this variant builds 4 radio driver families and is the largest nrf52 image; emote bitmaps don't fit under the 0xEA000 warm-store cap
|
||||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/diy/nrf52_promicro_diy_tcxo>
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/diy/nrf52_promicro_diy_tcxo>
|
||||||
debug_tool = jlink
|
debug_tool = jlink
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user