fix: Validate settings on read (#492)

Cherry-picked from upstream PR #492
Resolved conflict: kept custom values (ACTUAL, progress bar modes,
CUSTOM_FONT, DICTIONARY) while adding _COUNT validation
This commit is contained in:
cottongin 2026-01-27 07:41:07 -05:00
parent 03a18fb298
commit ff0392b9d2
No known key found for this signature in database
GPG Key ID: 0ECC91FE4655C262
2 changed files with 61 additions and 31 deletions

View File

@ -12,6 +12,14 @@
// Initialize the static instance
CrossPointSettings CrossPointSettings::instance;
void readAndValidate(FsFile& file, uint8_t& member, const uint8_t maxValue) {
uint8_t tempValue;
serialization::readPod(file, tempValue);
if (tempValue < maxValue) {
member = tempValue;
}
}
namespace {
constexpr uint8_t SETTINGS_FILE_VERSION = 1;
// Increment this when adding new persisted settings fields
@ -79,35 +87,35 @@ bool CrossPointSettings::loadFromFile() {
// load settings that exist (support older files with fewer fields)
uint8_t settingsRead = 0;
do {
serialization::readPod(inputFile, sleepScreen);
readAndValidate(inputFile, sleepScreen, SLEEP_SCREEN_MODE_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, extraParagraphSpacing);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, shortPwrBtn);
readAndValidate(inputFile, shortPwrBtn, SHORT_PWRBTN_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, statusBar);
readAndValidate(inputFile, statusBar, STATUS_BAR_MODE_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, orientation);
readAndValidate(inputFile, orientation, ORIENTATION_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, frontButtonLayout);
readAndValidate(inputFile, frontButtonLayout, FRONT_BUTTON_LAYOUT_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, sideButtonLayout);
readAndValidate(inputFile, sideButtonLayout, SIDE_BUTTON_LAYOUT_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, fontFamily);
readAndValidate(inputFile, fontFamily, FONT_FAMILY_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, fontSize);
readAndValidate(inputFile, fontSize, FONT_SIZE_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, lineSpacing);
readAndValidate(inputFile, lineSpacing, LINE_COMPRESSION_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, paragraphAlignment);
readAndValidate(inputFile, paragraphAlignment, PARAGRAPH_ALIGNMENT_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, sleepTimeout);
readAndValidate(inputFile, sleepTimeout, SLEEP_TIMEOUT_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, refreshFrequency);
readAndValidate(inputFile, refreshFrequency, REFRESH_FREQUENCY_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, screenMargin);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, sleepScreenCoverMode);
readAndValidate(inputFile, sleepScreenCoverMode, SLEEP_SCREEN_COVER_MODE_COUNT);
if (++settingsRead >= fileSettingsCount) break;
{
std::string urlStr;
@ -118,7 +126,7 @@ bool CrossPointSettings::loadFromFile() {
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, textAntiAliasing);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, hideBatteryPercentage);
readAndValidate(inputFile, hideBatteryPercentage, HIDE_BATTERY_PERCENTAGE_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, longPressChapterSkip);
if (++settingsRead >= fileSettingsCount) break;

View File

@ -16,17 +16,18 @@ class CrossPointSettings {
CrossPointSettings& operator=(const CrossPointSettings&) = delete;
// Should match with SettingsActivity text
enum SLEEP_SCREEN_MODE { DARK = 0, LIGHT = 1, CUSTOM = 2, COVER = 3, BLANK = 4 };
enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1, ACTUAL = 2 };
enum SLEEP_SCREEN_MODE { DARK = 0, LIGHT = 1, CUSTOM = 2, COVER = 3, BLANK = 4, SLEEP_SCREEN_MODE_COUNT };
enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1, ACTUAL = 2, SLEEP_SCREEN_COVER_MODE_COUNT };
// Status bar display type enum
enum STATUS_BAR_MODE { NONE = 0, NO_PROGRESS = 1, FULL = 2, FULL_WITH_PROGRESS_BAR = 3, ONLY_PROGRESS_BAR = 4 };
enum STATUS_BAR_MODE { NONE = 0, NO_PROGRESS = 1, FULL = 2, FULL_WITH_PROGRESS_BAR = 3, ONLY_PROGRESS_BAR = 4, STATUS_BAR_MODE_COUNT };
enum ORIENTATION {
PORTRAIT = 0, // 480x800 logical coordinates (current default)
LANDSCAPE_CW = 1, // 800x480 logical coordinates, rotated 180° (swap top/bottom)
INVERTED = 2, // 480x800 logical coordinates, inverted
LANDSCAPE_CCW = 3 // 800x480 logical coordinates, native panel orientation
PORTRAIT = 0, // 480x800 logical coordinates (current default)
LANDSCAPE_CW = 1, // 800x480 logical coordinates, rotated 180° (swap top/bottom)
INVERTED = 2, // 480x800 logical coordinates, inverted
LANDSCAPE_CCW = 3, // 800x480 logical coordinates, native panel orientation
ORIENTATION_COUNT
};
// Front button layout options
@ -36,32 +37,53 @@ class CrossPointSettings {
BACK_CONFIRM_LEFT_RIGHT = 0,
LEFT_RIGHT_BACK_CONFIRM = 1,
LEFT_BACK_CONFIRM_RIGHT = 2,
BACK_CONFIRM_RIGHT_LEFT = 3
BACK_CONFIRM_RIGHT_LEFT = 3,
FRONT_BUTTON_LAYOUT_COUNT
};
// Side button layout options
// Default: Previous, Next
// Swapped: Next, Previous
enum SIDE_BUTTON_LAYOUT { PREV_NEXT = 0, NEXT_PREV = 1 };
enum SIDE_BUTTON_LAYOUT { PREV_NEXT = 0, NEXT_PREV = 1, SIDE_BUTTON_LAYOUT_COUNT };
// Font family options
enum FONT_FAMILY { BOOKERLY = 0, NOTOSANS = 1, CUSTOM_FONT = 2 };
enum FONT_FAMILY { BOOKERLY = 0, NOTOSANS = 1, CUSTOM_FONT = 2, FONT_FAMILY_COUNT };
// Font size options
enum FONT_SIZE { SMALL = 0, MEDIUM = 1, LARGE = 2, EXTRA_LARGE = 3 };
enum LINE_COMPRESSION { TIGHT = 0, NORMAL = 1, WIDE = 2 };
enum PARAGRAPH_ALIGNMENT { JUSTIFIED = 0, LEFT_ALIGN = 1, CENTER_ALIGN = 2, RIGHT_ALIGN = 3 };
enum FONT_SIZE { SMALL = 0, MEDIUM = 1, LARGE = 2, EXTRA_LARGE = 3, FONT_SIZE_COUNT };
enum LINE_COMPRESSION { TIGHT = 0, NORMAL = 1, WIDE = 2, LINE_COMPRESSION_COUNT };
enum PARAGRAPH_ALIGNMENT {
JUSTIFIED = 0,
LEFT_ALIGN = 1,
CENTER_ALIGN = 2,
RIGHT_ALIGN = 3,
PARAGRAPH_ALIGNMENT_COUNT
};
// Auto-sleep timeout options (in minutes)
enum SLEEP_TIMEOUT { SLEEP_1_MIN = 0, SLEEP_5_MIN = 1, SLEEP_10_MIN = 2, SLEEP_15_MIN = 3, SLEEP_30_MIN = 4 };
enum SLEEP_TIMEOUT {
SLEEP_1_MIN = 0,
SLEEP_5_MIN = 1,
SLEEP_10_MIN = 2,
SLEEP_15_MIN = 3,
SLEEP_30_MIN = 4,
SLEEP_TIMEOUT_COUNT
};
// E-ink refresh frequency (pages between full refreshes)
enum REFRESH_FREQUENCY { REFRESH_1 = 0, REFRESH_5 = 1, REFRESH_10 = 2, REFRESH_15 = 3, REFRESH_30 = 4 };
enum REFRESH_FREQUENCY {
REFRESH_1 = 0,
REFRESH_5 = 1,
REFRESH_10 = 2,
REFRESH_15 = 3,
REFRESH_30 = 4,
REFRESH_FREQUENCY_COUNT
};
// Short power button press actions
enum SHORT_PWRBTN { IGNORE = 0, SLEEP = 1, PAGE_TURN = 2, DICTIONARY = 3 };
enum SHORT_PWRBTN { IGNORE = 0, SLEEP = 1, PAGE_TURN = 2, DICTIONARY = 3, SHORT_PWRBTN_COUNT };
// Hide battery percentage
enum HIDE_BATTERY_PERCENTAGE { HIDE_NEVER = 0, HIDE_READER = 1, HIDE_ALWAYS = 2 };
enum HIDE_BATTERY_PERCENTAGE { HIDE_NEVER = 0, HIDE_READER = 1, HIDE_ALWAYS = 2, HIDE_BATTERY_PERCENTAGE_COUNT };
// Sleep screen settings
uint8_t sleepScreen = DARK;