netget/server/gnmi/
json.rs1use serde::de::{DeserializeSeed, MapAccess, SeqAccess, Visitor};
3use serde_json::{Map, Number, Value};
4use tonic::Status;
5pub fn parse(bytes: &[u8]) -> Result<Value, Status> {
6 parse_with_budget(bytes, &mut 0)
7}
8pub(super) fn parse_with_budget(bytes: &[u8], nodes: &mut usize) -> Result<Value, Status> {
9 if bytes.len() > super::codec::MAX_VALUE_BYTES {
10 return Err(Status::resource_exhausted("gNMI JSON value exceeds 64 KiB"));
11 }
12 let mut decoder = serde_json::Deserializer::from_slice(bytes);
13 let mut deepest = 0usize;
14 let value = Seed {
15 nodes,
16 depth: 0,
17 deepest: &mut deepest,
18 }
19 .deserialize(&mut decoder)
20 .map_err(|_| {
21 if *nodes > super::codec::MAX_NODES || deepest > super::codec::MAX_DEPTH {
22 Status::resource_exhausted("gNMI JSON node/depth bound")
23 } else {
24 Status::invalid_argument("invalid gNMI JSON or text/key bound")
25 }
26 })?;
27 decoder
28 .end()
29 .map_err(|_| Status::invalid_argument("trailing JSON value"))?;
30 Ok(value)
31}
32struct Seed<'a> {
33 nodes: &'a mut usize,
34 depth: usize,
35 deepest: &'a mut usize,
36}
37impl<'de> DeserializeSeed<'de> for Seed<'_> {
38 type Value = Value;
39 fn deserialize<D: serde::Deserializer<'de>>(self, decoder: D) -> Result<Value, D::Error> {
40 *self.nodes += 1;
41 *self.deepest = (*self.deepest).max(self.depth);
42 if *self.nodes > super::codec::MAX_NODES || self.depth > super::codec::MAX_DEPTH {
43 return Err(serde::de::Error::custom("JSON node/depth bound"));
44 }
45 decoder.deserialize_any(self)
46 }
47}
48impl<'de> Visitor<'de> for Seed<'_> {
49 type Value = Value;
50 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
51 f.write_str("bounded JSON value")
52 }
53 fn visit_unit<E: serde::de::Error>(self) -> Result<Value, E> {
54 Ok(Value::Null)
55 }
56 fn visit_bool<E: serde::de::Error>(self, v: bool) -> Result<Value, E> {
57 Ok(Value::Bool(v))
58 }
59 fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<Value, E> {
60 Ok(v.into())
61 }
62 fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<Value, E> {
63 Ok(v.into())
64 }
65 fn visit_f64<E: serde::de::Error>(self, v: f64) -> Result<Value, E> {
66 Number::from_f64(v)
67 .map(Value::Number)
68 .ok_or_else(|| E::custom("nonfinite JSON number"))
69 }
70 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Value, E> {
71 if v.len() > super::codec::MAX_VALUE_BYTES {
72 return Err(E::custom("JSON text bound"));
73 }
74 Ok(Value::String(v.into()))
75 }
76 fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Value, E> {
77 self.visit_str(&v)
78 }
79 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Value, A::Error> {
80 let mut result = Vec::new();
81 while let Some(v) = seq.next_element_seed(Seed {
82 nodes: self.nodes,
83 depth: self.depth + 1,
84 deepest: self.deepest,
85 })? {
86 result.push(v);
87 }
88 Ok(Value::Array(result))
89 }
90 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Value, A::Error> {
91 let mut result = Map::new();
92 while let Some(key) = map.next_key::<String>()? {
93 if key.len() > 256 || result.contains_key(&key) {
94 return Err(serde::de::Error::custom("JSON key bound or duplicate"));
95 }
96 *self.nodes += 1;
97 if *self.nodes > super::codec::MAX_NODES {
98 return Err(serde::de::Error::custom("JSON node bound"));
99 }
100 let value = map.next_value_seed(Seed {
101 nodes: self.nodes,
102 depth: self.depth + 1,
103 deepest: self.deepest,
104 })?;
105 result.insert(key, value);
106 }
107 Ok(Value::Object(result))
108 }
109}