1use crate::{Error, Result, number::hex_val};
2
3pub fn validate_json(input: &[u8]) -> Result<usize> {
4 let mut validator = JsonValidator {
5 bytes: input,
6 depth: 0,
7 };
8 let end = validator.parse_value(validator.skip_ws(0))?;
9 let end = validator.skip_ws(end);
10 if end == input.len() {
11 Ok(end)
12 } else {
13 Err(Error::BadTrail)
14 }
15}
16
17pub(crate) struct JsonValidator<'a> {
18 pub(crate) bytes: &'a [u8],
19 pub(crate) depth: usize,
20}
21
22impl JsonValidator<'_> {
23 const MAX_DEPTH: usize = 1024;
24
25 #[inline]
26 fn parse_value(&mut self, i: usize) -> Result<usize> {
27 if i >= self.bytes.len() {
28 return Err(Error::BadTrail);
29 }
30 match self.bytes[i] {
31 b'{' => self.parse_object(i),
32 b'[' => self.parse_array(i),
33 b'"' => self.parse_string(i),
34 b't' => self.parse_literal(i, b"true"),
35 b'f' => self.parse_literal(i, b"false"),
36 b'n' => self.parse_literal(i, b"null"),
37 b'-' | b'0'..=b'9' => self.parse_number(i),
38 _ => Err(Error::BadTrail),
39 }
40 }
41
42 fn parse_object(&mut self, mut i: usize) -> Result<usize> {
43 self.enter()?;
44 i += 1;
45 i = self.skip_ws(i);
46 if i < self.bytes.len() && self.bytes[i] == b'}' {
47 self.leave();
48 return Ok(i + 1);
49 }
50 loop {
51 if i >= self.bytes.len() || self.bytes[i] != b'"' {
52 self.leave();
53 return Err(Error::AttrStart);
54 }
55 i = self.parse_string(i)?;
56 i = self.skip_ws(i);
57 if i >= self.bytes.len() || self.bytes[i] != b':' {
58 self.leave();
59 return Err(Error::BadTrail);
60 }
61 i = self.parse_value(self.skip_ws(i + 1))?;
62 i = self.skip_ws(i);
63 if i >= self.bytes.len() {
64 self.leave();
65 return Err(Error::BadTrail);
66 }
67 match self.bytes[i] {
68 b',' => i = self.skip_ws(i + 1),
69 b'}' => {
70 self.leave();
71 return Ok(i + 1);
72 }
73 _ => {
74 self.leave();
75 return Err(Error::BadTrail);
76 }
77 }
78 }
79 }
80
81 fn parse_array(&mut self, mut i: usize) -> Result<usize> {
82 self.enter()?;
83 i += 1;
84 i = self.skip_ws(i);
85 if i < self.bytes.len() && self.bytes[i] == b']' {
86 self.leave();
87 return Ok(i + 1);
88 }
89 loop {
90 i = self.parse_value(i)?;
91 i = self.skip_ws(i);
92 if i >= self.bytes.len() {
93 self.leave();
94 return Err(Error::BadTrail);
95 }
96 match self.bytes[i] {
97 b',' => i = self.skip_ws(i + 1),
98 b']' => {
99 self.leave();
100 return Ok(i + 1);
101 }
102 _ => {
103 self.leave();
104 return Err(Error::BadTrail);
105 }
106 }
107 }
108 }
109
110 pub(crate) fn parse_string(&self, mut i: usize) -> Result<usize> {
111 i += 1;
112 let mut raw_start = i;
113 while i < self.bytes.len() {
114 match self.bytes[i] {
115 b'"' => {
116 core::str::from_utf8(&self.bytes[raw_start..i])
117 .map_err(|_| Error::BadString)?;
118 return Ok(i + 1);
119 }
120 b'\\' => {
121 core::str::from_utf8(&self.bytes[raw_start..i])
122 .map_err(|_| Error::BadString)?;
123 i += 1;
124 if i >= self.bytes.len() {
125 return Err(Error::BadString);
126 }
127 match self.bytes[i] {
128 b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {
129 i += 1;
130 }
131 b'u' => {
132 i += 1;
133 for _ in 0..4 {
134 if i >= self.bytes.len() || hex_val(self.bytes[i]).is_none() {
135 return Err(Error::BadString);
136 }
137 i += 1;
138 }
139 }
140 _ => return Err(Error::BadString),
141 }
142 raw_start = i;
143 }
144 0x00..=0x1f => return Err(Error::BadString),
145 _ => i += 1,
146 }
147 }
148 Err(Error::BadString)
149 }
150
151 #[inline]
152 fn parse_literal(&self, i: usize, literal: &[u8]) -> Result<usize> {
153 if self.bytes[i..].starts_with(literal) {
154 Ok(i + literal.len())
155 } else {
156 Err(Error::BadTrail)
157 }
158 }
159
160 pub(crate) fn parse_number(&self, mut i: usize) -> Result<usize> {
161 if i < self.bytes.len() && self.bytes[i] == b'-' {
162 i += 1;
163 }
164 if i >= self.bytes.len() {
165 return Err(Error::BadNum);
166 }
167 if self.bytes[i] == b'0' {
168 i += 1;
169 if i < self.bytes.len() && self.bytes[i].is_ascii_digit() {
170 return Err(Error::BadNum);
171 }
172 } else if self.bytes[i].is_ascii_digit() {
173 while i < self.bytes.len() && self.bytes[i].is_ascii_digit() {
174 i += 1;
175 }
176 } else {
177 return Err(Error::BadNum);
178 }
179 if i < self.bytes.len() && self.bytes[i] == b'.' {
180 i += 1;
181 let start = i;
182 while i < self.bytes.len() && self.bytes[i].is_ascii_digit() {
183 i += 1;
184 }
185 if i == start {
186 return Err(Error::BadNum);
187 }
188 }
189 if i < self.bytes.len() && matches!(self.bytes[i], b'e' | b'E') {
190 i += 1;
191 if i < self.bytes.len() && matches!(self.bytes[i], b'+' | b'-') {
192 i += 1;
193 }
194 let start = i;
195 while i < self.bytes.len() && self.bytes[i].is_ascii_digit() {
196 i += 1;
197 }
198 if i == start {
199 return Err(Error::BadNum);
200 }
201 }
202 Ok(i)
203 }
204
205 #[inline]
206 pub(crate) fn skip_ws(&self, mut i: usize) -> usize {
207 while i < self.bytes.len() && matches!(self.bytes[i], b' ' | b'\t' | b'\n' | b'\r') {
208 i += 1;
209 }
210 i
211 }
212
213 #[inline]
214 fn enter(&mut self) -> Result<()> {
215 self.depth += 1;
216 if self.depth > Self::MAX_DEPTH {
217 return Err(Error::SubTooLong);
218 }
219 Ok(())
220 }
221
222 #[inline]
223 fn leave(&mut self) {
224 self.depth -= 1;
225 }
226}