uqa_analysis/descriptor/
limits.rs1use std::io::{self, Write};
10
11use serde::Serialize;
12
13use crate::{AnalysisError, AnalysisResult};
14
15#[derive(Debug, Clone, Copy)]
16pub struct AnalyzerLimits {
17 pub max_descriptor_bytes: usize,
18 pub max_stages: usize,
19 pub max_cached_analyzers: usize,
20 pub max_cached_descriptor_bytes: usize,
21}
22
23impl Default for AnalyzerLimits {
24 fn default() -> Self {
25 Self {
26 max_descriptor_bytes: 16 * 1024 * 1024,
27 max_stages: 256,
28 max_cached_analyzers: 128,
29 max_cached_descriptor_bytes: 8 * 1024 * 1024,
30 }
31 }
32}
33
34pub(crate) fn check_limit(
35 resource: &'static str,
36 required: usize,
37 limit: usize,
38) -> AnalysisResult<()> {
39 if required > limit {
40 return Err(AnalysisError::ResourceLimit {
41 resource,
42 required,
43 limit,
44 });
45 }
46 Ok(())
47}
48
49struct BoundedWriter {
50 bytes: Vec<u8>,
51 length: usize,
52 maximum: usize,
53 retain: bool,
54 exceeded: Option<usize>,
55}
56
57impl Write for BoundedWriter {
58 fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
59 let required = self
60 .length
61 .checked_add(bytes.len())
62 .ok_or_else(|| io::Error::other("analyzer size overflow"))?;
63 if required > self.maximum {
64 self.exceeded = Some(required);
65 return Err(io::Error::other("analyzer descriptor exceeds its limit"));
66 }
67 if self.retain {
68 self.bytes.extend_from_slice(bytes);
69 }
70 self.length = required;
71 Ok(bytes.len())
72 }
73 fn flush(&mut self) -> io::Result<()> {
74 Ok(())
75 }
76}
77
78pub(super) fn encode(
79 value: &impl Serialize,
80 maximum: usize,
81 retain: bool,
82) -> AnalysisResult<Vec<u8>> {
83 let mut writer = BoundedWriter {
84 bytes: Vec::new(),
85 length: 0,
86 maximum,
87 retain,
88 exceeded: None,
89 };
90 let result = serde_json::to_writer(&mut writer, value);
91 if let Some(required) = writer.exceeded {
92 return Err(AnalysisError::ResourceLimit {
93 resource: "analyzer descriptor bytes",
94 required,
95 limit: maximum,
96 });
97 }
98 result?;
99 Ok(writer.bytes)
100}