diff --git a/lib/matrix_api_lite.dart b/lib/matrix_api_lite.dart
index d90c0a1b..f2ac3ec3 100644
--- a/lib/matrix_api_lite.dart
+++ b/lib/matrix_api_lite.dart
@@ -20,6 +20,7 @@ library matrix_api_lite;
export 'src/matrix_api.dart';
export 'src/utils/logs.dart';
+export 'src/utils/map_copy_extension.dart';
export 'src/utils/try_get_map_extension.dart';
export 'src/model/algorithm_types.dart';
export 'src/model/basic_event.dart';
diff --git a/lib/src/model/auth/authentication_password.dart b/lib/src/model/auth/authentication_password.dart
index fe28d1c8..6ae4df3f 100644
--- a/lib/src/model/auth/authentication_password.dart
+++ b/lib/src/model/auth/authentication_password.dart
@@ -17,6 +17,7 @@
*/
import 'authentication_user_identifier.dart';
+
import 'authentication_data.dart';
import 'authentication_identifier.dart';
import 'authentication_phone_identifier.dart';
diff --git a/lib/src/model/basic_event.dart b/lib/src/model/basic_event.dart
index 095b2b21..7a91f559 100644
--- a/lib/src/model/basic_event.dart
+++ b/lib/src/model/basic_event.dart
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+import '../utils/map_copy_extension.dart';
+
class BasicEvent {
String type;
Map content;
@@ -27,7 +29,7 @@ class BasicEvent {
BasicEvent.fromJson(Map json) {
type = json['type'];
- content = Map.from(json['content']);
+ content = (json['content'] as Map).copy();
}
Map toJson() {
final data = {};
diff --git a/lib/src/model/keys_query_response.dart b/lib/src/model/keys_query_response.dart
index b368b4f1..ed02e87d 100644
--- a/lib/src/model/keys_query_response.dart
+++ b/lib/src/model/keys_query_response.dart
@@ -17,6 +17,7 @@
*/
import 'matrix_keys.dart';
+import '../utils/map_copy_extension.dart';
class KeysQueryResponse {
Map failures;
@@ -26,9 +27,7 @@ class KeysQueryResponse {
Map userSigningKeys;
KeysQueryResponse.fromJson(Map json) {
- failures = json['failures'] != null
- ? Map.from(json['failures'])
- : null;
+ failures = (json['failures'] as Map)?.copy();
deviceKeys = json['device_keys'] != null
? (json['device_keys'] as Map).map(
(k, v) => MapEntry(
diff --git a/lib/src/model/matrix_event.dart b/lib/src/model/matrix_event.dart
index 2f5f35f0..83fe7596 100644
--- a/lib/src/model/matrix_event.dart
+++ b/lib/src/model/matrix_event.dart
@@ -17,6 +17,7 @@
*/
import 'stripped_state_event.dart';
+import '../utils/map_copy_extension.dart';
class MatrixEvent extends StrippedStateEvent {
String eventId;
@@ -38,12 +39,8 @@ class MatrixEvent extends StrippedStateEvent {
roomId = json['room_id'];
originServerTs =
DateTime.fromMillisecondsSinceEpoch(json['origin_server_ts']);
- unsigned = json['unsigned'] != null
- ? Map.from(json['unsigned'])
- : null;
- prevContent = json['prev_content'] != null
- ? Map.from(json['prev_content'])
- : null;
+ unsigned = (json['unsigned'] as Map)?.copy();
+ prevContent = (json['prev_content'] as Map)?.copy();
redacts = json['redacts'];
}
diff --git a/lib/src/model/matrix_keys.dart b/lib/src/model/matrix_keys.dart
index c0f00386..317ef390 100644
--- a/lib/src/model/matrix_keys.dart
+++ b/lib/src/model/matrix_keys.dart
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+import '../utils/map_copy_extension.dart';
+
class MatrixSignableKey {
String userId;
String identifier;
@@ -33,13 +35,12 @@ class MatrixSignableKey {
_json = json;
userId = json['user_id'];
keys = Map.from(json['keys']);
+ // we need to manually copy to ensure that our map is Map>
signatures = json['signatures'] is Map
? Map>.from((json['signatures'] as Map)
.map((k, v) => MapEntry(k, Map.from(v))))
: null;
- unsigned = json['unsigned'] is Map
- ? Map.from(json['unsigned'])
- : null;
+ unsigned = (json['unsigned'] as Map)?.copy();
}
Map toJson() {
diff --git a/lib/src/model/one_time_keys_claim_response.dart b/lib/src/model/one_time_keys_claim_response.dart
index 7834211c..7607892b 100644
--- a/lib/src/model/one_time_keys_claim_response.dart
+++ b/lib/src/model/one_time_keys_claim_response.dart
@@ -16,13 +16,17 @@
* along with this program. If not, see .
*/
+import '../utils/map_copy_extension.dart';
+
class OneTimeKeysClaimResponse {
Map failures;
Map> oneTimeKeys;
OneTimeKeysClaimResponse.fromJson(Map json) {
- failures = Map.from(json['failures'] ?? {});
- oneTimeKeys = Map>.from(json['one_time_keys']);
+ failures = (json['failures'] as Map)?.copy() ?? {};
+ // We still need a Map<...>.from(...) to ensure all second-level entries are also maps
+ oneTimeKeys = Map>.from(
+ (json['one_time_keys'] as Map).copy());
}
Map toJson() {
diff --git a/lib/src/model/room_keys_info.dart b/lib/src/model/room_keys_info.dart
index 2ac7ac3c..037b20e1 100644
--- a/lib/src/model/room_keys_info.dart
+++ b/lib/src/model/room_keys_info.dart
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import 'algorithm_types.dart';
+import '../../matrix_api_lite.dart';
enum RoomKeysAlgorithmType { v1Curve25519AesSha2 }
diff --git a/lib/src/model/server_capabilities.dart b/lib/src/model/server_capabilities.dart
index 0e449e9d..0ae7c1ee 100644
--- a/lib/src/model/server_capabilities.dart
+++ b/lib/src/model/server_capabilities.dart
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+import '../utils/map_copy_extension.dart';
+
enum RoomVersionStability { stable, unstable }
class ServerCapabilities {
@@ -30,7 +32,7 @@ class ServerCapabilities {
mRoomVersions = json['m.room_versions'] != null
? MRoomVersions.fromJson(json['m.room_versions'])
: null;
- customCapabilities = Map.from(json);
+ customCapabilities = json.copy();
customCapabilities.remove('m.change_password');
customCapabilities.remove('m.room_versions');
}
diff --git a/lib/src/model/third_party_identifier.dart b/lib/src/model/third_party_identifier.dart
index 14fe31d8..25d5b469 100644
--- a/lib/src/model/third_party_identifier.dart
+++ b/lib/src/model/third_party_identifier.dart
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import '../../matrix_api_lite.dart';
+import '../matrix_api.dart';
class ThirdPartyIdentifier {
ThirdPartyIdentifierMedium medium;
diff --git a/lib/src/model/third_party_location.dart b/lib/src/model/third_party_location.dart
index 68083805..39546099 100644
--- a/lib/src/model/third_party_location.dart
+++ b/lib/src/model/third_party_location.dart
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+import '../utils/map_copy_extension.dart';
+
class ThirdPartyLocation {
String alias;
String protocol;
@@ -24,7 +26,7 @@ class ThirdPartyLocation {
ThirdPartyLocation.fromJson(Map json) {
alias = json['alias'];
protocol = json['protocol'];
- fields = Map.from(json['fields']);
+ fields = (json['fields'] as Map).copy();
}
Map toJson() {
diff --git a/lib/src/model/third_party_user.dart b/lib/src/model/third_party_user.dart
index fd84f907..e19818e8 100644
--- a/lib/src/model/third_party_user.dart
+++ b/lib/src/model/third_party_user.dart
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+import '../utils/map_copy_extension.dart';
+
class ThirdPartyUser {
String userId;
String protocol;
@@ -24,7 +26,7 @@ class ThirdPartyUser {
ThirdPartyUser.fromJson(Map json) {
userId = json['userid'];
protocol = json['protocol'];
- fields = Map.from(json['fields']);
+ fields = (json['fields'] as Map).copy();
}
Map toJson() {
diff --git a/lib/src/utils/map_copy_extension.dart b/lib/src/utils/map_copy_extension.dart
new file mode 100644
index 00000000..84ddc272
--- /dev/null
+++ b/lib/src/utils/map_copy_extension.dart
@@ -0,0 +1,33 @@
+/*
+ * Famedly Matrix SDK
+ * Copyright (C) 2020 Famedly GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+extension MapCopyExtension on Map {
+ /// Deep-copies a given json map
+ Map copy() {
+ final copy = Map.from(this);
+ for (final entry in copy.entries) {
+ if (entry.value is Map) {
+ copy[entry.key] = (entry.value as Map).copy();
+ }
+ if (entry.value is List) {
+ copy[entry.key] = List.from(entry.value);
+ }
+ }
+ return copy;
+ }
+}