commit a99df25eb4161081e32ce8c817e11848552a1027
parent 32a295afb4bb7d200d17a61030fd9e5b2570ef28
Author: MTRNord <mtrnord1@gmail.com>
Date: Fri, 12 Aug 2022 17:15:07 +0200
Lazy mans solution to arbitrary json objects
Diffstat:
3 files changed, 76 insertions(+), 124 deletions(-)
diff --git a/README.md b/README.md
@@ -30,3 +30,7 @@ Matrix fuzzing is a dumb fuzzer fuzzing a few matrix endpoints. It requires a HS
- https://github.com/matrix-org/synapse/issues/13510
- https://github.com/matrix-org/synapse/issues/13511
- https://github.com/matrix-org/synapse/issues/13512
+
+# Known bugs in the fuzzer
+
+The fuzzer generates arbitrary json objects currently very poorly. Resulting in a lot less cases than it should. Its a workaround for now until there is a nicer way.
+\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
@@ -112,7 +112,7 @@ mod tests {
#[cfg(all(fuzzing, test))]
mod tests {
- use crate::types::CreateRoomMagic;
+ use crate::types::{CreateRoomMagic, CreateRoomMagicJSON};
fn create_room(data: &CreateRoomMagic) -> bool {
// FIXME: We probably should set it to null and not do a false positive
@@ -134,10 +134,11 @@ mod tests {
// TODO: Login once and reuse the access token
let access_token = crate::access_token();
let client = crate::client();
+ let json_data: CreateRoomMagicJSON = data.into();
let resp = client
.post("http://localhost:8008/_matrix/client/v3/createRoom")
.header("Authorization", format!("Bearer {}", access_token))
- .json(data)
+ .json(&json_data)
.send();
if let Ok(resp) = resp {
let status = resp.status().clone();
diff --git a/src/types.rs b/src/types.rs
@@ -1,10 +1,6 @@
-use fuzzcheck::{
- mutators::{grammar::*, map::MapMutator, option::OptionMutator},
- DefaultMutator, Mutator,
-};
+use fuzzcheck::DefaultMutator;
use serde::{Deserialize, Serialize};
-use serde_json::{Map, Value};
-use std::rc::{Rc, Weak};
+use std::collections::HashMap;
#[derive(Debug, Serialize, Deserialize)]
pub struct LoginGet {
@@ -25,9 +21,9 @@ pub struct LoginPost {
}
#[derive(Clone, Serialize, Deserialize, Debug, Default)]
-pub struct CreateRoomMagic {
+pub struct CreateRoomMagicJSON {
#[serde(skip_serializing_if = "Option::is_none")]
- pub creation_content: Option<Map<String, Value>>,
+ pub creation_content: Option<HashMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub invite: Option<Vec<String>>,
// Due to https://github.com/matrix-org/synapse/issues/13512
@@ -49,24 +45,71 @@ pub struct CreateRoomMagic {
pub visibility: Option<String>,
}
-fuzzcheck::make_mutator! {
- name: CreateRoomMagicMutator,
- default: true,
- type:
- pub struct CreateRoomMagic {
- #[field_mutator(OptionMutator<Map<String,Value>, JSONMutator> = { OptionMutator::new(json_object_mutator()) } )]
- pub creation_content: Option<Map<String,Value>>,
- pub invite: Option<Vec<String>>,
- // Due to https://github.com/matrix-org/synapse/issues/13512
- //pub invite_3pid: Option<Vec<Invite3pid>>,
- pub is_direct: Option<bool>,
- pub name: Option<String>,
- pub preset: Option<String>,
- pub room_alias_name: Option<String>,
- pub room_version: Option<String>,
- pub topic: Option<String>,
- pub visibility: Option<String>,
+// FIXME: This is stupid hacky.
+impl From<&CreateRoomMagic> for CreateRoomMagicJSON {
+ fn from(item: &CreateRoomMagic) -> Self {
+ let mut creation_content = HashMap::new();
+ if let Some(mut creation_content_keys) = item.creation_content_keys.clone() {
+ if let Some(mut creation_content_values) = item.creation_content_values.clone() {
+ if creation_content_keys.len() > creation_content_values.len() {
+ creation_content_keys.truncate(creation_content_values.len());
+ } else {
+ creation_content_values.truncate(creation_content_keys.len());
+ }
+ for (key, value) in creation_content_keys
+ .iter()
+ .zip(creation_content_values.iter())
+ {
+ creation_content.insert(key.to_string(), value.to_string());
+ }
+ }
}
+
+ CreateRoomMagicJSON {
+ invite: item.invite.clone(),
+ is_direct: item.is_direct,
+ name: item.name.clone(),
+ preset: item.preset.clone(),
+ room_alias_name: item.room_alias_name.clone(),
+ room_version: item.room_version.clone(),
+ topic: item.topic.clone(),
+ visibility: item.visibility.clone(),
+ creation_content: if item.creation_content_keys.is_none()
+ || item.creation_content_values.is_none()
+ {
+ None
+ } else {
+ Some(creation_content)
+ },
+ }
+ }
+}
+
+#[derive(Clone, Serialize, Deserialize, Debug, Default, DefaultMutator)]
+pub struct CreateRoomMagic {
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub creation_content_keys: Option<Vec<String>>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub creation_content_values: Option<Vec<String>>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub invite: Option<Vec<String>>,
+ // Due to https://github.com/matrix-org/synapse/issues/13512
+ //#[serde(skip_serializing_if = "Option::is_none")]
+ //pub invite_3pid: Option<Vec<Invite3pid>>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub is_direct: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub name: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub preset: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub room_alias_name: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub room_version: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub topic: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub visibility: Option<String>,
}
#[derive(Clone, Serialize, Deserialize, Debug, DefaultMutator, Default)]
@@ -76,100 +119,3 @@ pub struct Invite3pid {
pub id_server: String,
pub medium: String,
}
-fn null() -> Rc<Grammar> {
- regex("null")
-}
-
-fn boolean() -> Rc<Grammar> {
- regex("true|false")
-}
-
-fn text() -> Rc<Grammar> {
- concatenation([
- literal('"'),
- regex("([\u{0020}-\u{0021}]|[\u{0023}-\u{7f}]|.)+"),
- literal('"'),
- ])
- //concatenation([literal('"'), regex("([\u{0}-\u{7f}]|.)+"), literal('"')])
-}
-
-fn number() -> Rc<Grammar> {
- regex("[0-9]+")
-}
-
-fn json_object_entry(rule: &Weak<Grammar>) -> Rc<Grammar> {
- concatenation([text(), literal(':'), json_value(rule, None)])
-}
-
-fn json_array(outer_rule: &Weak<Grammar>) -> Rc<Grammar> {
- recursive(|rule| {
- concatenation([
- literal('['),
- json_value(outer_rule, Some(rule)),
- repetition(
- concatenation([literal(','), json_value(outer_rule, Some(rule))]),
- 1..,
- ),
- literal(']'),
- ])
- })
-}
-
-fn json_value(object_rule: &Weak<Grammar>, array_rule: Option<&Weak<Grammar>>) -> Rc<Grammar> {
- if let Some(array_rule) = array_rule {
- alternation([
- recurse(object_rule),
- recurse(array_rule),
- text(),
- number(),
- null(),
- boolean(),
- ])
- } else {
- alternation([
- recurse(object_rule),
- json_array(object_rule),
- text(),
- number(),
- null(),
- boolean(),
- ])
- }
-}
-
-fn json_object() -> Rc<Grammar> {
- recursive(|rule| {
- concatenation([
- literal('{'),
- json_object_entry(rule),
- repetition(concatenation([literal(','), json_object_entry(rule)]), 1..),
- literal('}'),
- ])
- })
-}
-
-type JSONMutator = impl Mutator<Map<String, Value>>;
-
-fn json_object_mutator() -> JSONMutator {
- MapMutator::new(
- grammar_based_ast_mutator(json_object()),
- |_string: &Map<String, Value>| {
- // FIXME: This is a hack
- Some(serde_json::from_str::<AST>(r#"{"Sequence":[{"Token":"{"},{"Sequence":[{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":""}]},{"Token":"\""}]},{"Token":":"},{"Sequence":[{"Token":"["},{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":"\u0006"}]},{"Token":"\""}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Sequence":[{"Token":"{"},{"Sequence":[{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":"J"}]},{"Token":"\""}]},{"Token":":"},{"Sequence":[{"Sequence":[{"Token":"{"},{"Sequence":[{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":""}]},{"Token":"\""}]},{"Token":":"},{"Sequence":[{"Token":"6"}]}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":"|"}]},{"Token":"\""}]},{"Token":":"},{"Sequence":[{"Token":"["},{"Sequence":[{"Sequence":[{"Token":"["},{"Sequence":[{"Token":"n"},{"Token":"u"},{"Token":"l"},{"Token":"l"}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Sequence":[{"Token":"["},{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":""}]},{"Token":"\""}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Sequence":[{"Token":"["},{"Sequence":[{"Sequence":[{"Token":"{"},{"Sequence":[{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":"𪪍"}]},{"Token":"\""}]},{"Token":":"},{"Sequence":[{"Token":"t"},{"Token":"r"},{"Token":"u"},{"Token":"e"}]}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":"\u0001"}]},{"Token":"\""}]},{"Token":":"},{"Sequence":[{"Token":"4"}]}]}]}]},{"Token":"}"}]}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Sequence":[{"Token":"{"},{"Sequence":[{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":""}]},{"Token":"\""}]},{"Token":":"},{"Sequence":[{"Token":"f"},{"Token":"a"},{"Token":"l"},{"Token":"s"},{"Token":"e"}]}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":"m"}]},{"Token":"\""}]},{"Token":":"},{"Sequence":[{"Token":"8"}]}]}]}]},{"Token":"}"}]}]}]}]},{"Token":"]"}]}]}]}]},{"Token":"]"}]}]}]}]},{"Token":"]"}]}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Token":"n"},{"Token":"u"},{"Token":"l"},{"Token":"l"}]}]}]},{"Token":"]"}]}]}]}]},{"Token":"}"}]}]}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":"}"}]},{"Token":"\""}]},{"Token":":"},{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":"𬗲"}]},{"Token":"\""}]}]}]}]},{"Token":"}"}]}]}]}]},{"Token":"]"}]}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":""}]},{"Token":"\""}]},{"Token":":"},{"Sequence":[{"Token":"["},{"Sequence":[{"Token":"\""},{"Sequence":[{"Token":""}]},{"Token":"\""}]},{"Sequence":[{"Sequence":[{"Token":","},{"Sequence":[{"Token":"0"}]}]}]},{"Token":"]"}]}]}]}]},{"Token":"}"}]}"#).unwrap())
- /*match serde_json::from_str::<AST>(string) {
- Ok(ast) => Some(ast),
- Err(e) => {
- println!("Error: {:?}", e);
-
- None
- }
- }*/
- },
- |ast| {
- let string = ast.to_string();
- //println!("{}", string);
- serde_json::from_str::<Map<String, Value>>(&string).unwrap()
- },
- |_, cplx| cplx,
- )
-}