From 73d1839ddddee63df97c3af1d012bb96b7c43bf3 Mon Sep 17 00:00:00 2001 From: IFAKA <99131130+IFAKA@users.noreply.github.com> Date: Sun, 21 Dec 2025 03:36:30 +0100 Subject: [PATCH] fix: add bounds checks to Epub getter functions (#82) ## Problem Three Epub getter functions can throw exceptions: - `getCumulativeSpineItemSize()`: No bounds check before `.at(spineIndex)` - `getSpineItem()`: If spine is empty and index invalid, `.at(0)` throws - `getTocItem()`: If toc is empty and index invalid, `.at(0)` throws ## Fix - Add bounds check to `getCumulativeSpineItemSize()`, return 0 on error - Add empty container checks to `getSpineItem()` and `getTocItem()` - Use static fallback objects for safe reference returns on empty containers Changed `lib/Epub/Epub.cpp`. ## Test - Defensive additions - follows existing bounds check patterns - No logic changes for valid inputs - Manual device testing appreciated --- lib/Epub/Epub.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/Epub/Epub.cpp b/lib/Epub/Epub.cpp index a3edac8..8d3e4ad 100644 --- a/lib/Epub/Epub.cpp +++ b/lib/Epub/Epub.cpp @@ -298,10 +298,21 @@ bool Epub::getItemSize(const std::string& itemHref, size_t* size) const { int Epub::getSpineItemsCount() const { return spine.size(); } -size_t Epub::getCumulativeSpineItemSize(const int spineIndex) const { return cumulativeSpineItemSize.at(spineIndex); } +size_t Epub::getCumulativeSpineItemSize(const int spineIndex) const { + if (spineIndex < 0 || spineIndex >= static_cast(cumulativeSpineItemSize.size())) { + Serial.printf("[%lu] [EBP] getCumulativeSpineItemSize index:%d is out of range\n", millis(), spineIndex); + return 0; + } + return cumulativeSpineItemSize.at(spineIndex); +} std::string& Epub::getSpineItem(const int spineIndex) { - if (spineIndex < 0 || spineIndex >= spine.size()) { + static std::string emptyString; + if (spine.empty()) { + Serial.printf("[%lu] [EBP] getSpineItem called but spine is empty\n", millis()); + return emptyString; + } + if (spineIndex < 0 || spineIndex >= static_cast(spine.size())) { Serial.printf("[%lu] [EBP] getSpineItem index:%d is out of range\n", millis(), spineIndex); return spine.at(0).second; } @@ -310,7 +321,12 @@ std::string& Epub::getSpineItem(const int spineIndex) { } EpubTocEntry& Epub::getTocItem(const int tocTndex) { - if (tocTndex < 0 || tocTndex >= toc.size()) { + static EpubTocEntry emptyEntry("", "", "", 0); + if (toc.empty()) { + Serial.printf("[%lu] [EBP] getTocItem called but toc is empty\n", millis()); + return emptyEntry; + } + if (tocTndex < 0 || tocTndex >= static_cast(toc.size())) { Serial.printf("[%lu] [EBP] getTocItem index:%d is out of range\n", millis(), tocTndex); return toc.at(0); }