fix: Skip large CSS files to prevent crashes (#952)
## Summary **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) * Fixes: https://github.com/crosspoint-reader/crosspoint-reader/issues/947 **What changes are included?** * Check to see if there's free heap memory before processing CSS (should we be doing this type of check or is it better to just crash if we exhaust the memory?) * Skip CSS files larger than 128kb ## Additional Context * I found that a copy of `Release it` contained a 250kb+ CSS file, from the homepage of the publisher. It has nothing to do with the epub, so we should just skip it * Major question: Are there better ways to detect CSS that doesn't belong in a book, or is this size-based approach valid? * Another question: Are there any epubs we know of that legitimately include >128kb CSS files? Code changes themselves created with an agent, all investigation and write-up done by human. If you (the maintainers) would prefer a different fix for this issue, let me know. --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**< YES >**_
This commit is contained in:
@@ -213,6 +213,12 @@ bool Epub::parseTocNavFile() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Epub::parseCssFiles() const {
|
void Epub::parseCssFiles() const {
|
||||||
|
// Maximum CSS file size we'll attempt to parse (uncompressed)
|
||||||
|
// Larger files risk memory exhaustion on ESP32
|
||||||
|
constexpr size_t MAX_CSS_FILE_SIZE = 128 * 1024; // 128KB
|
||||||
|
// Minimum heap required before attempting CSS parsing
|
||||||
|
constexpr size_t MIN_HEAP_FOR_CSS_PARSING = 64 * 1024; // 64KB
|
||||||
|
|
||||||
if (cssFiles.empty()) {
|
if (cssFiles.empty()) {
|
||||||
LOG_DBG("EBP", "No CSS files to parse, but CssParser created for inline styles");
|
LOG_DBG("EBP", "No CSS files to parse, but CssParser created for inline styles");
|
||||||
}
|
}
|
||||||
@@ -223,6 +229,24 @@ void Epub::parseCssFiles() const {
|
|||||||
for (const auto& cssPath : cssFiles) {
|
for (const auto& cssPath : cssFiles) {
|
||||||
LOG_DBG("EBP", "Parsing CSS file: %s", cssPath.c_str());
|
LOG_DBG("EBP", "Parsing CSS file: %s", cssPath.c_str());
|
||||||
|
|
||||||
|
// Check heap before parsing - CSS parsing allocates heavily
|
||||||
|
const uint32_t freeHeap = ESP.getFreeHeap();
|
||||||
|
if (freeHeap < MIN_HEAP_FOR_CSS_PARSING) {
|
||||||
|
LOG_ERR("EBP", "Insufficient heap for CSS parsing (%u bytes free, need %zu), skipping: %s", freeHeap,
|
||||||
|
MIN_HEAP_FOR_CSS_PARSING, cssPath.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check CSS file size before decompressing - skip files that are too large
|
||||||
|
size_t cssFileSize = 0;
|
||||||
|
if (getItemSize(cssPath, &cssFileSize)) {
|
||||||
|
if (cssFileSize > MAX_CSS_FILE_SIZE) {
|
||||||
|
LOG_ERR("EBP", "CSS file too large (%zu bytes > %zu max), skipping: %s", cssFileSize, MAX_CSS_FILE_SIZE,
|
||||||
|
cssPath.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Extract CSS file to temp location
|
// Extract CSS file to temp location
|
||||||
const auto tmpCssPath = getCachePath() + "/.tmp.css";
|
const auto tmpCssPath = getCachePath() + "/.tmp.css";
|
||||||
FsFile tempCssFile;
|
FsFile tempCssFile;
|
||||||
|
|||||||
Reference in New Issue
Block a user