Skip to content

Commit cb4fb13

Browse files
authored
[shared_preferences] Fix JSON parsing issue with _decodeValue (#8211)
[shared_preferences] Fix JSON parsing issue with getAllWithParameters this is a restored PR #5813 Fixes flutter/flutter#156574 https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changelog-style
1 parent 89f6e93 commit cb4fb13

File tree

4 files changed

+64
-6
lines changed

4 files changed

+64
-6
lines changed

packages/shared_preferences/shared_preferences_web/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.4.3
2+
3+
* Fixes issue where non-JSON formatted strings cause parsing errors.
4+
15
## 2.4.2
26

37
* Fixes `getStringList` returning immutable list.

packages/shared_preferences/shared_preferences_web/example/integration_test/shared_preferences_web_test.dart

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,24 @@ void main() {
382382
);
383383
expect(values['Int'], writeCount);
384384
});
385+
386+
testWidgets('returns all valid JSON data', (WidgetTester _) async {
387+
const String value = 'value';
388+
const String invalidJsonDataKey = 'invalidJsonData';
389+
const String validJsonDataKey = 'validJsonData';
390+
html.window.localStorage.setItem(invalidJsonDataKey, value);
391+
html.window.localStorage.setItem(validJsonDataKey, '"$value"');
392+
393+
final Map<String, Object> values = await preferences.getAllWithParameters(
394+
GetAllParameters(
395+
filter: PreferencesFilter(prefix: ''),
396+
),
397+
);
398+
399+
expect(values.containsKey(invalidJsonDataKey), isFalse);
400+
expect(values.containsKey(validJsonDataKey), isTrue);
401+
expect(values[validJsonDataKey], equals(value));
402+
});
385403
});
386404

387405
group('shared_preferences_async', () {
@@ -454,6 +472,29 @@ void main() {
454472
expect(list?.length, testList.length + 1);
455473
});
456474

475+
testWidgets(
476+
'returns null when reading invalid JSON value',
477+
(WidgetTester _) async {
478+
const String value = 'value';
479+
const String invalidJsonDataKey = 'invalidJsonData';
480+
const String validJsonDataKey = 'validJsonData';
481+
final SharedPreferencesAsyncPlatform preferences =
482+
await getPreferences();
483+
484+
html.window.localStorage.setItem(invalidJsonDataKey, value);
485+
html.window.localStorage.setItem(validJsonDataKey, '"$value"');
486+
487+
expect(
488+
await preferences.getString(invalidJsonDataKey, emptyOptions),
489+
isNull,
490+
);
491+
expect(
492+
await preferences.getString(validJsonDataKey, emptyOptions),
493+
equals(value),
494+
);
495+
},
496+
);
497+
457498
testWidgets('getPreferences', (WidgetTester _) async {
458499
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
459500
await Future.wait(<Future<void>>[

packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform {
7373
final Map<String, Object> allData = <String, Object>{};
7474
for (final String key
7575
in _getPrefixedKeys(filter.prefix, allowList: filter.allowList)) {
76-
allData[key] = _decodeValue(html.window.localStorage.getItem(key)!);
76+
final Object? value =
77+
_decodeValue(html.window.localStorage.getItem(key)!);
78+
if (value != null) {
79+
allData[key] = value;
80+
}
7781
}
7882
return allData;
7983
}
@@ -132,7 +136,11 @@ base class SharedPreferencesAsyncWeb extends SharedPreferencesAsyncPlatform {
132136
) async {
133137
final Map<String, Object> allData = <String, Object>{};
134138
for (final String key in _getAllowedKeys(allowList: allowList)) {
135-
allData[key] = _decodeValue(html.window.localStorage.getItem(key)!);
139+
final Object? value =
140+
_decodeValue(html.window.localStorage.getItem(key)!);
141+
if (value != null) {
142+
allData[key] = value;
143+
}
136144
}
137145
return allData;
138146
}
@@ -258,8 +266,13 @@ String _encodeValue(Object? value) {
258266
return json.encode(value);
259267
}
260268

261-
Object _decodeValue(String encodedValue) {
262-
final Object? decodedValue = json.decode(encodedValue);
269+
Object? _decodeValue(String encodedValue) {
270+
final Object? decodedValue;
271+
try {
272+
decodedValue = json.decode(encodedValue);
273+
} on FormatException catch (_) {
274+
return null;
275+
}
263276

264277
if (decodedValue is List) {
265278
// JSON does not preserve generics. The encode/decode roundtrip is
@@ -268,7 +281,7 @@ Object _decodeValue(String encodedValue) {
268281
return decodedValue.cast<String>();
269282
}
270283

271-
return decodedValue!;
284+
return decodedValue;
272285
}
273286

274287
/// Web specific SharedPreferences Options.

packages/shared_preferences/shared_preferences_web/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: shared_preferences_web
22
description: Web platform implementation of shared_preferences
33
repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_web
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
5-
version: 2.4.2
5+
version: 2.4.3
66

77
environment:
88
sdk: ^3.4.0

0 commit comments

Comments
 (0)