diff --git a/lib/src/utils.dart b/lib/src/utils.dart index bcbccf167c..0e5e93e181 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -12,8 +12,13 @@ void mergeAttributes(Map attributes, {@required Map into}) { assert(attributes != null && into != null); attributes.forEach((String name, dynamic value) { - final dynamic targetValue = into[name]; - if (value is Map && targetValue is Map) { + dynamic targetValue = into[name]; + if (value is Map) { + if (targetValue is! Map) { + // Let mergeAttributes make a deep copy, because assigning a reference + // of 'value' will expose 'value' to be mutated by further merges. + into[name] = targetValue = {}; + } mergeAttributes(value, into: targetValue); } else { into[name] = value; diff --git a/test/utils_test.dart b/test/utils_test.dart index 3ee15130dc..e86a57a2aa 100644 --- a/test/utils_test.dart +++ b/test/utils_test.dart @@ -35,6 +35,25 @@ void main() { }, }); }); + + test('does not allow overriding original maps', () { + final environment = { + 'extra': { + 'device': 'Pixel 2', + }, + }; + + final event = { + 'extra': { + 'widget': 'Scaffold', + }, + }; + + final target = {}; + mergeAttributes(environment, into: target); + mergeAttributes(event, into: target); + expect(environment['extra'], {'device': 'Pixel 2'}); + }); }); group('formatDateAsIso8601WithSecondPrecision', () {