diff --git a/static/extension_settings.js b/static/extension_settings.js index 5299f66d..4918cf72 100644 --- a/static/extension_settings.js +++ b/static/extension_settings.js @@ -143,17 +143,23 @@ } } - function safeRead(key){ + function safeReadState(key){ try{ const raw=window.localStorage.getItem(key); - if(!raw) return {}; + if(!raw) return {value:{},malformed:false}; const parsed=JSON.parse(raw); - return parsed&&typeof parsed==='object'&&!Array.isArray(parsed)?parsed:{}; + return parsed&&typeof parsed==='object'&&!Array.isArray(parsed) + ?{value:parsed,malformed:false} + :{value:{},malformed:true}; }catch(_e){ - return {}; + return {value:{},malformed:true}; } } + function safeRead(key){ + return safeReadState(key).value; + } + function safeWrite(key,value){ const keys=Object.keys(value||{}); try{ @@ -211,10 +217,10 @@ } function readSettingsState(schema,key){ - const stored=safeRead(key); - const checked=validate(schema,stored); + const stored=safeReadState(key); + const checked=validate(schema,stored.value); const overrides=overridesFromValues(schema,checked.values); - if(JSON.stringify(stored)!==JSON.stringify(overrides)) safeWrite(key,overrides); + if(stored.malformed||JSON.stringify(stored.value)!==JSON.stringify(overrides)) safeWrite(key,overrides); return {values:checked.values,overrides}; } diff --git a/tests/test_extension_settings_runtime.py b/tests/test_extension_settings_runtime.py index bae6086c..307da362 100644 --- a/tests/test_extension_settings_runtime.py +++ b/tests/test_extension_settings_runtime.py @@ -72,6 +72,14 @@ def test_extension_settings_runtime_normalizes_persists_resets_and_clears(): assert.deepStrictEqual(settings.values, {{flag: false, mode: 'compact', count: 2}}); assert.deepStrictEqual(settings.overrides, {{}}); assert.strictEqual(store.has('hermes.ext.settings.demo.ext'), false); + store.set('hermes.ext.settings.demo.ext', 'not-json'); + assert.deepStrictEqual(settings.values, {{flag: false, mode: 'compact', count: 2}}); + assert.deepStrictEqual(settings.overrides, {{}}); + assert.strictEqual(store.has('hermes.ext.settings.demo.ext'), false); + store.set('hermes.ext.settings.demo.ext', JSON.stringify(['bad'])); + assert.deepStrictEqual(settings.values, {{flag: false, mode: 'compact', count: 2}}); + assert.deepStrictEqual(settings.overrides, {{}}); + assert.strictEqual(store.has('hermes.ext.settings.demo.ext'), false); assert.strictEqual(settings.set('mode', 'invalid').ok, false); assert.deepStrictEqual(settings.reset(), {{flag: false, mode: 'compact', count: 2}}); assert.strictEqual(store.has('hermes.ext.settings.demo.ext'), false);