1#![crate_type = "dylib"]
2#![deny(clippy::correctness, clippy::perf, clippy::style, clippy::suspicious)]
3#![allow(unused)]
4#![allow(non_camel_case_types)]
5#![allow(non_snake_case)]
6#![allow(non_upper_case_globals)]
7#![allow(unsafe_op_in_unsafe_fn)] use std::alloc::Layout;
10use std::ptr::null;
11use std::slice;
12
13include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
14
15#[cfg(feature = "dynamic")]
16mod dylib;
17#[cfg(feature = "dynamic")]
18pub use dylib::*;
19
20unsafe impl Send for ddwaf_object {}
23unsafe impl Sync for ddwaf_object {}
24
25#[warn(clippy::pedantic)]
26impl ddwaf_object {
27 pub unsafe fn drop_key(&mut self) {
37 if self.parameterName.is_null() {
38 return;
39 }
40 let len =
41 usize::try_from(self.parameterNameLength).expect("key is too large for this platform");
42 let slice: &mut [u8] = unsafe {
43 std::slice::from_raw_parts_mut(self.parameterName.cast::<u8>().cast_mut(), len)
44 };
45 drop(unsafe { Box::from_raw(std::ptr::from_mut(slice)) });
46 }
47
48 pub unsafe fn drop_array(&mut self) {
59 debug_assert_eq!(self.type_, DDWAF_OBJ_ARRAY);
60 if self.nbEntries == 0 {
61 return;
62 }
63 let array = unsafe { self.__bindgen_anon_1.array };
64 let len = isize::try_from(self.nbEntries).expect("array is too large for this platform");
65 for i in 0..len {
66 let elem = unsafe { &mut *array.offset(i) };
67 unsafe { elem.drop_object() };
68 }
69 #[allow(clippy::cast_possible_truncation)] let layout = Layout::array::<ddwaf_object>(self.nbEntries as usize).unwrap();
71 unsafe { std::alloc::dealloc(array.cast(), layout) };
72 }
73
74 pub unsafe fn drop_map(&mut self) {
85 debug_assert_eq!(self.type_, DDWAF_OBJ_MAP);
86 if self.nbEntries == 0 {
87 return;
88 }
89 let array = unsafe { self.__bindgen_anon_1.array };
90 let len = isize::try_from(self.nbEntries).expect("map is too large for this platform");
91 for i in 0..len {
92 let elem = unsafe { &mut *array.offset(i) };
93 unsafe { elem.drop_key() };
94 unsafe { elem.drop_object() };
95 }
96 #[allow(clippy::cast_possible_truncation)] let layout = Layout::array::<ddwaf_object>(self.nbEntries as usize).unwrap();
98 unsafe { std::alloc::dealloc(array.cast(), layout) };
99 }
100
101 pub unsafe fn drop_object(&mut self) {
108 match self.type_ {
109 DDWAF_OBJ_STRING => unsafe { self.drop_string() },
110 DDWAF_OBJ_ARRAY => unsafe { self.drop_array() },
111 DDWAF_OBJ_MAP => unsafe { self.drop_map() },
112 _ => { }
113 }
114 }
115
116 pub unsafe fn drop_string(&mut self) {
126 debug_assert_eq!(self.type_, DDWAF_OBJ_STRING);
127 let sval = unsafe { self.__bindgen_anon_1.stringValue };
128 if sval.is_null() {
129 return;
130 }
131 let len = usize::try_from(self.nbEntries).expect("string is too large for this platform");
132 let slice: &mut [u8] = unsafe { std::slice::from_raw_parts_mut(sval as *mut _, len) };
133 drop(unsafe { Box::from_raw(slice) });
134 }
135}
136impl std::cmp::PartialEq<ddwaf_object> for ddwaf_object {
137 fn eq(&self, other: &ddwaf_object) -> bool {
138 if self.type_ != other.type_ {
139 return false;
140 }
141 match self.type_ {
142 DDWAF_OBJ_INVALID | DDWAF_OBJ_NULL => true,
143 DDWAF_OBJ_SIGNED => unsafe {
144 self.__bindgen_anon_1.intValue == other.__bindgen_anon_1.intValue
145 },
146 DDWAF_OBJ_UNSIGNED => unsafe {
147 self.__bindgen_anon_1.uintValue == other.__bindgen_anon_1.uintValue
148 },
149 DDWAF_OBJ_BOOL => unsafe {
150 self.__bindgen_anon_1.boolean == other.__bindgen_anon_1.boolean
151 },
152 DDWAF_OBJ_FLOAT => unsafe {
153 self.__bindgen_anon_1.f64_ == other.__bindgen_anon_1.f64_
155 },
156
157 DDWAF_OBJ_STRING => unsafe {
159 if self.nbEntries != other.nbEntries {
160 return false;
161 }
162 if self.nbEntries == 0 {
163 return true;
164 }
165 let len =
166 usize::try_from(self.nbEntries).expect("string is too large for this platform");
167 let left = slice::from_raw_parts(self.__bindgen_anon_1.stringValue, len);
168 let right = slice::from_raw_parts(other.__bindgen_anon_1.stringValue, len);
169 left == right
170 },
171
172 DDWAF_OBJ_ARRAY | DDWAF_OBJ_MAP => unsafe {
174 if self.nbEntries != other.nbEntries {
175 return false;
176 }
177 if self.nbEntries == 0 {
178 return true;
179 }
180
181 let left = slice::from_raw_parts(
182 self.__bindgen_anon_1.array,
183 usize::try_from(self.nbEntries)
184 .expect("array/map is too large for this platform"),
185 );
186 let right = slice::from_raw_parts(
187 other.__bindgen_anon_1.array,
188 usize::try_from(other.nbEntries)
189 .expect("array/map is too large for this platform"),
190 );
191 for (left, right) in left.iter().zip(right.iter()) {
192 if self.type_ == DDWAF_OBJ_MAP {
193 if left.parameterNameLength != right.parameterNameLength {
194 return false;
195 }
196 let len = usize::try_from(left.parameterNameLength)
197 .expect("key is too large for this platform");
198 if len > 0 {
199 let left_key = slice::from_raw_parts(left.parameterName, len);
200 let right_key = slice::from_raw_parts(right.parameterName, len);
201 if left_key != right_key {
202 return false;
203 }
204 }
205 }
206 if left != right {
207 return false;
208 }
209 }
210 true
211 },
212
213 _ => false,
214 }
215 }
216}
217impl std::fmt::Debug for ddwaf_object {
218 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
219 let mut dbg = f.debug_struct("ddwaf_object");
220 let dbg = match usize::try_from(self.parameterNameLength) {
221 Ok(0) => &mut dbg,
222 Ok(len) => {
223 let key = unsafe { slice::from_raw_parts(self.parameterName.cast(), len) };
224 let key = String::from_utf8_lossy(key);
225 dbg.field("parameterName", &key)
226 }
227 Err(_) => {
228 let key = unsafe { slice::from_raw_parts(self.parameterName.cast(), usize::MAX) };
229 let key = String::from_utf8_lossy(key);
230 dbg.field("parameterName(trunc)", &key)
231 }
232 };
233 let dbg = match self.type_ {
234 DDWAF_OBJ_BOOL => dbg
235 .field("type", &stringify!(DDWAF_OBJ_BOOL))
236 .field("boolean", unsafe { &self.__bindgen_anon_1.boolean }),
237 DDWAF_OBJ_FLOAT => dbg
238 .field("type", &stringify!(DDWAF_OBJ_FLOAT))
239 .field("f64", unsafe { &self.__bindgen_anon_1.f64_ }),
240 DDWAF_OBJ_SIGNED => dbg
241 .field("type", &stringify!(DDWAF_OBJ_SIGNED))
242 .field("int", unsafe { &self.__bindgen_anon_1.intValue }),
243 DDWAF_OBJ_UNSIGNED => dbg
244 .field("type", &stringify!(DDWAF_OBJ_UNSIGNED))
245 .field("uint", unsafe { &self.__bindgen_anon_1.uintValue }),
246 DDWAF_OBJ_STRING => {
247 let (field, len) = match usize::try_from(self.nbEntries) {
248 Ok(len) => ("string", len),
249 Err(_) => ("string(trunc)", usize::MAX),
250 };
251 let sval =
252 unsafe { slice::from_raw_parts(self.__bindgen_anon_1.stringValue.cast(), len) };
253 let sval = String::from_utf8_lossy(sval);
254 dbg.field("type", &stringify!(DDWAF_OBJ_STRING))
255 .field(field, &sval)
256 }
257 DDWAF_OBJ_ARRAY => {
258 let (field, len) = match usize::try_from(self.nbEntries) {
259 Ok(len) => ("array", len),
260 Err(_) => ("array(trunc)", usize::MAX),
261 };
262 let array: &[ddwaf_object] =
263 unsafe { slice::from_raw_parts(self.__bindgen_anon_1.array.cast(), len) };
264 dbg.field("type", &stringify!(DDWAF_OBJ_ARRAY))
265 .field(field, &array)
266 }
267 DDWAF_OBJ_MAP => {
268 let (field, len) = match usize::try_from(self.nbEntries) {
269 Ok(len) => ("map", len),
270 Err(_) => ("map(trunc)", usize::MAX),
271 };
272 let array: &[ddwaf_object] =
273 unsafe { slice::from_raw_parts(self.__bindgen_anon_1.array.cast(), len) };
274 dbg.field("type", &stringify!(DDWAF_OBJ_MAP))
275 .field(field, &array)
276 }
277 DDWAF_OBJ_NULL => dbg.field("type", &stringify!(DDWAF_OBJ_NULL)),
278 DDWAF_OBJ_INVALID => dbg.field("type", &stringify!(DDWAF_OBJ_INVALID)),
279 unknown => dbg.field("type", &unknown),
280 };
281
282 dbg.finish_non_exhaustive()
283 }
284}