From 42f9ef00b9e47cb828a910640e6aaf3dda2b1b27 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Mon, 10 Jan 2022 12:42:23 +0100 Subject: [PATCH] wrap update-item-array into an update-object on the wire; this allows to add other members in the future. the updates the peers see is not changed --- src/mimefactory.rs | 6 +++-- src/webxdc.rs | 59 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/mimefactory.rs b/src/mimefactory.rs index ec32446e1..14ffdf497 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -1163,8 +1163,10 @@ impl<'a> MimeFactory<'a> { let json = self.msg.param.get(Param::Arg).unwrap_or_default(); parts.push(context.build_status_update_part(json).await); } else if self.msg.viewtype == Viewtype::Webxdc { - let json = context.get_webxdc_status_updates(self.msg.id, None).await?; - if json != "[]" { + let json = context + .render_webxdc_status_update_object(self.msg.id, None) + .await?; + if json != r#"{{"updates":[]}}"# { parts.push(context.build_status_update_part(&json).await); } } diff --git a/src/webxdc.rs b/src/webxdc.rs index bd7b0b623..c81ace9fe 100644 --- a/src/webxdc.rs +++ b/src/webxdc.rs @@ -61,6 +61,12 @@ impl rusqlite::types::ToSql for StatusUpdateId { } } +// Array of update items as sent on the wire. +#[derive(Debug, Deserialize)] +struct StatusUpdates { + updates: Vec, +} + /// Update items as sent on the wire and as stored in the database. #[derive(Debug, Serialize, Deserialize)] pub(crate) struct StatusUpdateItem { @@ -147,8 +153,11 @@ impl Context { .set_cmd(SystemMessage::WebxdcStatusUpdate); status_update.param.set( Param::Arg, - self.get_webxdc_status_updates(instance_msg_id, Some(status_update_id)) - .await?, + self.render_webxdc_status_update_object( + instance_msg_id, + Some(status_update_id), + ) + .await?, ); status_update.set_quote(self, Some(&instance)).await?; let status_update_msg_id = @@ -190,8 +199,8 @@ impl Context { bail!("receive_status_update: status message has no parent.") }; - let update_items: Vec = serde_json::from_str(json)?; - for update_item in update_items { + let updates: StatusUpdates = serde_json::from_str(json)?; + for update_item in updates.updates { let status_update_id = self .create_status_update_record( instance.id, @@ -242,6 +251,18 @@ impl Context { .await?; Ok(format!("[{}]", json)) } + + /// Render JSON-object for status updates as used on the wire. + pub(crate) async fn render_webxdc_status_update_object( + &self, + instance_msg_id: MsgId, + status_update_id: Option, + ) -> Result { + let updates_array = self + .get_webxdc_status_updates(instance_msg_id, status_update_id) + .await?; + Ok(format!(r#"{{"updates":{}}}"#, updates_array)) + } } async fn parse_webxdc_manifest(bytes: &[u8]) -> Result { @@ -548,23 +569,30 @@ mod tests { .await .is_err()); // no json assert!(t - .receive_status_update(instance.id, r#"[{"foo":"bar"}]"#) + .receive_status_update(instance.id, r#"{"updada":[{"payload":{"foo":"bar"}}]}"#) + .await + .is_err()); // "updates" object missing + assert!(t + .receive_status_update(instance.id, r#"{"updates":[{"foo":"bar"}]}"#) .await .is_err()); // "payload" field missing assert!(t - .receive_status_update(instance.id, r#"{"payload":{"foo":"bar"}}"#) + .receive_status_update(instance.id, r#"{"updates":{"payload":{"foo":"bar"}}}"#) .await .is_err()); // not an array - t.receive_status_update(instance.id, r#"[{"payload":{"foo":"bar"}}]"#) + t.receive_status_update(instance.id, r#"{"updates":[{"payload":{"foo":"bar"}}]}"#) .await?; assert_eq!( t.get_webxdc_status_updates(instance.id, None).await?, r#"[{"payload":{"foo":"bar"}}]"# ); - t.receive_status_update(instance.id, r#" [ {"payload" :42} , {"payload": 23} ] "#) - .await?; + t.receive_status_update( + instance.id, + r#" {"updates": [ {"payload" :42} , {"payload": 23} ] } "#, + ) + .await?; assert_eq!( t.get_webxdc_status_updates(instance.id, None).await?, r#"[{"payload":{"foo":"bar"}}, @@ -572,6 +600,19 @@ mod tests { {"payload":23}]"# ); + t.receive_status_update( + instance.id, + r#" {"updates": [ {"payload" :"ok", "future_item": "test"} ], "from": "future" } "#, + ) + .await?; // ignore members that may be added in the future + assert_eq!( + t.get_webxdc_status_updates(instance.id, None).await?, + r#"[{"payload":{"foo":"bar"}}, +{"payload":42}, +{"payload":23}, +{"payload":"ok"}]"# + ); + Ok(()) }