diff --git a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md index a1c53c01465..c450422c744 100644 --- a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.4.3 + +* Fixes issue where non-JSON formatted strings cause parsing errors. + ## 2.4.2 * Fixes `getStringList` returning immutable list. diff --git a/packages/shared_preferences/shared_preferences_web/example/integration_test/shared_preferences_web_test.dart b/packages/shared_preferences/shared_preferences_web/example/integration_test/shared_preferences_web_test.dart index 90ebbc5b899..c5313341e56 100644 --- a/packages/shared_preferences/shared_preferences_web/example/integration_test/shared_preferences_web_test.dart +++ b/packages/shared_preferences/shared_preferences_web/example/integration_test/shared_preferences_web_test.dart @@ -382,6 +382,24 @@ void main() { ); expect(values['Int'], writeCount); }); + + testWidgets('returns all valid JSON data', (WidgetTester _) async { + const String value = 'value'; + const String invalidJsonDataKey = 'invalidJsonData'; + const String validJsonDataKey = 'validJsonData'; + html.window.localStorage.setItem(invalidJsonDataKey, value); + html.window.localStorage.setItem(validJsonDataKey, '"$value"'); + + final Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + + expect(values.containsKey(invalidJsonDataKey), isFalse); + expect(values.containsKey(validJsonDataKey), isTrue); + expect(values[validJsonDataKey], equals(value)); + }); }); group('shared_preferences_async', () { @@ -454,6 +472,29 @@ void main() { expect(list?.length, testList.length + 1); }); + testWidgets( + 'returns null when reading invalid JSON value', + (WidgetTester _) async { + const String value = 'value'; + const String invalidJsonDataKey = 'invalidJsonData'; + const String validJsonDataKey = 'validJsonData'; + final SharedPreferencesAsyncPlatform preferences = + await getPreferences(); + + html.window.localStorage.setItem(invalidJsonDataKey, value); + html.window.localStorage.setItem(validJsonDataKey, '"$value"'); + + expect( + await preferences.getString(invalidJsonDataKey, emptyOptions), + isNull, + ); + expect( + await preferences.getString(validJsonDataKey, emptyOptions), + equals(value), + ); + }, + ); + testWidgets('getPreferences', (WidgetTester _) async { final SharedPreferencesAsyncPlatform preferences = await getPreferences(); await Future.wait(>[ diff --git a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart index 97160b5d150..0dfd1e9c9f9 100644 --- a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart +++ b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart @@ -73,7 +73,11 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform { final Map allData = {}; for (final String key in _getPrefixedKeys(filter.prefix, allowList: filter.allowList)) { - allData[key] = _decodeValue(html.window.localStorage.getItem(key)!); + final Object? value = + _decodeValue(html.window.localStorage.getItem(key)!); + if (value != null) { + allData[key] = value; + } } return allData; } @@ -132,7 +136,11 @@ base class SharedPreferencesAsyncWeb extends SharedPreferencesAsyncPlatform { ) async { final Map allData = {}; for (final String key in _getAllowedKeys(allowList: allowList)) { - allData[key] = _decodeValue(html.window.localStorage.getItem(key)!); + final Object? value = + _decodeValue(html.window.localStorage.getItem(key)!); + if (value != null) { + allData[key] = value; + } } return allData; } @@ -258,8 +266,13 @@ String _encodeValue(Object? value) { return json.encode(value); } -Object _decodeValue(String encodedValue) { - final Object? decodedValue = json.decode(encodedValue); +Object? _decodeValue(String encodedValue) { + final Object? decodedValue; + try { + decodedValue = json.decode(encodedValue); + } on FormatException catch (_) { + return null; + } if (decodedValue is List) { // JSON does not preserve generics. The encode/decode roundtrip is @@ -268,7 +281,7 @@ Object _decodeValue(String encodedValue) { return decodedValue.cast(); } - return decodedValue!; + return decodedValue; } /// Web specific SharedPreferences Options. diff --git a/packages/shared_preferences/shared_preferences_web/pubspec.yaml b/packages/shared_preferences/shared_preferences_web/pubspec.yaml index a8592342dc2..1b68fd54014 100644 --- a/packages/shared_preferences/shared_preferences_web/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_web/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences_web description: Web platform implementation of shared_preferences repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.4.2 +version: 2.4.3 environment: sdk: ^3.4.0