Fix blank reader from invalid custom themes

The AI4Paper plugin wrote a non-array value to the readerCustomThemes
synced setting, which broke attachment opening in the reader. Validate
the value where it's used.

https://forums.zotero.org/discussion/133694/
https://forums.zotero.org/discussion/134248/
This commit is contained in:
Dan Stillman 2026-09-15 22:11:52 -04:00
parent 896a3f829a
commit 2cc8bf8053
2 changed files with 33 additions and 2 deletions

View file

@ -46,6 +46,18 @@ const READ_ALOUD_VOICE_DEFAULTS_PATH = PathUtils.join(Zotero.Profile.dir, 'readA
// Whether the Read Aloud audio cache has been pruned of stale versions this session
let readAloudCachePruned = false;
/**
* Return the custom reader themes from the synced setting
*
* Plugins can write to the setting, and the reader fails to load if the value isn't an array.
*
* @return {Object[]}
*/
function getCustomThemes() {
let customThemes = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'readerCustomThemes');
return Array.isArray(customThemes) ? customThemes : [];
}
class ReaderInstance {
constructor(options) {
this.stateFileName = '.zotero-reader-state';
@ -251,7 +263,7 @@ class ReaderInstance {
ftl,
showAnnotations: true,
textSelectionAnnotationMode: Zotero.Prefs.get('reader.textSelectionAnnotationMode'),
customThemes: Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'readerCustomThemes') ?? [],
customThemes: getCustomThemes(),
lightTheme: Zotero.Prefs.get('reader.lightTheme'),
darkTheme: Zotero.Prefs.get('reader.darkTheme'),
fontFamily: Zotero.Prefs.get('reader.ebookFontFamily'),
@ -2868,7 +2880,7 @@ class Reader {
else if (type === 'setting') {
let id = ids[0];
if (id === `${Zotero.Libraries.userLibraryID}/readerCustomThemes`) {
let newCustomThemes = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'readerCustomThemes') ?? [];
let newCustomThemes = getCustomThemes();
this._readers.forEach((reader) => {
reader._internalReader.setCustomThemes(
Components.utils.cloneInto(newCustomThemes, reader._iframeWindow)

View file

@ -352,6 +352,25 @@ describe("Reader", function () {
}
});
it('should open with an invalid custom themes setting', async function () {
var attachment = await importFileAttachment('test.pdf');
// Plugins can write anything to a synced setting
await Zotero.SyncedSettings.set(
Zotero.Libraries.userLibraryID,
'readerCustomThemes',
{ 0: { id: 'custom1', label: 'Custom', background: '#FFFFFF', foreground: '#000000' } }
);
try {
var reader = await Zotero.Reader.open(attachment.itemID);
await reader._initPromise;
assert.ok(reader._internalReader);
}
finally {
await Zotero.SyncedSettings.clear(Zotero.Libraries.userLibraryID, 'readerCustomThemes');
}
});
describe("#importFromEPUB()", function () {
let bookEpubPath; // The EPUB itself
let bookSdrPath; // The KOReader "sidecar" folder