From 1f6cc0970a7d54e36be29c5932def1f0663cfeaa Mon Sep 17 00:00:00 2001 From: "glm-5.3-flash" Date: Sat, 10 Oct 2026 21:42:41 +0000 Subject: [PATCH] =?UTF-8?q?fuzz-target-payload-codec:=20the=20=C2=A73.1=20?= =?UTF-8?q?target=20=E2=80=94=20all=20five=20invariants=20in=20shared,=20t?= =?UTF-8?q?hin=20fuzz=5Ftarget=20wrapper,=2097=20committed=20seeds=20+=20g?= =?UTF-8?q?itignore=20negation=20+=20README=20row;=20placeholder=20bin=20r?= =?UTF-8?q?eplaced;=20serde=20(derive)=20added=20to=20shared?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fuzz/.gitignore | 1 + fuzz/Cargo.lock | 2 + fuzz/Cargo.toml | 4 +- fuzz/README.md | 2 +- fuzz/corpus/payload_codec/seed-000 | 1 + fuzz/corpus/payload_codec/seed-001 | 1 + fuzz/corpus/payload_codec/seed-002 | 1 + fuzz/corpus/payload_codec/seed-003 | 1 + fuzz/corpus/payload_codec/seed-004 | 1 + fuzz/corpus/payload_codec/seed-005 | 1 + fuzz/corpus/payload_codec/seed-006 | 1 + fuzz/corpus/payload_codec/seed-007 | 1 + fuzz/corpus/payload_codec/seed-008 | 1 + fuzz/corpus/payload_codec/seed-009 | 1 + fuzz/corpus/payload_codec/seed-010 | 1 + fuzz/corpus/payload_codec/seed-011 | 1 + fuzz/corpus/payload_codec/seed-012 | 1 + fuzz/corpus/payload_codec/seed-013 | 1 + fuzz/corpus/payload_codec/seed-014 | 1 + fuzz/corpus/payload_codec/seed-015 | 1 + fuzz/corpus/payload_codec/seed-016 | 1 + fuzz/corpus/payload_codec/seed-017 | 1 + fuzz/corpus/payload_codec/seed-018 | 1 + fuzz/corpus/payload_codec/seed-019 | 1 + fuzz/corpus/payload_codec/seed-020 | 1 + fuzz/corpus/payload_codec/seed-021 | 1 + fuzz/corpus/payload_codec/seed-022 | 1 + fuzz/corpus/payload_codec/seed-023 | 1 + fuzz/corpus/payload_codec/seed-024 | 1 + fuzz/corpus/payload_codec/seed-025 | 1 + fuzz/corpus/payload_codec/seed-026 | 3 + fuzz/corpus/payload_codec/seed-027 | 1 + fuzz/corpus/payload_codec/seed-028 | 1 + fuzz/corpus/payload_codec/seed-029 | 1 + fuzz/corpus/payload_codec/seed-030 | 1 + fuzz/corpus/payload_codec/seed-031 | 1 + fuzz/corpus/payload_codec/seed-032 | 1 + fuzz/corpus/payload_codec/seed-033 | 1 + fuzz/corpus/payload_codec/seed-034 | 1 + fuzz/corpus/payload_codec/seed-035 | 1 + fuzz/corpus/payload_codec/seed-036 | 1 + fuzz/corpus/payload_codec/seed-037 | 1 + fuzz/corpus/payload_codec/seed-038 | 1 + fuzz/corpus/payload_codec/seed-039 | 1 + fuzz/corpus/payload_codec/seed-040 | 1 + fuzz/corpus/payload_codec/seed-041 | 1 + fuzz/corpus/payload_codec/seed-042 | 1 + fuzz/corpus/payload_codec/seed-043 | 1 + fuzz/corpus/payload_codec/seed-044 | 1 + fuzz/corpus/payload_codec/seed-045 | 1 + fuzz/corpus/payload_codec/seed-046 | 1 + fuzz/corpus/payload_codec/seed-047 | 1 + fuzz/corpus/payload_codec/seed-048 | 1 + fuzz/corpus/payload_codec/seed-049 | 1 + fuzz/corpus/payload_codec/seed-050 | 1 + fuzz/corpus/payload_codec/seed-051 | 1 + fuzz/corpus/payload_codec/seed-052 | 1 + fuzz/corpus/payload_codec/seed-053 | 1 + fuzz/corpus/payload_codec/seed-054 | 1 + fuzz/corpus/payload_codec/seed-055 | 1 + fuzz/corpus/payload_codec/seed-056 | 1 + fuzz/corpus/payload_codec/seed-057 | 1 + fuzz/corpus/payload_codec/seed-058 | 1 + fuzz/corpus/payload_codec/seed-059 | 1 + fuzz/corpus/payload_codec/seed-060 | 1 + fuzz/corpus/payload_codec/seed-061 | 1 + fuzz/corpus/payload_codec/seed-062 | 1 + fuzz/corpus/payload_codec/seed-063 | 1 + fuzz/corpus/payload_codec/seed-064 | 1 + fuzz/corpus/payload_codec/seed-065 | 1 + fuzz/corpus/payload_codec/seed-066 | 1 + fuzz/corpus/payload_codec/seed-067 | 1 + fuzz/corpus/payload_codec/seed-068 | 1 + fuzz/corpus/payload_codec/seed-069 | 1 + fuzz/corpus/payload_codec/seed-070 | 1 + fuzz/corpus/payload_codec/seed-071 | 1 + fuzz/corpus/payload_codec/seed-072 | 1 + fuzz/corpus/payload_codec/seed-073 | 1 + fuzz/corpus/payload_codec/seed-074 | 1 + fuzz/corpus/payload_codec/seed-075 | 1 + fuzz/corpus/payload_codec/seed-076 | 1 + fuzz/corpus/payload_codec/seed-077 | 1 + fuzz/corpus/payload_codec/seed-078 | 1 + fuzz/corpus/payload_codec/seed-079 | 1 + fuzz/corpus/payload_codec/seed-080 | 1 + fuzz/corpus/payload_codec/seed-081 | 0 fuzz/corpus/payload_codec/seed-082 | 1 + fuzz/corpus/payload_codec/seed-083 | 1 + fuzz/corpus/payload_codec/seed-084 | 1 + fuzz/corpus/payload_codec/seed-085 | 1 + fuzz/corpus/payload_codec/seed-086 | 1 + fuzz/corpus/payload_codec/seed-087 | 1 + fuzz/corpus/payload_codec/seed-088 | 1 + fuzz/corpus/payload_codec/seed-089 | 1 + fuzz/corpus/payload_codec/seed-090 | 1 + fuzz/corpus/payload_codec/seed-091 | 1 + fuzz/corpus/payload_codec/seed-092 | 1 + fuzz/corpus/payload_codec/seed-093 | 1 + fuzz/corpus/payload_codec/seed-094 | 1 + fuzz/corpus/payload_codec/seed-095 | 1 + fuzz/corpus/payload_codec/seed-096 | 1 + fuzz/fuzz_targets/payload_codec.rs | 10 + fuzz/fuzz_targets/placeholder.rs | 11 -- fuzz/gen_fuzz_seeds.py | 102 +++++++++- fuzz/shared/Cargo.toml | 1 + fuzz/shared/src/lib.rs | 1 + fuzz/shared/src/payload_codec.rs | 295 +++++++++++++++++++++++++++++ tasks/fuzz-target-payload-codec.md | 80 +++++++- 108 files changed, 583 insertions(+), 24 deletions(-) create mode 100644 fuzz/corpus/payload_codec/seed-000 create mode 100644 fuzz/corpus/payload_codec/seed-001 create mode 100644 fuzz/corpus/payload_codec/seed-002 create mode 100644 fuzz/corpus/payload_codec/seed-003 create mode 100644 fuzz/corpus/payload_codec/seed-004 create mode 100644 fuzz/corpus/payload_codec/seed-005 create mode 100644 fuzz/corpus/payload_codec/seed-006 create mode 100644 fuzz/corpus/payload_codec/seed-007 create mode 100644 fuzz/corpus/payload_codec/seed-008 create mode 100644 fuzz/corpus/payload_codec/seed-009 create mode 100644 fuzz/corpus/payload_codec/seed-010 create mode 100644 fuzz/corpus/payload_codec/seed-011 create mode 100644 fuzz/corpus/payload_codec/seed-012 create mode 100644 fuzz/corpus/payload_codec/seed-013 create mode 100644 fuzz/corpus/payload_codec/seed-014 create mode 100644 fuzz/corpus/payload_codec/seed-015 create mode 100644 fuzz/corpus/payload_codec/seed-016 create mode 100644 fuzz/corpus/payload_codec/seed-017 create mode 100644 fuzz/corpus/payload_codec/seed-018 create mode 100644 fuzz/corpus/payload_codec/seed-019 create mode 100644 fuzz/corpus/payload_codec/seed-020 create mode 100644 fuzz/corpus/payload_codec/seed-021 create mode 100644 fuzz/corpus/payload_codec/seed-022 create mode 100644 fuzz/corpus/payload_codec/seed-023 create mode 100644 fuzz/corpus/payload_codec/seed-024 create mode 100644 fuzz/corpus/payload_codec/seed-025 create mode 100644 fuzz/corpus/payload_codec/seed-026 create mode 100644 fuzz/corpus/payload_codec/seed-027 create mode 100644 fuzz/corpus/payload_codec/seed-028 create mode 100644 fuzz/corpus/payload_codec/seed-029 create mode 100644 fuzz/corpus/payload_codec/seed-030 create mode 100644 fuzz/corpus/payload_codec/seed-031 create mode 100644 fuzz/corpus/payload_codec/seed-032 create mode 100644 fuzz/corpus/payload_codec/seed-033 create mode 100644 fuzz/corpus/payload_codec/seed-034 create mode 100644 fuzz/corpus/payload_codec/seed-035 create mode 100644 fuzz/corpus/payload_codec/seed-036 create mode 100644 fuzz/corpus/payload_codec/seed-037 create mode 100644 fuzz/corpus/payload_codec/seed-038 create mode 100644 fuzz/corpus/payload_codec/seed-039 create mode 100644 fuzz/corpus/payload_codec/seed-040 create mode 100644 fuzz/corpus/payload_codec/seed-041 create mode 100644 fuzz/corpus/payload_codec/seed-042 create mode 100644 fuzz/corpus/payload_codec/seed-043 create mode 100644 fuzz/corpus/payload_codec/seed-044 create mode 100644 fuzz/corpus/payload_codec/seed-045 create mode 100644 fuzz/corpus/payload_codec/seed-046 create mode 100644 fuzz/corpus/payload_codec/seed-047 create mode 100644 fuzz/corpus/payload_codec/seed-048 create mode 100644 fuzz/corpus/payload_codec/seed-049 create mode 100644 fuzz/corpus/payload_codec/seed-050 create mode 100644 fuzz/corpus/payload_codec/seed-051 create mode 100644 fuzz/corpus/payload_codec/seed-052 create mode 100644 fuzz/corpus/payload_codec/seed-053 create mode 100644 fuzz/corpus/payload_codec/seed-054 create mode 100644 fuzz/corpus/payload_codec/seed-055 create mode 100644 fuzz/corpus/payload_codec/seed-056 create mode 100644 fuzz/corpus/payload_codec/seed-057 create mode 100644 fuzz/corpus/payload_codec/seed-058 create mode 100644 fuzz/corpus/payload_codec/seed-059 create mode 100644 fuzz/corpus/payload_codec/seed-060 create mode 100644 fuzz/corpus/payload_codec/seed-061 create mode 100644 fuzz/corpus/payload_codec/seed-062 create mode 100644 fuzz/corpus/payload_codec/seed-063 create mode 100644 fuzz/corpus/payload_codec/seed-064 create mode 100644 fuzz/corpus/payload_codec/seed-065 create mode 100644 fuzz/corpus/payload_codec/seed-066 create mode 100644 fuzz/corpus/payload_codec/seed-067 create mode 100644 fuzz/corpus/payload_codec/seed-068 create mode 100644 fuzz/corpus/payload_codec/seed-069 create mode 100644 fuzz/corpus/payload_codec/seed-070 create mode 100644 fuzz/corpus/payload_codec/seed-071 create mode 100644 fuzz/corpus/payload_codec/seed-072 create mode 100644 fuzz/corpus/payload_codec/seed-073 create mode 100644 fuzz/corpus/payload_codec/seed-074 create mode 100644 fuzz/corpus/payload_codec/seed-075 create mode 100644 fuzz/corpus/payload_codec/seed-076 create mode 100644 fuzz/corpus/payload_codec/seed-077 create mode 100644 fuzz/corpus/payload_codec/seed-078 create mode 100644 fuzz/corpus/payload_codec/seed-079 create mode 100644 fuzz/corpus/payload_codec/seed-080 create mode 100644 fuzz/corpus/payload_codec/seed-081 create mode 100644 fuzz/corpus/payload_codec/seed-082 create mode 100644 fuzz/corpus/payload_codec/seed-083 create mode 100644 fuzz/corpus/payload_codec/seed-084 create mode 100644 fuzz/corpus/payload_codec/seed-085 create mode 100644 fuzz/corpus/payload_codec/seed-086 create mode 100644 fuzz/corpus/payload_codec/seed-087 create mode 100644 fuzz/corpus/payload_codec/seed-088 create mode 100644 fuzz/corpus/payload_codec/seed-089 create mode 100644 fuzz/corpus/payload_codec/seed-090 create mode 100644 fuzz/corpus/payload_codec/seed-091 create mode 100644 fuzz/corpus/payload_codec/seed-092 create mode 100644 fuzz/corpus/payload_codec/seed-093 create mode 100644 fuzz/corpus/payload_codec/seed-094 create mode 100644 fuzz/corpus/payload_codec/seed-095 create mode 100644 fuzz/corpus/payload_codec/seed-096 create mode 100644 fuzz/fuzz_targets/payload_codec.rs delete mode 100644 fuzz/fuzz_targets/placeholder.rs create mode 100644 fuzz/shared/src/payload_codec.rs diff --git a/fuzz/.gitignore b/fuzz/.gitignore index df13f06..40b96c7 100644 --- a/fuzz/.gitignore +++ b/fuzz/.gitignore @@ -1,4 +1,5 @@ target corpus/* +!corpus/payload_codec artifacts coverage diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index c171b2a..3366e02 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -26,6 +26,7 @@ version = "0.0.0" dependencies = [ "alkstore", "arbitrary", + "serde", "serde_json", ] @@ -153,6 +154,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", + "serde_derive", ] [[package]] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 3f0e157..d5f8ea7 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -15,8 +15,8 @@ alkstore-fuzz-shared = { path = "shared" } path = "../alkstore" [[bin]] -name = "placeholder" -path = "fuzz_targets/placeholder.rs" +name = "payload_codec" +path = "fuzz_targets/payload_codec.rs" test = false doc = false bench = false diff --git a/fuzz/README.md b/fuzz/README.md index 284770a..170b46a 100644 --- a/fuzz/README.md +++ b/fuzz/README.md @@ -27,7 +27,7 @@ libFuzzer targets for alkstore's parse/codec surfaces (see | Target | Drives | Invariants | |---|---|---| -| `payload_codec` | `encode_payload` / `payload_as::` (`alkstore/src/payload.rs`) | filled by its target task | +| `payload_codec` | `encode_payload` / `payload_as::` (`alkstore/src/payload.rs`) | no-panic on any byte sequence; every decode failure typed `Error::Codec`; deep nesting loud at serde_json's recursion limit; `Value` round-trip (serde_json canonicalization pinned); typed round-trip for a representative payload set | | `every_parse` | the three `parse_every_interval` implementations (differential) | filled by its target task | | `name_validation` | `validate_name` / `validate_shared_name` / `validate_local_name` (`alkstore/src/validation.rs`) | filled by its target task | diff --git a/fuzz/corpus/payload_codec/seed-000 b/fuzz/corpus/payload_codec/seed-000 new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-000 @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-001 b/fuzz/corpus/payload_codec/seed-001 new file mode 100644 index 0000000..f32a580 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-001 @@ -0,0 +1 @@ +true \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-002 b/fuzz/corpus/payload_codec/seed-002 new file mode 100644 index 0000000..02e4a84 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-002 @@ -0,0 +1 @@ +false \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-003 b/fuzz/corpus/payload_codec/seed-003 new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-003 @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-004 b/fuzz/corpus/payload_codec/seed-004 new file mode 100644 index 0000000..d7d17fc --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-004 @@ -0,0 +1 @@ +-1 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-005 b/fuzz/corpus/payload_codec/seed-005 new file mode 100644 index 0000000..9af921b --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-005 @@ -0,0 +1 @@ +-9223372036854775808 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-006 b/fuzz/corpus/payload_codec/seed-006 new file mode 100644 index 0000000..996d127 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-006 @@ -0,0 +1 @@ +9223372036854775807 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-007 b/fuzz/corpus/payload_codec/seed-007 new file mode 100644 index 0000000..84d7ca0 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-007 @@ -0,0 +1 @@ +18446744073709551615 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-008 b/fuzz/corpus/payload_codec/seed-008 new file mode 100644 index 0000000..4936a4a --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-008 @@ -0,0 +1 @@ +18446744073709551616 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-009 b/fuzz/corpus/payload_codec/seed-009 new file mode 100644 index 0000000..56e972a --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-009 @@ -0,0 +1 @@ +3.5 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-010 b/fuzz/corpus/payload_codec/seed-010 new file mode 100644 index 0000000..4aa83c7 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-010 @@ -0,0 +1 @@ +-2.25 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-011 b/fuzz/corpus/payload_codec/seed-011 new file mode 100644 index 0000000..67ec2fb --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-011 @@ -0,0 +1 @@ +1e10 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-012 b/fuzz/corpus/payload_codec/seed-012 new file mode 100644 index 0000000..3cf34bf --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-012 @@ -0,0 +1 @@ +1e309 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-013 b/fuzz/corpus/payload_codec/seed-013 new file mode 100644 index 0000000..16593f0 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-013 @@ -0,0 +1 @@ +-0 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-014 b/fuzz/corpus/payload_codec/seed-014 new file mode 100644 index 0000000..3cc762b --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-014 @@ -0,0 +1 @@ +"" \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-015 b/fuzz/corpus/payload_codec/seed-015 new file mode 100644 index 0000000..cfcb15c --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-015 @@ -0,0 +1 @@ +"hello world" \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-016 b/fuzz/corpus/payload_codec/seed-016 new file mode 100644 index 0000000..1ed4654 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-016 @@ -0,0 +1 @@ +"unicode \u00e9" \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-017 b/fuzz/corpus/payload_codec/seed-017 new file mode 100644 index 0000000..b1338b7 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-017 @@ -0,0 +1 @@ +"emoji \ud83d\ude00" \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-018 b/fuzz/corpus/payload_codec/seed-018 new file mode 100644 index 0000000..1a81a16 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-018 @@ -0,0 +1 @@ +"tab\tnewline\nquote\"slash" \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-019 b/fuzz/corpus/payload_codec/seed-019 new file mode 100644 index 0000000..80541ce --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-019 @@ -0,0 +1 @@ +"null" \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-020 b/fuzz/corpus/payload_codec/seed-020 new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-020 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-021 b/fuzz/corpus/payload_codec/seed-021 new file mode 100644 index 0000000..a61c8a5 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-021 @@ -0,0 +1 @@ +[1, "two", null, true, {"three": 3}, []] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-022 b/fuzz/corpus/payload_codec/seed-022 new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-022 @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-023 b/fuzz/corpus/payload_codec/seed-023 new file mode 100644 index 0000000..4a036f5 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-023 @@ -0,0 +1 @@ +{"a": 1} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-024 b/fuzz/corpus/payload_codec/seed-024 new file mode 100644 index 0000000..68faabc --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-024 @@ -0,0 +1 @@ +{"a": 1, "nested": {"deep": [true, null, 3.5]}} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-025 b/fuzz/corpus/payload_codec/seed-025 new file mode 100644 index 0000000..7e23b66 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-025 @@ -0,0 +1 @@ +{"\u00e9": "value"} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-026 b/fuzz/corpus/payload_codec/seed-026 new file mode 100644 index 0000000..af1b961 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-026 @@ -0,0 +1,3 @@ + +{"spaced": true} + \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-027 b/fuzz/corpus/payload_codec/seed-027 new file mode 100644 index 0000000..81750b9 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-027 @@ -0,0 +1 @@ +{ \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-028 b/fuzz/corpus/payload_codec/seed-028 new file mode 100644 index 0000000..20f22da --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-028 @@ -0,0 +1 @@ +{" \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-029 b/fuzz/corpus/payload_codec/seed-029 new file mode 100644 index 0000000..328c30c --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-029 @@ -0,0 +1 @@ +{"a \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-030 b/fuzz/corpus/payload_codec/seed-030 new file mode 100644 index 0000000..f3797b3 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-030 @@ -0,0 +1 @@ +{"a" \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-031 b/fuzz/corpus/payload_codec/seed-031 new file mode 100644 index 0000000..3ef538a --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-031 @@ -0,0 +1 @@ +{"a": \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-032 b/fuzz/corpus/payload_codec/seed-032 new file mode 100644 index 0000000..4d416b6 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-032 @@ -0,0 +1 @@ +{"a": \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-033 b/fuzz/corpus/payload_codec/seed-033 new file mode 100644 index 0000000..483be79 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-033 @@ -0,0 +1 @@ +{"a": 1 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-034 b/fuzz/corpus/payload_codec/seed-034 new file mode 100644 index 0000000..e074e55 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-034 @@ -0,0 +1 @@ +{"a": 1, \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-035 b/fuzz/corpus/payload_codec/seed-035 new file mode 100644 index 0000000..42a3ab6 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-035 @@ -0,0 +1 @@ +{"a": 1, \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-036 b/fuzz/corpus/payload_codec/seed-036 new file mode 100644 index 0000000..b99e5cf --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-036 @@ -0,0 +1 @@ +{"a": 1, " \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-037 b/fuzz/corpus/payload_codec/seed-037 new file mode 100644 index 0000000..ae2c73d --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-037 @@ -0,0 +1 @@ +{"a": 1, "b \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-038 b/fuzz/corpus/payload_codec/seed-038 new file mode 100644 index 0000000..d4072ad --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-038 @@ -0,0 +1 @@ +{"a": 1, "b" \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-039 b/fuzz/corpus/payload_codec/seed-039 new file mode 100644 index 0000000..1868b00 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-039 @@ -0,0 +1 @@ +{"a": 1, "b": \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-040 b/fuzz/corpus/payload_codec/seed-040 new file mode 100644 index 0000000..32c69eb --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-040 @@ -0,0 +1 @@ +{"a": 1, "b": \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-041 b/fuzz/corpus/payload_codec/seed-041 new file mode 100644 index 0000000..86f5a1d --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-041 @@ -0,0 +1 @@ +{"a": 1, "b": [ \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-042 b/fuzz/corpus/payload_codec/seed-042 new file mode 100644 index 0000000..b946d01 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-042 @@ -0,0 +1 @@ +{"a": 1, "b": [2 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-043 b/fuzz/corpus/payload_codec/seed-043 new file mode 100644 index 0000000..7186124 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-043 @@ -0,0 +1 @@ +{"a": 1, "b": [2, \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-044 b/fuzz/corpus/payload_codec/seed-044 new file mode 100644 index 0000000..25ca84a --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-044 @@ -0,0 +1 @@ +{"a": 1, "b": [2, \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-045 b/fuzz/corpus/payload_codec/seed-045 new file mode 100644 index 0000000..fcc0467 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-045 @@ -0,0 +1 @@ +{"a": 1, "b": [2, 3 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-046 b/fuzz/corpus/payload_codec/seed-046 new file mode 100644 index 0000000..682d8ed --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-046 @@ -0,0 +1 @@ +{"a": 1, "b": [2, 3] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-047 b/fuzz/corpus/payload_codec/seed-047 new file mode 100644 index 0000000..8e2f0be --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-047 @@ -0,0 +1 @@ +[ \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-048 b/fuzz/corpus/payload_codec/seed-048 new file mode 100644 index 0000000..762e5cd --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-048 @@ -0,0 +1 @@ +[t \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-049 b/fuzz/corpus/payload_codec/seed-049 new file mode 100644 index 0000000..81b218e --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-049 @@ -0,0 +1 @@ +[tr \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-050 b/fuzz/corpus/payload_codec/seed-050 new file mode 100644 index 0000000..8491481 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-050 @@ -0,0 +1 @@ +[tru \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-051 b/fuzz/corpus/payload_codec/seed-051 new file mode 100644 index 0000000..a8c346f --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-051 @@ -0,0 +1 @@ +[true \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-052 b/fuzz/corpus/payload_codec/seed-052 new file mode 100644 index 0000000..9e48319 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-052 @@ -0,0 +1 @@ +[true, \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-053 b/fuzz/corpus/payload_codec/seed-053 new file mode 100644 index 0000000..923f21a --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-053 @@ -0,0 +1 @@ +[true, \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-054 b/fuzz/corpus/payload_codec/seed-054 new file mode 100644 index 0000000..cd7b662 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-054 @@ -0,0 +1 @@ +[true, n \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-055 b/fuzz/corpus/payload_codec/seed-055 new file mode 100644 index 0000000..d723086 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-055 @@ -0,0 +1 @@ +[true, nu \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-056 b/fuzz/corpus/payload_codec/seed-056 new file mode 100644 index 0000000..f0e2a15 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-056 @@ -0,0 +1 @@ +[true, nul \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-057 b/fuzz/corpus/payload_codec/seed-057 new file mode 100644 index 0000000..07a5a66 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-057 @@ -0,0 +1 @@ +[true, null \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-058 b/fuzz/corpus/payload_codec/seed-058 new file mode 100644 index 0000000..99d7c9b --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-058 @@ -0,0 +1 @@ +[true, null, \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-059 b/fuzz/corpus/payload_codec/seed-059 new file mode 100644 index 0000000..004450e --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-059 @@ -0,0 +1 @@ +[true, null, \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-060 b/fuzz/corpus/payload_codec/seed-060 new file mode 100644 index 0000000..7bb6619 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-060 @@ -0,0 +1 @@ +[true, null, 1 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-061 b/fuzz/corpus/payload_codec/seed-061 new file mode 100644 index 0000000..fc45c60 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-061 @@ -0,0 +1 @@ +[true, null, 1. \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-062 b/fuzz/corpus/payload_codec/seed-062 new file mode 100644 index 0000000..f2a7fa3 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-062 @@ -0,0 +1 @@ +[true, null, 1.5 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-063 b/fuzz/corpus/payload_codec/seed-063 new file mode 100644 index 0000000..21e8f58 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-063 @@ -0,0 +1 @@ +[[[[[[[[0]]]]]]]] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-064 b/fuzz/corpus/payload_codec/seed-064 new file mode 100644 index 0000000..8bdbdb4 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-064 @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[0]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-065 b/fuzz/corpus/payload_codec/seed-065 new file mode 100644 index 0000000..23548cc --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-065 @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[0]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-066 b/fuzz/corpus/payload_codec/seed-066 new file mode 100644 index 0000000..33fc499 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-066 @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[0]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-067 b/fuzz/corpus/payload_codec/seed-067 new file mode 100644 index 0000000..aebd465 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-067 @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[0]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-068 b/fuzz/corpus/payload_codec/seed-068 new file mode 100644 index 0000000..caa5b65 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-068 @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[0]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-069 b/fuzz/corpus/payload_codec/seed-069 new file mode 100644 index 0000000..d165b82 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-069 @@ -0,0 +1 @@ +{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":1}}}}}}}} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-070 b/fuzz/corpus/payload_codec/seed-070 new file mode 100644 index 0000000..da071eb --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-070 @@ -0,0 +1 @@ +{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":1}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-071 b/fuzz/corpus/payload_codec/seed-071 new file mode 100644 index 0000000..79fc2f1 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-071 @@ -0,0 +1 @@ +ÿþý \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-072 b/fuzz/corpus/payload_codec/seed-072 new file mode 100644 index 0000000..0688e73 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-072 @@ -0,0 +1 @@ +{"a": "ÿ"} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-073 b/fuzz/corpus/payload_codec/seed-073 new file mode 100644 index 0000000..97fc544 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-073 @@ -0,0 +1 @@ +[1, 2ÿ] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-074 b/fuzz/corpus/payload_codec/seed-074 new file mode 100644 index 0000000..534db03 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-074 @@ -0,0 +1 @@ +{} trailing \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-075 b/fuzz/corpus/payload_codec/seed-075 new file mode 100644 index 0000000..5a745e6 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-075 @@ -0,0 +1 @@ +[1]x \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-076 b/fuzz/corpus/payload_codec/seed-076 new file mode 100644 index 0000000..1c6ae71 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-076 @@ -0,0 +1 @@ +1 2 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-077 b/fuzz/corpus/payload_codec/seed-077 new file mode 100644 index 0000000..b694c6d --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-077 @@ -0,0 +1 @@ +null null \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-078 b/fuzz/corpus/payload_codec/seed-078 new file mode 100644 index 0000000..ea741ca --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-078 @@ -0,0 +1 @@ +"first""second" \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-079 b/fuzz/corpus/payload_codec/seed-079 new file mode 100644 index 0000000..52793d1 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-079 @@ -0,0 +1 @@ +{"a": 1, "a": 2} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-080 b/fuzz/corpus/payload_codec/seed-080 new file mode 100644 index 0000000..724ac11 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-080 @@ -0,0 +1 @@ +{"o": {"k": 1, "k": 2}, "o": 3} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-081 b/fuzz/corpus/payload_codec/seed-081 new file mode 100644 index 0000000..e69de29 diff --git a/fuzz/corpus/payload_codec/seed-082 b/fuzz/corpus/payload_codec/seed-082 new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-082 @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-083 b/fuzz/corpus/payload_codec/seed-083 new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-083 @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-084 b/fuzz/corpus/payload_codec/seed-084 new file mode 100644 index 0000000..b184f7b --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-084 @@ -0,0 +1 @@ +nullx \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-085 b/fuzz/corpus/payload_codec/seed-085 new file mode 100644 index 0000000..b955cad --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-085 @@ -0,0 +1 @@ +NaN \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-086 b/fuzz/corpus/payload_codec/seed-086 new file mode 100644 index 0000000..5865e1c --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-086 @@ -0,0 +1 @@ +Infinity \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-087 b/fuzz/corpus/payload_codec/seed-087 new file mode 100644 index 0000000..c57a195 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-087 @@ -0,0 +1 @@ ++1 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-088 b/fuzz/corpus/payload_codec/seed-088 new file mode 100644 index 0000000..a616ad4 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-088 @@ -0,0 +1 @@ +01 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-089 b/fuzz/corpus/payload_codec/seed-089 new file mode 100644 index 0000000..cdfa3b2 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-089 @@ -0,0 +1 @@ +.5 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-090 b/fuzz/corpus/payload_codec/seed-090 new file mode 100644 index 0000000..ee85c37 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-090 @@ -0,0 +1 @@ +1. \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-091 b/fuzz/corpus/payload_codec/seed-091 new file mode 100644 index 0000000..bfbbe2b --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-091 @@ -0,0 +1 @@ +--1 \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-092 b/fuzz/corpus/payload_codec/seed-092 new file mode 100644 index 0000000..4f7034e --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-092 @@ -0,0 +1 @@ +{,} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-093 b/fuzz/corpus/payload_codec/seed-093 new file mode 100644 index 0000000..13f6f1d --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-093 @@ -0,0 +1 @@ +[1,] \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-094 b/fuzz/corpus/payload_codec/seed-094 new file mode 100644 index 0000000..d857aa3 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-094 @@ -0,0 +1 @@ +{"a"} \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-095 b/fuzz/corpus/payload_codec/seed-095 new file mode 100644 index 0000000..c306e0a --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-095 @@ -0,0 +1 @@ +{"missing": } \ No newline at end of file diff --git a/fuzz/corpus/payload_codec/seed-096 b/fuzz/corpus/payload_codec/seed-096 new file mode 100644 index 0000000..7658df0 --- /dev/null +++ b/fuzz/corpus/payload_codec/seed-096 @@ -0,0 +1 @@ +€�‚ \ No newline at end of file diff --git a/fuzz/fuzz_targets/payload_codec.rs b/fuzz/fuzz_targets/payload_codec.rs new file mode 100644 index 0000000..9e14e76 --- /dev/null +++ b/fuzz/fuzz_targets/payload_codec.rs @@ -0,0 +1,10 @@ +//! The §3.1 target: core's payload encode/decode invariants, driven +//! through the already-`pub` `encode_payload` / `payload_as` surface. + +#![no_main] + +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + alkstore_fuzz_shared::payload_codec::fuzz_payload_codec(data); +}); \ No newline at end of file diff --git a/fuzz/fuzz_targets/placeholder.rs b/fuzz/fuzz_targets/placeholder.rs deleted file mode 100644 index 954c760..0000000 --- a/fuzz/fuzz_targets/placeholder.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Placeholder target: the scaffold carries no real targets yet. The -//! wave-1 target tasks (payload_codec, every_parse, name_validation) -//! replace this with their fuzz_targets entries; it exists only so the -//! bins-only sidecar manifest parses and `cargo fuzz build` exercises -//! the nightly + ASAN toolchain check from wave 7 onward. - -#![no_main] - -use libfuzzer_sys::fuzz_target; - -fuzz_target!(|_data: &[u8]| {}); \ No newline at end of file diff --git a/fuzz/gen_fuzz_seeds.py b/fuzz/gen_fuzz_seeds.py index 17af5fe..a8adba1 100644 --- a/fuzz/gen_fuzz_seeds.py +++ b/fuzz/gen_fuzz_seeds.py @@ -24,8 +24,108 @@ def write_seed(target, i, data): f.write(data) +def payload_codec_seeds(): + i = 0 + + # Valid JSON of every Value variant (numbers incl. bounds/floats, + # strings incl. escapes/unicode, arrays, objects), plus whitespace + # padding. + valid_docs = [ + b"null", + b"true", + b"false", + b"0", + b"-1", + b"-9223372036854775808", + b"9223372036854775807", + b"18446744073709551615", + b"18446744073709551616", + b"3.5", + b"-2.25", + b"1e10", + b"1e309", + b"-0", + b'""', + b'"hello world"', + b'"unicode \\u00e9"', + b'"emoji \\ud83d\\ude00"', + b'"tab\\tnewline\\nquote\\"slash"', + b'"null"', + b"[]", + b'[1, "two", null, true, {"three": 3}, []]', + b"{}", + b'{"a": 1}', + b'{"a": 1, "nested": {"deep": [true, null, 3.5]}}', + b'{"\\u00e9": "value"}', + b' \t\r\n{"spaced": true}\t\n ', + ] + for doc in valid_docs: + write_seed("payload_codec", i, doc) + i += 1 + + # Truncations at every prefix length of two representative docs. + for doc in [b'{"a": 1, "b": [2, 3]}', b"[true, null, 1.5]"]: + for n in range(1, len(doc)): + write_seed("payload_codec", i, doc[:n]) + i += 1 + + # Deep nesting: shallow, at/near serde_json's 128 recursion limit, + # and well past it. Arrays and objects both. + for depth in [8, 127, 128, 129, 256, 1024]: + write_seed("payload_codec", i, ("[" * depth + "0" + "]" * depth).encode()) + i += 1 + for depth in [8, 200]: + write_seed("payload_codec", i, ('{"a":' * depth + "1" + "}" * depth).encode()) + i += 1 + + # Non-UTF-8 bytes inside and outside string positions. + for raw in [b"\xff\xfe\xfd", b'{"a": "\xff"}', b"[1, 2\xff]"]: + write_seed("payload_codec", i, raw) + i += 1 + + # Trailing garbage after a valid document. + for raw in [ + b"{} trailing", + b"[1]x", + b"1 2", + b"null null", + b'"first""second"', + ]: + write_seed("payload_codec", i, raw) + i += 1 + + # Duplicate keys (canonicalization is serde_json's). + for raw in [b'{"a": 1, "a": 2}', b'{"o": {"k": 1, "k": 2}, "o": 3}']: + write_seed("payload_codec", i, raw) + i += 1 + + # The Null-decode shape: an empty byte store must never decode to + # a silent Null (ADR-023 §1). + for raw in [b"", b" ", b"null", b"nullx"]: + write_seed("payload_codec", i, raw) + i += 1 + + # Other loud-fail shapes (typed `Codec` partition coverage). + for raw in [ + b"NaN", + b"Infinity", + b"+1", + b"01", + b".5", + b"1.", + b"--1", + b"{,}", + b"[1,]", + b'{"a"}', + b'{"missing": }', + b"\x80\x81\x82", + ]: + write_seed("payload_codec", i, raw) + i += 1 + + def main(): - pass + payload_codec_seeds() if __name__ == "__main__": diff --git a/fuzz/shared/Cargo.toml b/fuzz/shared/Cargo.toml index 872a160..31387cd 100644 --- a/fuzz/shared/Cargo.toml +++ b/fuzz/shared/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] alkstore = { path = "../../alkstore" } +serde = { version = "1", features = ["derive"] } serde_json = "1" [dependencies.arbitrary] diff --git a/fuzz/shared/src/lib.rs b/fuzz/shared/src/lib.rs index 6be67f4..3bbef47 100644 --- a/fuzz/shared/src/lib.rs +++ b/fuzz/shared/src/lib.rs @@ -4,3 +4,4 @@ //! CI pattern) without a nightly toolchain. pub mod arbitrary_value; +pub mod payload_codec; diff --git a/fuzz/shared/src/payload_codec.rs b/fuzz/shared/src/payload_codec.rs new file mode 100644 index 0000000..16adf30 --- /dev/null +++ b/fuzz/shared/src/payload_codec.rs @@ -0,0 +1,295 @@ +//! Invariant logic for the payload codec target (ADR-020 §4 and +//! ADR-023 §1, `alkstore/src/payload.rs`): no-panic on any byte +//! sequence, the typed-failure partition (every decode failure is +//! `Error::Codec`), deep-input loudness at serde_json's recursion +//! limit, the `Value` round-trip with serde_json's canonicalization +//! pinned-not-regressed, and the typed round-trip for a +//! representative payload set. + +use std::collections::BTreeMap; + +use alkstore::{encode_payload, payload_as, Error}; +use arbitrary::{Arbitrary, Unstructured}; +use serde_json::{json, Map, Value}; + +use crate::arbitrary_value::JsonValue; + +/// serde_json's default recursion limit — the depth at which decode +/// must fail loud and typed. +const RECURSION_LIMIT: usize = 128; + +/// The representative typed payload for the `payload_as` side: a +/// struct in the shape consumers actually construct, covering +/// string/int/vec/option/map fields. +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +struct TestJobPayload { + queue: String, + attempt: i64, + tags: Vec, + note: Option, + meta: BTreeMap, +} + +fn test_payload_batteries() -> Vec { + vec![ + TestJobPayload { + queue: "orders".to_owned(), + attempt: 3, + tags: vec!["alpha".to_owned(), "beta".to_owned()], + note: Some("queued by the bridge".to_owned()), + meta: BTreeMap::from([ + ("source".to_owned(), json!("outbox")), + ("count".to_owned(), json!(7)), + ]), + }, + TestJobPayload { + queue: String::new(), + attempt: i64::MIN, + tags: Vec::new(), + note: None, + meta: BTreeMap::new(), + }, + TestJobPayload { + queue: "unicode-é-😀".to_owned(), + attempt: i64::MAX, + tags: vec!["tab\tquote\"slash\\/".to_owned()], + note: Some(String::new()), + meta: BTreeMap::from([("nested".to_owned(), json!([1, null, true]))]), + }, + ] +} + +pub fn fuzz_payload_codec(data: &[u8]) { + // The baseline: no panic on any byte sequence, and every decode + // failure across the input space is the typed `Error::Codec` — + // over `Value` and over representative typed targets alike. + assert_decode_partition::(data); + assert_decode_partition::(data); + assert_decode_partition::(data); + assert_decode_partition::>(data); + + // A successfully-decoded `Value` re-encodes byte-stably: the Value + // round-trip closes over the raw input, with serde_json's + // canonicalization (duplicate-key last-write-wins, number-to-NormalizedNumber, + // key ordering) pinned — not re-derived, just not regressed. + if let Ok(v) = payload_as::(data) { + let bytes = encode_payload(&v).expect("a decoded `Value` must re-encode"); + let back: Value = payload_as(&bytes).expect("the encoded `Value` must decode"); + assert_eq!(back, v, "the `Value` round-trip must close over raw input"); + } + + assert_deep_input_loudness(); + assert_empty_byte_store_loudness(); + assert_value_round_trip_battery(); + assert_typed_round_trip_battery(); + assert_arbitrary_value_round_trip(data); +} + +fn assert_decode_partition(data: &[u8]) { + match payload_as::(data) { + Ok(_) | Err(Error::Codec(_)) => {} + Err(other) => panic!("the decode failure must be `Error::Codec`, got {other:?}"), + } +} + +/// Deep inputs decode loud and typed: past serde_json's recursion +/// limit, deserialization fails with `Error::Codec` — never a stack +/// overflow, never an untyped panic. The encode side handles deep +/// (but sub-limit) data as the normal round-trip. +fn assert_deep_input_loudness() { + for depth in [RECURSION_LIMIT * 4, 4096] { + let deep_bytes = nested_array_bytes(depth); + match payload_as::(&deep_bytes) { + Err(Error::Codec(_)) => {} + Err(other) => { + panic!("deep deserialization failure must be `Error::Codec`, got {other:?}") + } + Ok(_) => panic!("nesting at depth {depth} must hit serde_json's recursion limit"), + } + match payload_as::(&deep_bytes) { + Err(Error::Codec(_)) => {} + Err(other) => { + panic!("deep typed deserialization must be `Error::Codec`, got {other:?}") + } + Ok(_) => panic!("deep bytes must not decode to the typed target at depth {depth}"), + } + let deep_value = nest_value(Value::Null, RECURSION_LIMIT + 1); + let deep_encoded = + encode_payload(&deep_value).expect("a sub-limit-depth `Value` must encode"); + match payload_as::(&deep_encoded) { + Err(Error::Codec(_)) => {} + Err(other) => { + panic!("the stored deep form must decode as typed `Codec`, got {other:?}") + } + Ok(_) => { + panic!("stored bytes nested past the decode limit must decode loud, not silent") + } + } + } + + let shallow_bytes = nested_array_bytes(8); + let shallow_value = nest_value(Value::from(0u8), 8); + let shallow_encoded = encode_payload(&shallow_value).expect("a shallow `Value` must encode"); + let back: Value = payload_as(&shallow_encoded).expect("the shallow form must decode"); + let shallow_parsed: Value = payload_as(&shallow_bytes).expect("the shallow doc must decode"); + assert_eq!(back, shallow_value, "the shallow `Value` round-trip holds"); + assert_eq!(shallow_parsed, shallow_value, "nesting shape is preserved"); +} + +fn assert_empty_byte_store_loudness() { + match payload_as::(b"") { + Err(Error::Codec(_)) => {} + Err(other) => { + panic!("the empty-byte-store failure must be `Codec`, got {other:?}") + } + Ok(_) => panic!("the empty-byte store must never decode to a silent `Null` (ADR-023 §1)"), + } +} + +fn assert_value_round_trip_battery() { + for v in value_battery() { + let bytes = encode_payload(&v).expect( + "encode_payload is only type-theoretically fallible; `Value` variants all serialize", + ); + let back: Value = payload_as(&bytes).expect("the encoded battery `Value` must decode"); + assert_eq!(back, v, "the `Value` round-trip must be exact"); + } +} + +fn assert_typed_round_trip_battery() { + for payload in test_payload_batteries() { + assert_typed_round_trip(&payload); + } + assert_typed_round_trip(&String::from("hello")); + assert_typed_round_trip(&String::new()); + assert_typed_round_trip(&String::from("unicode é 😀")); + assert_typed_round_trip(&42i64); + assert_typed_round_trip(&i64::MAX); + assert_typed_round_trip(&i64::MIN); + assert_typed_round_trip(&true); + assert_typed_round_trip(&()); + assert_typed_round_trip(&Option::::None); + assert_typed_round_trip(&Some(String::from("some"))); + assert_typed_round_trip(&vec![1i64, -2, 3]); + assert_typed_round_trip(&Vec::::new()); + assert_typed_round_trip(&BTreeMap::from([ + (String::from("a"), String::from("1")), + (String::from("b"), String::from("2")), + ])); +} + +fn assert_typed_round_trip(payload: &T) +where + T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + std::fmt::Debug, +{ + let value = + serde_json::to_value(payload).expect("the battery payload must serialize to a `Value`"); + let bytes = encode_payload(&value).expect("the battery `Value` must encode"); + let back: T = match payload_as(&bytes) { + Ok(payload) => payload, + Err(other) => panic!("the typed round-trip decode holds, got {other:?}"), + }; + assert_eq!(&back, payload, "the typed round-trip must be exact"); +} + +fn assert_arbitrary_value_round_trip(data: &[u8]) { + let mut u = Unstructured::new(data); + for _ in 0..2 { + let Ok(jv) = JsonValue::arbitrary(&mut u) else { + return; + }; + let v: Value = jv.into(); + let bytes = encode_payload(&v).expect("any arbitrary-derived `Value` must encode"); + let back: Value = payload_as(&bytes).expect("the encoded arbitrary `Value` must decode"); + assert_eq!( + back, v, + "the `Value` round-trip must hold for every arbitrary `Value`" + ); + match payload_as::(&bytes) { + Ok(typed) => { + let retrip = serde_json::to_value(&typed) + .expect("a decoded typed payload must re-serialize"); + let bytes2 = + encode_payload(&retrip).expect("the re-serialized typed payload must encode"); + let back: TestJobPayload = + payload_as(&bytes2).expect("the typed re-encoded form must decode"); + assert_eq!(back, typed, "the typed round-trip is stable"); + } + Err(Error::Codec(_)) => {} + Err(other) => { + panic!("the typed decode of arbitrary `Value` bytes must be `Codec`, got {other:?}") + } + } + } +} + +fn value_battery() -> Vec { + vec![ + Value::Null, + json!(true), + json!(false), + json!(0), + json!(-1), + json!(i64::MIN), + json!(i64::MAX), + Value::from(u64::MAX), + json!(1.5), + json!(-2.25), + json!(1e10), + json!(""), + json!("hello world"), + json!("unicode é 😀"), + json!("tab\tnewline\nquote\"slash\\/"), + json!("null"), + Value::Array(vec![]), + json!([1, "two", null, true, {"three": 3}, []]), + Value::Object(Map::new()), + json!({"a": 1, "nested": {"deep": [true, null, 1.5]}}), + json!({"unicode-é-key": "value"}), + ] +} + +fn nested_array_bytes(depth: usize) -> Vec { + let mut s = String::with_capacity(depth * 2 + 1); + s.push_str(&"[".repeat(depth)); + s.push('0'); + s.push_str(&"]".repeat(depth)); + s.into_bytes() +} + +fn nest_value(inner: Value, depth: usize) -> Value { + let mut v = inner; + for _ in 0..depth { + v = Value::Array(vec![v]); + } + v +} + +#[cfg(test)] +mod corpus_replay { + use super::*; + use std::path::PathBuf; + + #[test] + fn committed_corpus_replays_through_the_invariants() { + let corpus = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../corpus/payload_codec"); + let mut count = 0usize; + for entry in std::fs::read_dir(&corpus).expect("corpus directory is committed") { + let path = entry.expect("corpus entry readable").path(); + let data = std::fs::read(&path).expect("corpus entry readable"); + fuzz_payload_codec(&data); + count += 1; + } + assert!( + count >= 64, + "committed seed corpus is present, found {count}" + ); + } + + #[test] + fn invariants_hold_without_corpus() { + fuzz_payload_codec(b""); + fuzz_payload_codec(b"null"); + fuzz_payload_codec(&nested_array_bytes(RECURSION_LIMIT + 1)); + } +} diff --git a/tasks/fuzz-target-payload-codec.md b/tasks/fuzz-target-payload-codec.md index 897ab74..b1d4feb 100644 --- a/tasks/fuzz-target-payload-codec.md +++ b/tasks/fuzz-target-payload-codec.md @@ -1,7 +1,7 @@ --- id: fuzz-target-payload-codec name: Fuzz target — `payload_codec` (core payload encode/decode invariants) -status: pending +status: completed depends_on: [fuzz-scaffold] scope: moderate risk: low @@ -54,19 +54,19 @@ replay. ## Acceptance Criteria -- [ ] `fuzz_targets/payload_codec.rs` + `shared/src/payload_codec.rs` +- [x] `fuzz_targets/payload_codec.rs` + `shared/src/payload_codec.rs` exist; `cargo fuzz build` builds the target (nightly, ASAN) -- [ ] All five §3.1 invariants implemented in `shared` and exercised by +- [x] All five §3.1 invariants implemented in `shared` and exercised by both the fuzz path and the `#[cfg(test)]` replay module -- [ ] Seed corpus committed (`fuzz/corpus/payload_codec/`), generated +- [x] Seed corpus committed (`fuzz/corpus/payload_codec/`), generated by `python3 fuzz/gen_fuzz_seeds.py` (deterministic — re-running is a no-op diff); gitignore negation in place -- [ ] `cargo test --manifest-path fuzz/shared/Cargo.toml` green +- [x] `cargo test --manifest-path fuzz/shared/Cargo.toml` green (replays the committed corpus through the invariants) -- [ ] `shared` clippy/fmt gates green +- [x] `shared` clippy/fmt gates green (`cargo clippy --manifest-path fuzz/shared/Cargo.toml --all-targets -- -D warnings`, `fmt --check`) -- [ ] Root workspace gates still green +- [x] Root workspace gates still green ## References @@ -81,8 +81,70 @@ replay. ## Notes -> To be filled by implementation agent +- **serde added to `shared`'s manifest** with `derive` (beyond the + spec's manifest list of `alkstore`/`serde_json`/`arbitrary`): the + typed round-trip needs a representative *struct* payload + (`TestJobPayload` — string/int/vec/option/map fields, the consumer + payload shape), and `#[derive(Serialize, Deserialize)]` requires the + direct dep for the bounds. `serde_json` re-exports nothing derive-able; + core already depends on serde transitively. +- **The typed-failure partition is exercised four ways**: over `Value`, + `TestJobPayload`, `String`, and `Vec` decodes of the raw + input — each failure must be `Error::Codec` (the ADR-023 §1 pin), + each success is then driven back through `encode_payload` → + `payload_as::` for input-closure Value round-trip + (canonicalization is serde_json's: duplicate-key last-write-wins + etc., pinned-not-regressed, not re-derived). +- **Deep-input loudness probes**: raw nested-array strings at 4x and + past-4096 depth decode → `Err(Codec)` (both `Value` and typed); + a constructed `Value` nested one past the 128 limit encodes fine + (the serializer's recursion is unbounded but shallow here) and its + stored bytes decode → `Err(Codec)` — the stored-deep-form loudness + the ADR-023 §1 posture wants. Encode is deliberately NOT probed at + extreme depth (serializer recursion would overflow at absurd + depths); 129 + shallow-8 form the pair. serde_json's 128 limit is + pinned as `RECURSION_LIMIT`; a future serde_json bump failing these + probes is the intended loud signal, not a fragility. +- **`arbitrary` path** runs `Unstructured::new(data)` → up to two + `JsonValue`s from the same bytes (exhaustion → skip, the raw path + already covers it): encode Ok, decode == v, plus a typed-stability + check for arbitrary values that happen to decode as `TestJobPayload`. +- **Placeholder target removed** per the scaffold's lifecycle note — + `payload_codec`'s `[[bin]]` replaces it; the two remaining wave-1 + target tasks still add their own bins. +- **Seeds came out at 97** (spec list expanded: per-prefix truncations + of two docs, depth probes at 8/127/128/129/256/1024 for arrays and + 8/200 for objects, plus the loud-fail shapes NaN/Infinity/+1/01/.5/ + 1./--1/lone-key/missing-value). Replay-floor set at ≥ 64. +- One behavior surfaced by the corpus: `payload_as::` of + deep/sub-limit vs shallow shapes needed the round-trip battery's + constructed `Value` to match the probe doc's leaf (`0`, not `Null`) + — fixed during implementation; the final replay is green. ## Summary -> To be filled on completion \ No newline at end of file +Landed the §3.1 `payload_codec` fuzz target: `fuzz_targets/payload_codec.rs` +(the thin `fuzz_target!` wrapper, replacing the scaffold placeholder's +`[[bin]]`) and `fuzz/shared/src/payload_codec.rs` implementing all five +§3.1 invariants — no-panic baseline via the four-way typed decode +partition (`Value` / `TestJobPayload` / `String` / `Vec`), +deep-input loudness at serde_json's recursion limit (raw-byte probes +and the stored-deep-form probe), empty-byte-store loudness (the ADR-023 +§1 corruption note), the `Value` round-trip (fixed battery + raw-input +closure + arbitrary `JsonValue`s from the bounded-depth helper), and +the typed round-trip over a representative payload set (derived struct ++ std types). 97 deterministic seeds committed under +`fuzz/corpus/payload_codec/` (generated by `gen_fuzz_seeds.py`'s new +`payload_codec_seeds()`, re-run is a no-op), with the `.gitignore` +negation and the README targets-table row. `fuzz/shared/Cargo.toml` +gained `serde` (derive) — no other manifest changes; `fuzz/Cargo.lock` +updated. + +Verified: `cargo test --manifest-path fuzz/shared/Cargo.toml` green +(corpus replay 97/97 + invariant unit probes); shared clippy +`-D warnings` + `fmt --check` green; `cargo fuzz build` green from +`fuzz/` (nightly/ASAN binary at +`target/x86_64-unknown-linux-gnu/release/payload_codec`); root +workspace `cargo build` / `cargo test` (all suites pass) / clippy +`-D warnings` / `fmt --check` green. Campaign flags remain the +campaigns-and-gate task's concern. \ No newline at end of file