From 98fb3d65c9bf36765ee2063e6a7126bd0cd7f7f4 Mon Sep 17 00:00:00 2001 From: jpirnay Date: Sun, 8 Mar 2026 12:45:14 +0100 Subject: [PATCH] And even more... --- lib/Epub/Epub/parsers/ContentOpfParser.cpp | 10 ++++++---- src/RecentBooksStore.cpp | 19 +++++++++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/Epub/Epub/parsers/ContentOpfParser.cpp b/lib/Epub/Epub/parsers/ContentOpfParser.cpp index 8ff97d80..963d4fd0 100644 --- a/lib/Epub/Epub/parsers/ContentOpfParser.cpp +++ b/lib/Epub/Epub/parsers/ContentOpfParser.cpp @@ -260,9 +260,10 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name if (strcmp(metaName, "cover") == 0) { self->coverItemId = metaContent; } else if (strcmp(metaName, "calibre:series") == 0 && self->series.empty()) { - self->series = trim(std::string(metaContent)).substr(0, MAX_DESCRIPTION_LENGTH); + self->series = trim(std::string(metaContent, std::min(strlen(metaContent), size_t{MAX_DESCRIPTION_LENGTH}))); } else if (strcmp(metaName, "calibre:series_index") == 0 && self->seriesIndex.empty()) { - self->seriesIndex = trim(std::string(metaContent)).substr(0, MAX_DESCRIPTION_LENGTH); + self->seriesIndex = + trim(std::string(metaContent, std::min(strlen(metaContent), size_t{MAX_DESCRIPTION_LENGTH}))); } } @@ -273,7 +274,7 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name if (metaProperty) { if (strcmp(metaProperty, "belongs-to-collection") == 0 && self->series.empty()) { if (metaContent) { - self->series = trim(std::string(metaContent)).substr(0, MAX_DESCRIPTION_LENGTH); + self->series = trim(std::string(metaContent, std::min(strlen(metaContent), size_t{MAX_DESCRIPTION_LENGTH}))); } else { self->state = IN_BOOK_SERIES; return; @@ -281,7 +282,8 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name } if (strcmp(metaProperty, "group-position") == 0 && self->seriesIndex.empty()) { if (metaContent) { - self->seriesIndex = trim(std::string(metaContent)).substr(0, MAX_DESCRIPTION_LENGTH); + self->seriesIndex = + trim(std::string(metaContent, std::min(strlen(metaContent), size_t{MAX_DESCRIPTION_LENGTH}))); } else { self->state = IN_BOOK_SERIES_INDEX; return; diff --git a/src/RecentBooksStore.cpp b/src/RecentBooksStore.cpp index ff811cd8..5746cbe7 100644 --- a/src/RecentBooksStore.cpp +++ b/src/RecentBooksStore.cpp @@ -134,19 +134,26 @@ bool RecentBooksStore::loadFromBinaryFile() { // load book to get missing data RecentBook book = getDataFromBook(path); - if (book.title.empty() && book.author.empty() && version == 2) { - // Fall back to loading what we can from the store - std::string title, author; - if (!serialization::readString(inputFile, title) || !serialization::readString(inputFile, author)) { + if (version == 2) { + // v2 always stores title and author after path; consume them regardless + // of whether live metadata was found, to keep the stream aligned. + std::string storedTitle, storedAuthor; + if (!serialization::readString(inputFile, storedTitle) || !serialization::readString(inputFile, storedAuthor)) { LOG_ERR("RBS", "Corrupt recent.bin: string too long at entry %u", i); inputFile.close(); return false; } + // Prefer live metadata; fall back to stored when live is unavailable. + const std::string& title = !book.title.empty() ? book.title : storedTitle; + const std::string& author = !book.title.empty() ? book.author : storedAuthor; if (!title.empty()) { tmpRecentBooks.push_back({path, title, author, "", ""}); } - } else if (!book.title.empty()) { - tmpRecentBooks.push_back(book); + } else { + // v1: no stored title/author bytes + if (!book.title.empty()) { + tmpRecentBooks.push_back(book); + } } } recentBooks = std::move(tmpRecentBooks);