diff --git a/src/subscription.rs b/src/subscription.rs index 725d39c..972e978 100644 --- a/src/subscription.rs +++ b/src/subscription.rs @@ -65,12 +65,21 @@ impl<'de> Deserialize<'de> for ReqFilter { tags: None, force_no_match: false, }; + let empty_string = "".into(); let mut ts = None; // iterate through each key, and assign values that exist for (key, val) in filter.into_iter() { // ids if key == "ids" { - rf.ids = Deserialize::deserialize(val).ok(); + let raw_ids: Option>= Deserialize::deserialize(val).ok(); + if let Some(a) = raw_ids.as_ref() { + if a.contains(&empty_string) { + return Err(serde::de::Error::invalid_type( + Unexpected::Other("prefix matches must not be empty strings"), + &"a json object")); + } + } + rf.ids =raw_ids; } else if key == "kinds" { rf.kinds = Deserialize::deserialize(val).ok(); } else if key == "since" { @@ -80,7 +89,15 @@ impl<'de> Deserialize<'de> for ReqFilter { } else if key == "limit" { rf.limit = Deserialize::deserialize(val).ok(); } else if key == "authors" { - rf.authors = Deserialize::deserialize(val).ok(); + let raw_authors: Option>= Deserialize::deserialize(val).ok(); + if let Some(a) = raw_authors.as_ref() { + if a.contains(&empty_string) { + return Err(serde::de::Error::invalid_type( + Unexpected::Other("prefix matches must not be empty strings"), + &"a json object")); + } + } + rf.authors = raw_authors; } else if key.starts_with('#') && key.len() > 1 && val.is_array() { if let Some(tag_search) = tag_search_char_from_filter(key) { if ts.is_none() { @@ -294,6 +311,24 @@ mod tests { assert!(serde_json::from_str::(raw_json).is_err()); } + #[test] + fn req_empty_authors_prefix() { + let raw_json = "[\"REQ\",\"some-id\",{\"authors\": [\"\"]}]"; + assert!(serde_json::from_str::(raw_json).is_err()); + } + + #[test] + fn req_empty_ids_prefix() { + let raw_json = "[\"REQ\",\"some-id\",{\"ids\": [\"\"]}]"; + assert!(serde_json::from_str::(raw_json).is_err()); + } + + #[test] + fn req_empty_ids_prefix_mixed() { + let raw_json = "[\"REQ\",\"some-id\",{\"ids\": [\"\",\"aaa\"]}]"; + assert!(serde_json::from_str::(raw_json).is_err()); + } + #[test] fn legacy_filter() { // legacy field in filter