From c1ffed4fc90df15d8aace772a630d40eeb99d76c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 16 Jul 2020 12:44:07 +0200 Subject: [PATCH] base: Sanitize the room id for the path of the state store. This closes: #71. --- matrix_sdk_base/src/state/json_store.rs | 50 ++++++++++++++++++------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/matrix_sdk_base/src/state/json_store.rs b/matrix_sdk_base/src/state/json_store.rs index f5074231..c33d2f02 100644 --- a/matrix_sdk_base/src/state/json_store.rs +++ b/matrix_sdk_base/src/state/json_store.rs @@ -39,6 +39,36 @@ impl JsonStore { user_path_set: AtomicBool::new(false), }) } + + /// Build a path for a file where the Room state to be stored in. + async fn build_room_path(&self, room_state: &str, room_id: &RoomId) -> PathBuf { + let mut path = self.path.read().await.clone(); + + path.push("rooms"); + path.push(room_state); + path.push(JsonStore::sanitize_room_id(room_id)); + path.set_extension("json"); + + path + } + + /// Build a path for the file where the Client state to be stored in. + async fn build_client_path(&self) -> PathBuf { + let mut path = self.path.read().await.clone(); + path.push("client"); + path.set_extension("json"); + + path + } + + /// Replace common characters that can't be used in a file name with an + /// underscore. + fn sanitize_room_id(room_id: &RoomId) -> String { + room_id.as_str().replace( + &['.', ':', '<', '>', '"', '/', '\\', '|', '?', '*'][..], + "_", + ) + } } impl fmt::Debug for JsonStore { @@ -57,8 +87,7 @@ impl StateStore for JsonStore { self.path.write().await.push(sess.user_id.localpart()) } - let mut path = self.path.read().await.clone(); - path.push("client.json"); + let path = self.build_client_path().await; let json = async_fs::read_to_string(path) .await @@ -114,8 +143,7 @@ impl StateStore for JsonStore { } async fn store_client_state(&self, state: ClientState) -> Result<()> { - let mut path = self.path.read().await.clone(); - path.push("client.json"); + let path = self.build_client_path().await; if !path.exists() { let mut dir = path.clone(); @@ -146,9 +174,7 @@ impl StateStore for JsonStore { self.path.write().await.push(room.own_user_id.localpart()) } - let mut path = self.path.read().await.clone(); - path.push("rooms"); - path.push(&format!("{}/{}.json", room_state, room.room_id)); + let path = self.build_room_path(room_state, &room.room_id).await; if !path.exists() { let mut dir = path.clone(); @@ -178,15 +204,13 @@ impl StateStore for JsonStore { return Err(Error::StateStore("path for JsonStore not set".into())); } - let mut to_del = self.path.read().await.clone(); - to_del.push("rooms"); - to_del.push(&format!("{}/{}.json", room_state, room_id)); + let path = self.build_room_path(room_state, room_id).await; - if !to_del.exists() { - return Err(Error::StateStore(format!("file {:?} not found", to_del))); + if !path.exists() { + return Err(Error::StateStore(format!("file {:?} not found", path))); } - tokio::fs::remove_file(to_del).await.map_err(Error::from) + tokio::fs::remove_file(path).await.map_err(Error::from) } }