diff --git a/lib/KOReaderSync/ChapterXPathIndexer.h b/lib/KOReaderSync/ChapterXPathIndexer.h index 356815f2..246fdecd 100644 --- a/lib/KOReaderSync/ChapterXPathIndexer.h +++ b/lib/KOReaderSync/ChapterXPathIndexer.h @@ -55,9 +55,13 @@ class ChapterXPathIndexer { * Parse DocFragment index from KOReader-style path segment: * /body/DocFragment[N]/body/... * + * KOReader uses 1-based DocFragment indices; N is converted to the 0-based + * spine index stored in outSpineIndex (i.e. outSpineIndex = N - 1). + * * @param xpath KOReader XPath - * @param outSpineIndex Parsed DocFragment index (0-based) - * @return true when DocFragment[N] exists and N is valid integer >= 0 + * @param outSpineIndex 0-based spine index derived from DocFragment[N] + * @return true when DocFragment[N] exists and N is a valid integer >= 1 + * (converted to 0-based outSpineIndex); false otherwise */ static bool tryExtractSpineIndexFromXPath(const std::string& xpath, int& outSpineIndex); }; diff --git a/lib/KOReaderSync/ProgressMapper.cpp b/lib/KOReaderSync/ProgressMapper.cpp index b0199bf6..d62e0608 100644 --- a/lib/KOReaderSync/ProgressMapper.cpp +++ b/lib/KOReaderSync/ProgressMapper.cpp @@ -2,6 +2,7 @@ #include +#include #include #include "ChapterXPathIndexer.h" @@ -71,7 +72,12 @@ CrossPointPosition ProgressMapper::toCrossPoint(const std::shared_ptr& epu return result; } - const size_t targetBytes = static_cast(bookSize * koPos.percentage); + if (!std::isfinite(koPos.percentage)) { + return result; + } + + const float sanitizedPercentage = std::clamp(koPos.percentage, 0.0f, 1.0f); + const size_t targetBytes = static_cast(bookSize * sanitizedPercentage); bool spineFound = false; for (int i = 0; i < spineCount; i++) {