fix: Crash (Load access fault) when indexing chapters containing characters unsupported by bold/italic font variants (#997)

## Summary

* **What is the goal of this PR?** 

I flashed the last revision before commit f1740dbe, and chapter indexing
worked without any crashes.
After applying f1740dbe, the same chapter consistently triggered a
device reboot during indexing.

The affected chapter contains inline equation images surrounded by
styled (bold/italic) text that includes special math/symbol characters.

## Additional Context

Prior to f1740dbe, both `getTextAdvanceX()` and `getSpaceWidth()` always
measured text using `EpdFontFamily::REGULAR`, regardless of the actual
style.

Commit f1740dbe improved correctness by passing the active style so
spacing is calculated using the actual bold/italic font variant.

However, bold and italic variants have narrower Unicode coverage than
the regular font. When a character exists in the regular font but not in
the selected styled variant, `pdFont::getGlyph()` returns `nullptr`.

The updated measurement functions did not check for this and immediately
dereferenced the pointer:

`width += font.getGlyph(cp, style)->advanceX;   // nullptr->advanceX`


Because `advanceX` is located at byte offset 2 within `EpdGlyph`,
dereferencing a null pointer caused the CPU to attempt a load from
address `0x00000002`, resulting in a RISC-V:
Load access fault
MCAUSE = 5
MTVAL = 2


## Fix

Added null-safety checks to both `getTextAdvanceX()` and
`getSpaceWidth()`, following the same pattern used in the rendering
path:

If the glyph is missing in the selected style → fall back to the
replacement glyph.

If the replacement glyph is also unavailable → treat the character as
zero-width.

This preserves the improved style-correct spacing while preventing
crashes.
No behavioral changes occur for characters that are supported by the
selected font variant.

---

### AI Usage

Did you use AI tools to help write this code? _**< YES >**_
I encounter this bug while testing 1.1.0 RC. 
I pasted the serial log to Claude, which identify the bug and fixed it.
I can confirm now the chapter in question is indexed and loaded
correctly.
This commit is contained in:
Uri Tauber
2026-02-19 18:44:46 +02:00
committed by GitHub
parent 103fac2ee1
commit ca89e41636

View File

@@ -744,7 +744,8 @@ int GfxRenderer::getSpaceWidth(const int fontId, const EpdFontFamily::Style styl
return 0;
}
return fontIt->second.getGlyph(' ', style)->advanceX;
const EpdGlyph* spaceGlyph = fontIt->second.getGlyph(' ', style);
return spaceGlyph ? spaceGlyph->advanceX : 0;
}
int GfxRenderer::getTextAdvanceX(const int fontId, const char* text, const EpdFontFamily::Style style) const {
@@ -758,7 +759,9 @@ int GfxRenderer::getTextAdvanceX(const int fontId, const char* text, const EpdFo
int width = 0;
const auto& font = fontIt->second;
while ((cp = utf8NextCodepoint(reinterpret_cast<const uint8_t**>(&text)))) {
width += font.getGlyph(cp, style)->advanceX;
const EpdGlyph* glyph = font.getGlyph(cp, style);
if (!glyph) glyph = font.getGlyph(REPLACEMENT_GLYPH, style);
if (glyph) width += glyph->advanceX;
}
return width;
}