matrix-fuzz

git clone git://archive.git.mtrnord.blog/MTRNord/matrix-fuzz.git
Log | Files | Refs | README | LICENSE

commit 32a295afb4bb7d200d17a61030fd9e5b2570ef28
parent 11565c064d19b2af7736c749f41df2d817256a38
Author: MTRNord <mtrnord1@gmail.com>
Date:   Fri, 12 Aug 2022 16:11:20 +0200

V1

Diffstat:
M.gitignore | 6++++--
MCargo.toml | 2--
MLICENSE.md | 402++++++++++++++++++++++++++++++++++++++++----------------------------------------
MREADME.md | 64++++++++++++++++++++++++++++++++--------------------------------
Msrc/lib.rs | 79+++++++++----------------------------------------------------------------------
Msrc/types.rs | 194+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
6 files changed, 421 insertions(+), 326 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -2,4 +2,6 @@ /Cargo.lock notes.md src/secrets.rs -/fuzz -\ No newline at end of file +/fuzz +/meep.rs +/weird_ones/security_issues +\ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml @@ -10,6 +10,4 @@ serde = { version = "1.0", features = ["derive"] } reqwest = { version = "0.11.11", features = ["blocking","json","gzip"] } serde_json = "1.0.83" once_cell = "1.13.0" - -[target.'cfg(fuzzing)'.dev-dependencies] fuzzcheck = "0.12" \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md @@ -1,201 +1,201 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md @@ -1,32 +1,32 @@ -# Matrix Fuzzing - -Matrix fuzzing is a dumb fuzzer fuzzing a few matrix endpoints. It requires a HS and a user to exist. - -# Current targets - -- `/_matrix/client/v3/createRoom` - `tests::tests::fuzz_create_room` - -# Usage - -1. Create a HS -1. Setup a user -1. Add the secrets to src/secrets.rs. - - Example code: - - ```rust - pub const USERNAME: &str = "@a:localhost"; - pub const PASSWORD: &str = "abc123"; - ``` - -1. Install fuzzcheck -> https://github.com/loiclec/fuzzcheck-rs#setup -1. Run `cargo fuzzcheck <target>` -1. Wait until it crashes -1. Verify the error by trying the output json yourself -1. Please make sure to follow https://matrix.org/security-disclosure-policy/ for found errors instead of posting them in public unless you are 100% sure they are not a security issue. If you are in doubt prefer the security disclosure policy. - -# Hall of Explosions (Bugs found) - -- https://github.com/matrix-org/synapse/issues/13510 -- https://github.com/matrix-org/synapse/issues/13511 -- https://github.com/matrix-org/synapse/issues/13512 +# Matrix Fuzzing + +Matrix fuzzing is a dumb fuzzer fuzzing a few matrix endpoints. It requires a HS and a user to exist. + +# Current targets + +- `/_matrix/client/v3/createRoom` - `tests::tests::fuzz_create_room` + +# Usage + +1. Create a HS +1. Setup a user +1. Add the secrets to src/secrets.rs. + + Example code: + + ```rust + pub const USERNAME: &str = "@a:localhost"; + pub const PASSWORD: &str = "abc123"; + ``` + +1. Install fuzzcheck -> https://github.com/loiclec/fuzzcheck-rs#setup +1. Run `cargo fuzzcheck <target>` +1. Wait until it crashes +1. Verify the error by trying the output json yourself +1. Please make sure to follow https://matrix.org/security-disclosure-policy/ for found errors instead of posting them in public unless you are 100% sure they are not a security issue. If you are in doubt prefer the security disclosure policy. + +# Hall of Explosions (Bugs found) + +- https://github.com/matrix-org/synapse/issues/13510 +- https://github.com/matrix-org/synapse/issues/13511 +- https://github.com/matrix-org/synapse/issues/13512 diff --git a/src/lib.rs b/src/lib.rs @@ -1,5 +1,7 @@ -#![cfg_attr(fuzzing, feature(no_coverage))] +#![feature(no_coverage)] +#![feature(type_alias_impl_trait)] #![allow(dead_code)] +#![allow(clippy::too_many_arguments)] use std::collections::HashMap; @@ -55,6 +57,10 @@ fn login() -> String { #[cfg(all(test, not(fuzzing)))] mod tests { + use reqwest::header::{HeaderValue, CONTENT_TYPE}; + + use crate::types::CreateRoomMagic; + #[test] fn connection_test() { let client = crate::client(); @@ -65,39 +71,6 @@ mod tests { assert!(resp.status().is_success()); } - use reqwest::header::{HeaderValue, CONTENT_TYPE}; - use serde::{Deserialize, Serialize}; - - #[derive(Clone, Serialize, Deserialize, Debug, Default)] - struct CreateRoomMagic { - #[serde(skip_serializing_if = "Option::is_none")] - invite: Option<Vec<String>>, - #[serde(skip_serializing_if = "Option::is_none")] - invite_3pid: Option<Vec<Invite3pid>>, - #[serde(skip_serializing_if = "Option::is_none")] - is_direct: Option<bool>, - #[serde(skip_serializing_if = "Option::is_none")] - name: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - preset: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - room_alias_name: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - room_version: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - topic: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - visibility: Option<String>, - } - - #[derive(Clone, Serialize, Deserialize, Debug, Default)] - struct Invite3pid { - address: String, - id_access_token: String, - id_server: String, - medium: String, - } - #[test] fn null_in_room() { let content = CreateRoomMagic { @@ -139,39 +112,7 @@ mod tests { #[cfg(all(fuzzing, test))] mod tests { - use fuzzcheck::DefaultMutator; - use serde::{Deserialize, Serialize}; - - #[derive(Clone, DefaultMutator, Serialize, Deserialize, Debug)] - struct CreateRoomMagic { - #[serde(skip_serializing_if = "Option::is_none")] - invite: Option<Vec<String>>, - // Due to https://github.com/matrix-org/synapse/issues/13512 - //#[serde(skip_serializing_if = "Option::is_none")] - //invite_3pid: Option<Vec<Invite3pid>>, - #[serde(skip_serializing_if = "Option::is_none")] - is_direct: Option<bool>, - #[serde(skip_serializing_if = "Option::is_none")] - name: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - preset: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - room_alias_name: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - room_version: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - topic: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - visibility: Option<String>, - } - - #[derive(Clone, DefaultMutator, Serialize, Deserialize, Debug)] - struct Invite3pid { - address: String, - id_access_token: String, - id_server: String, - medium: String, - } + use crate::types::CreateRoomMagic; fn create_room(data: &CreateRoomMagic) -> bool { // FIXME: We probably should set it to null and not do a false positive @@ -230,13 +171,11 @@ mod tests { if !resp.status().is_success() { panic!("Failed to connect"); } + let result = fuzzcheck::fuzz_test(create_room) .default_options() .stop_after_first_test_failure(true) .launch(); - if result.found_test_failure { - println!("{:?}", result.reason_for_stopping); - } assert!(!result.found_test_failure); } } diff --git a/src/types.rs b/src/types.rs @@ -1,19 +1,175 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Serialize, Deserialize)] -pub struct LoginGet { - pub flows: Vec<Flow>, -} - -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] -pub struct Flow { - #[serde(rename = "type")] - pub type_: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct LoginPost { - pub user_id: String, - pub access_token: String, - pub home_server: String, -} +use fuzzcheck::{ + mutators::{grammar::*, map::MapMutator, option::OptionMutator}, + DefaultMutator, Mutator, +}; +use serde::{Deserialize, Serialize}; +use serde_json::{Map, Value}; +use std::rc::{Rc, Weak}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct LoginGet { + pub flows: Vec<Flow>, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +pub struct Flow { + #[serde(rename = "type")] + pub type_: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct LoginPost { + pub user_id: String, + pub access_token: String, + pub home_server: String, +} + +#[derive(Clone, Serialize, Deserialize, Debug, Default)] +pub struct CreateRoomMagic { + #[serde(skip_serializing_if = "Option::is_none")] + pub creation_content: Option<Map<String, Value>>, + #[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>, +} + +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>, + } +} + +#[derive(Clone, Serialize, Deserialize, Debug, DefaultMutator, Default)] +pub struct Invite3pid { + pub address: String, + pub id_access_token: String, + 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, + ) +}