From ca89e41636188063d1dfc3abf4734a4e89a19e87 Mon Sep 17 00:00:00 2001 From: Uri Tauber <142022451+Uri-Tauber@users.noreply.github.com> Date: Thu, 19 Feb 2026 18:44:46 +0200 Subject: [PATCH] fix: Crash (Load access fault) when indexing chapters containing characters unsupported by bold/italic font variants (#997) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 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. --- lib/GfxRenderer/GfxRenderer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/GfxRenderer/GfxRenderer.cpp b/lib/GfxRenderer/GfxRenderer.cpp index 77dd810c..5126ed36 100644 --- a/lib/GfxRenderer/GfxRenderer.cpp +++ b/lib/GfxRenderer/GfxRenderer.cpp @@ -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(&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; }