From 531a21af353001ed521a706aa28f33e2bb15a70c Mon Sep 17 00:00:00 2001 From: Aaron Blankstein Date: Wed, 3 Feb 2021 15:57:01 -0600 Subject: [PATCH 1/2] fix: use stacker for serde_json deserializer --- Cargo.lock | 33 +++++++++++++++++++++++++++++++++ Cargo.toml | 3 ++- src/vm/database/structures.rs | 8 +++++++- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7f2dc67d..66940ffec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,6 +270,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "serde_stacker", "sha2 0.8.2", "sha2-asm", "sha3", @@ -1676,6 +1677,15 @@ version = "2.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d883f78645c21b7281d21305181aa1f4dd9e9363e7cf2566c93121552cff003e" +[[package]] +name = "psm" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3abf49e5417290756acfd26501536358560c4a5cc4a0934d390939acb3e7083a" +dependencies = [ + "cc", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -2201,6 +2211,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_stacker" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c92391a63e3b83f77334d8beaaf11bac4c900f3769483e543bf76a81bf8ee2" +dependencies = [ + "serde", + "stacker", +] + [[package]] name = "serde_urlencoded" version = "0.6.1" @@ -2351,6 +2371,19 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "stacker" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f47e840d001df3b785fbc3b84c7228519bdf63d4fb61b9e9f50f7fa153ce10" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "libc", + "psm", + "winapi 0.3.9", +] + [[package]] name = "stacks-node" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 1db44ac29..fdaf56db6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ rand = "=0.7.2" rand_chacha = "=0.2.2" serde = "1" serde_derive = "1" +serde_stacker = "0.1" sha3 = "0.8.2" ripemd160 = "0.8.0" regex = "1" @@ -66,7 +67,7 @@ libc = "0.2.82" [dependencies.serde_json] version = "1.0" -features = ["arbitrary_precision"] +features = ["arbitrary_precision", "unbounded_depth"] [dependencies.secp256k1] version = "0.19.0" diff --git a/src/vm/database/structures.rs b/src/vm/database/structures.rs index 2cea35514..06f7f3486 100644 --- a/src/vm/database/structures.rs +++ b/src/vm/database/structures.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use serde::Deserialize; use std::convert::TryInto; use std::io::Write; use util::hash::{hex_bytes, to_hex}; @@ -51,7 +52,12 @@ macro_rules! clarity_serializable { } impl ClarityDeserializable<$Name> for $Name { fn deserialize(json: &str) -> Self { - serde_json::from_str(json).expect("Failed to serialize vm.Value") + let mut deserializer = serde_json::Deserializer::from_str(&json); + // serde's default 128 depth limit can be exhausted + // by a 64-stack-depth AST, so disable the recursion limit + deserializer.disable_recursion_limit(); + let deserializer = serde_stacker::Deserializer::new(&mut deserializer); + Deserialize::deserialize(deserializer).expect("Failed to deserialize vm.Value") } } }; From 1b79f8f25cbff6ad8ddc15842cbc0e2206f59ad9 Mon Sep 17 00:00:00 2001 From: Aaron Blankstein Date: Wed, 3 Feb 2021 15:58:22 -0600 Subject: [PATCH 2/2] add comment on stacker --- src/vm/database/structures.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vm/database/structures.rs b/src/vm/database/structures.rs index 06f7f3486..8b3b84c23 100644 --- a/src/vm/database/structures.rs +++ b/src/vm/database/structures.rs @@ -56,6 +56,8 @@ macro_rules! clarity_serializable { // serde's default 128 depth limit can be exhausted // by a 64-stack-depth AST, so disable the recursion limit deserializer.disable_recursion_limit(); + // use stacker to prevent the deserializer from overflowing. + // this will instead spill to the heap let deserializer = serde_stacker::Deserializer::new(&mut deserializer); Deserialize::deserialize(deserializer).expect("Failed to deserialize vm.Value") }