1mod value;
4pub(crate) use value::read_into;
5
6use crate::Session;
7use crate::arena::{Arena, Children, Integer, Name, NodeId};
8use crate::byte_machine::{Decoder, Step};
9use crate::bytes::{Form, is_space};
10use crate::error::{Error, ErrorKind, Limit, ReadFailure, Syntax};
11use crate::object::Value;
12use crate::range::{RangeReader, RangeSource};
13use crate::source::{Location, Source};
14use structured_asn1::memory::{OwnedVec, Work};
15
16#[derive(Clone, Copy)]
17enum Container {
18 Array,
19 Dictionary,
20}
21
22pub(crate) enum NumberKind {
23 Integer,
24 Real { fractional: bool },
25}
26
27#[derive(Clone, Copy)]
28struct Frame {
29 node: NodeId,
30 kind: Container,
31 start: u64,
32 children: Children,
33}
34
35pub async fn read<'s, S: RangeSource, W: Work>(
40 source: &S,
41 session: &'s Session,
42 operation: &W,
43 offset: u64,
44) -> Result<Value<'s, S::Document, S::Generation>, ReadFailure<S::Error>> {
45 let reader = RangeReader::new(source, session, operation)?;
46 let stamp = reader.stamp();
47 if offset > stamp.length {
48 return Err(Error {
49 kind: ErrorKind::Foreign,
50 location: location(0, stamp.length),
51 }
52 .into());
53 }
54 let work = reader.execution();
55 let mut cursor = Cursor { reader, at: offset };
56 let (arena, root) = read_into(&mut cursor, session, Arena::new(&work).into_owned()).await?;
57 Ok(Value {
58 arena,
59 root,
60 session,
61 stamp,
62 end: cursor.at,
63 })
64}
65
66pub(crate) struct Cursor<'q, S: RangeSource> {
67 pub(crate) reader: RangeReader<'q, S>,
68 pub(crate) at: u64,
69}
70
71impl<S: RangeSource> Cursor<'_, S> {
72 pub(crate) fn location(&self, start: u64, length: u64) -> Location {
73 self.reader.location(start, length)
74 }
75
76 pub(crate) fn failure(&self, code: Syntax, at: u64) -> ReadFailure<S::Error> {
77 Error {
78 kind: ErrorKind::Syntax(code),
79 location: self.location(at, 0),
80 }
81 .into()
82 }
83
84 pub(crate) async fn peek(&mut self) -> Result<Option<u8>, ReadFailure<S::Error>> {
85 Ok(self.reader.byte_at(self.at).await?)
86 }
87
88 pub(crate) async fn take(&mut self) -> Result<Option<u8>, ReadFailure<S::Error>> {
89 let byte = self.peek().await?;
90 if byte.is_some() {
91 self.at += 1;
92 }
93 Ok(byte)
94 }
95
96 pub(crate) async fn skip(&mut self) -> Result<(), ReadFailure<S::Error>> {
97 loop {
98 let Some(byte) = self.peek().await? else {
99 return Ok(());
100 };
101 if is_space(byte) {
102 self.at += 1;
103 continue;
104 }
105 if byte != b'%' {
106 return Ok(());
107 }
108 self.at += 1;
109 let mut terminated = false;
110 while let Some(byte) = self.take().await? {
111 if byte == b'\r' || byte == b'\n' {
112 terminated = true;
113 break;
114 }
115 }
116 if !terminated && self.at < self.reader.stamp().length {
117 return Err(self.failure(Syntax::End, self.at));
118 }
119 }
120 }
121
122 pub(crate) async fn keyword(&mut self, expected: &[u8]) -> Result<(), ReadFailure<S::Error>> {
123 let start = self.at;
124 for &byte in expected {
125 if self.take().await? != Some(byte) {
126 return Err(self.failure(Syntax::Token, start));
127 }
128 }
129 if let Some(next) = self.peek().await?
130 && !boundary(next)
131 {
132 return Err(self.failure(Syntax::Token, self.at));
133 }
134 Ok(())
135 }
136
137 pub(crate) async fn looking(&mut self, expected: &[u8]) -> Result<bool, ReadFailure<S::Error>> {
138 let start = self.at;
139 for (index, &byte) in expected.iter().enumerate() {
140 let Some(at) = start.checked_add(index as u64) else {
141 return Ok(false);
142 };
143 if self.reader.byte_at(at).await? != Some(byte) {
144 return Ok(false);
145 }
146 }
147 Ok(true)
148 }
149
150 pub(crate) async fn natural(&mut self) -> Result<u64, ReadFailure<S::Error>> {
151 let at = self.at;
152 let (integer, real) = self.number().await?;
153 if !matches!(real, NumberKind::Integer) || integer.negative {
154 return Err(self.failure(Syntax::Number, at));
155 }
156 integer.magnitude.ok_or_else(|| {
157 Error {
158 kind: ErrorKind::Unsupported(crate::error::Unsupported::NumericRange),
159 location: self.location(at, self.at - at),
160 }
161 .into()
162 })
163 }
164
165 pub(crate) async fn space(&mut self) -> Result<(), ReadFailure<S::Error>> {
166 while self.peek().await?.is_some_and(is_space) {
167 self.at += 1;
168 }
169 Ok(())
170 }
171
172 async fn name<W: Work>(
173 &mut self,
174 names: &mut OwnedVec<u8, W>,
175 ) -> Result<Name, ReadFailure<S::Error>> {
176 let start = names.len();
177 self.at += 1; let mut decoder = Decoder::new(Form::Name);
179 loop {
180 let input = match self.peek().await? {
181 Some(byte) if !boundary(byte) => Some(byte),
182 _ => None,
183 };
184 match decoder.step(input) {
185 Step::More => {
186 debug_assert!(input.is_some());
187 self.at += 1;
188 }
189 Step::Byte { value, consumed } => {
190 if consumed {
191 self.at += 1;
192 }
193 names
194 .try_push(value)
195 .map_err(|cause| refused(cause, self.location(self.at, 0)))?;
196 }
197 Step::End => break,
198 Step::Malformed => return Err(self.failure(Syntax::Name, self.at)),
199 }
200 }
201 Ok(Name {
202 start,
203 length: names.len() - start,
204 })
205 }
206
207 async fn literal(
208 &mut self,
209 session: &Session,
210 outer_depth: u64,
211 ) -> Result<(), ReadFailure<S::Error>> {
212 let start = self.at;
213 self.at += 1;
214 let mut depth = 1;
215 let mut escaped = false;
216 check_depth(session, outer_depth + depth, self.location(start, 1))?;
217 while let Some(byte) = self.take().await? {
218 if escaped {
219 escaped = false;
220 continue;
221 }
222 match byte {
223 b'\\' => escaped = true,
224 b'(' => {
225 depth += 1;
226 check_depth(session, outer_depth + depth, self.location(self.at - 1, 1))?;
227 }
228 b')' => {
229 depth -= 1;
230 if depth == 0 {
231 return Ok(());
232 }
233 }
234 _ => {}
235 }
236 }
237 Err(self.failure(Syntax::String, self.at))
238 }
239
240 async fn hexadecimal(&mut self) -> Result<(), ReadFailure<S::Error>> {
241 let mut decoder = Decoder::new(Form::Hexadecimal);
242 loop {
243 let Some(byte) = self.take().await? else {
244 return Err(self.failure(Syntax::String, self.at));
245 };
246 if byte == b'>' {
247 match decoder.step(None) {
248 Step::End | Step::Byte { .. } => return Ok(()),
249 _ => return Err(self.failure(Syntax::String, self.at - 1)),
250 }
251 }
252 if matches!(decoder.step(Some(byte)), Step::Malformed) {
253 return Err(self.failure(Syntax::String, self.at - 1));
254 }
255 }
256 }
257
258 pub(crate) async fn number(&mut self) -> Result<(Integer, NumberKind), ReadFailure<S::Error>> {
259 let start = self.at;
260 let negative = self.peek().await? == Some(b'-');
261 if matches!(self.peek().await?, Some(b'+' | b'-')) {
262 self.at += 1;
263 }
264 let mut magnitude = Some(0_u64);
265 let mut real = false;
266 let mut fractional = false;
267 let mut digits = 0_u64;
268 while let Some(byte) = self.peek().await? {
269 if byte.is_ascii_digit() {
270 if real {
271 fractional |= byte != b'0';
272 } else {
273 magnitude = magnitude.and_then(|value| {
274 value
275 .checked_mul(10)
276 .and_then(|value| value.checked_add(u64::from(byte - b'0')))
277 });
278 }
279 digits += 1;
280 self.at += 1;
281 continue;
282 }
283 if byte == b'.' && !real {
284 real = true;
285 self.at += 1;
286 continue;
287 }
288 if boundary(byte) {
289 break;
290 }
291 return Err(self.failure(Syntax::Number, self.at));
292 }
293 if digits == 0 {
294 return Err(self.failure(Syntax::Number, start));
295 }
296 Ok((
297 Integer {
298 negative,
299 magnitude,
300 },
301 if real {
302 NumberKind::Real { fractional }
303 } else {
304 NumberKind::Integer
305 },
306 ))
307 }
308
309 async fn reference(
310 &mut self,
311 first: Integer,
312 ) -> Result<Option<(u64, u16)>, ReadFailure<S::Error>> {
313 let after_first = self.at;
314 self.skip().await?;
315 if self.at == after_first || !matches!(self.peek().await?, Some(b'0'..=b'9')) {
316 return Ok(None);
317 }
318 let generation = match self.number().await {
319 Ok((integer, NumberKind::Integer)) => integer,
320 Ok(_) => return Ok(None),
321 Err(ReadFailure::Format(error)) if error.kind == ErrorKind::Syntax(Syntax::Number) => {
325 return Ok(None);
326 }
327 Err(error) => return Err(error),
328 };
329 let after_generation = self.at;
330 self.skip().await?;
331 if self.at == after_generation || self.peek().await? != Some(b'R') {
332 return Ok(None);
333 }
334 self.at += 1;
335 if let Some(next) = self.peek().await?
336 && !boundary(next)
337 {
338 return Ok(None);
339 }
340 let (Some(number), Some(generation)) = (first.magnitude, generation.magnitude) else {
341 return Err(Error {
342 kind: ErrorKind::Unsupported(crate::error::Unsupported::NumericRange),
343 location: self.location(after_first, self.at - after_first),
344 }
345 .into());
346 };
347 let generation =
348 u16::try_from(generation).map_err(|_| self.failure(Syntax::Object, after_first))?;
349 Ok(Some((number, generation)))
350 }
351}
352
353fn boundary(byte: u8) -> bool {
354 is_space(byte)
355 || matches!(
356 byte,
357 b'(' | b')' | b'<' | b'>' | b'[' | b']' | b'{' | b'}' | b'/' | b'%'
358 )
359}
360
361fn location(start: u64, length: u64) -> Location {
362 Location::new(Source::File, start, length).expect("bounded original object range")
363}
364
365fn refused(cause: structured_asn1::memory::MemoryError, location: Location) -> Error {
366 Error {
367 kind: ErrorKind::Resource(cause),
368 location,
369 }
370}
371
372fn check_depth(session: &Session, depth: u64, location: Location) -> crate::Result<()> {
373 if depth > u64::from(session.limits().processing.max_depth) {
374 return Err(Error {
375 kind: ErrorKind::Limit(Limit::Depth),
376 location,
377 });
378 }
379 Ok(())
380}