1#![cfg_attr(docsrs, feature(doc_cfg))]
68#![cfg_attr(docsrs, doc(auto_cfg(hide(docsrs))))]
69#![cfg_attr(not(test), no_std)]
72
73use core::ffi::c_void;
74use core::ffi::{c_char, c_int};
75use usize as size_t; #[allow(non_camel_case_types)]
80#[repr(C)]
82pub struct magic_set {
83 _data: [u8; 0],
84 _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
85}
86
87#[allow(non_camel_case_types)]
88pub type magic_t = *mut magic_set;
89
90pub const MAGIC_NONE: c_int = 0x000_0000;
91pub const MAGIC_DEBUG: c_int = 0x000_0001;
92pub const MAGIC_SYMLINK: c_int = 0x000_0002;
93pub const MAGIC_COMPRESS: c_int = 0x000_0004;
94pub const MAGIC_DEVICES: c_int = 0x000_0008;
95pub const MAGIC_MIME_TYPE: c_int = 0x000_0010;
96pub const MAGIC_CONTINUE: c_int = 0x000_0020;
97pub const MAGIC_CHECK: c_int = 0x000_0040;
98pub const MAGIC_PRESERVE_ATIME: c_int = 0x000_0080;
99pub const MAGIC_RAW: c_int = 0x000_0100;
100pub const MAGIC_ERROR: c_int = 0x000_0200;
101pub const MAGIC_MIME_ENCODING: c_int = 0x000_0400;
102pub const MAGIC_MIME: c_int = MAGIC_MIME_TYPE | MAGIC_MIME_ENCODING;
103pub const MAGIC_APPLE: c_int = 0x00_0800;
104pub const MAGIC_EXTENSION: c_int = 0x100_0000;
105pub const MAGIC_COMPRESS_TRANSP: c_int = 0x200_0000;
106#[cfg_attr(docsrs, doc(cfg(feature = "v5-44")))]
107#[cfg(feature = "v5-44")]
108pub const MAGIC_NO_COMPRESS_FORK: c_int = 0x400_0000;
109pub const MAGIC_NODESC: c_int = MAGIC_EXTENSION | MAGIC_MIME | MAGIC_APPLE;
110
111pub const MAGIC_NO_CHECK_COMPRESS: c_int = 0x000_1000;
112pub const MAGIC_NO_CHECK_TAR: c_int = 0x000_2000;
113pub const MAGIC_NO_CHECK_SOFT: c_int = 0x000_4000;
114pub const MAGIC_NO_CHECK_APPTYPE: c_int = 0x000_8000;
115pub const MAGIC_NO_CHECK_ELF: c_int = 0x001_0000;
116pub const MAGIC_NO_CHECK_TEXT: c_int = 0x002_0000;
117pub const MAGIC_NO_CHECK_CDF: c_int = 0x004_0000;
118pub const MAGIC_NO_CHECK_CSV: c_int = 0x008_0000;
119pub const MAGIC_NO_CHECK_TOKENS: c_int = 0x010_0000;
120pub const MAGIC_NO_CHECK_ENCODING: c_int = 0x020_0000;
121pub const MAGIC_NO_CHECK_JSON: c_int = 0x040_0000;
122#[cfg_attr(docsrs, doc(cfg(feature = "v5-45")))]
123#[cfg(feature = "v5-45")]
124pub const MAGIC_NO_CHECK_SIMH: c_int = 0x080_0000;
125
126#[cfg(not(feature = "v5-45"))]
127pub const MAGIC_NO_CHECK_BUILTIN: c_int = MAGIC_NO_CHECK_COMPRESS |
128MAGIC_NO_CHECK_TAR |
129MAGIC_NO_CHECK_APPTYPE |
131MAGIC_NO_CHECK_ELF |
132MAGIC_NO_CHECK_TEXT |
133MAGIC_NO_CHECK_CSV |
134MAGIC_NO_CHECK_CDF |
135MAGIC_NO_CHECK_TOKENS |
136MAGIC_NO_CHECK_ENCODING |
137MAGIC_NO_CHECK_JSON;
138
139#[cfg(feature = "v5-45")]
140pub const MAGIC_NO_CHECK_BUILTIN: c_int = MAGIC_NO_CHECK_COMPRESS |
141MAGIC_NO_CHECK_TAR |
142MAGIC_NO_CHECK_APPTYPE |
144MAGIC_NO_CHECK_ELF |
145MAGIC_NO_CHECK_TEXT |
146MAGIC_NO_CHECK_CSV |
147MAGIC_NO_CHECK_CDF |
148MAGIC_NO_CHECK_TOKENS |
149MAGIC_NO_CHECK_ENCODING |
150MAGIC_NO_CHECK_JSON |
151MAGIC_NO_CHECK_SIMH;
152
153#[deprecated]
154pub const MAGIC_NO_CHECK_ASCII: c_int = MAGIC_NO_CHECK_TEXT;
155
156#[deprecated]
157pub const MAGIC_NO_CHECK_FORTRAN: c_int = 0x00_0000;
158#[deprecated]
159pub const MAGIC_NO_CHECK_TROFF: c_int = 0x00_0000;
160
161pub const MAGIC_PARAM_INDIR_MAX: c_int = 0;
166pub const MAGIC_PARAM_NAME_MAX: c_int = 1;
167pub const MAGIC_PARAM_ELF_PHNUM_MAX: c_int = 2;
168pub const MAGIC_PARAM_ELF_SHNUM_MAX: c_int = 3;
169pub const MAGIC_PARAM_ELF_NOTES_MAX: c_int = 4;
170pub const MAGIC_PARAM_REGEX_MAX: c_int = 5;
171pub const MAGIC_PARAM_BYTES_MAX: c_int = 6;
172#[cfg_attr(docsrs, doc(cfg(feature = "v5-40")))]
173#[cfg(feature = "v5-40")]
174pub const MAGIC_PARAM_ENCODING_MAX: c_int = 7;
175#[cfg_attr(docsrs, doc(cfg(feature = "v5-45")))]
176#[cfg(feature = "v5-45")]
177pub const MAGIC_PARAM_ELF_SHSIZE_MAX: c_int = 8;
178#[cfg(feature = "v5-46")]
179pub const MAGIC_PARAM_MAGWARN_MAX: c_int = 9;
180
181pub const FILE_LOAD: c_int = 0;
183pub const FILE_CHECK: c_int = 1;
184pub const FILE_COMPILE: c_int = 2;
185pub const FILE_LIST: c_int = 3;
186
187extern "C" {
188 pub fn magic_open(flags: c_int) -> magic_t;
189 pub fn magic_close(cookie: magic_t);
190
191 pub fn magic_getpath(magicfile: *const c_char, action: c_int) -> *const c_char;
192 pub fn magic_file(cookie: magic_t, filename: *const c_char) -> *const c_char;
193 pub fn magic_descriptor(cookie: magic_t, fd: c_int) -> *const c_char;
194 pub fn magic_buffer(cookie: magic_t, buffer: *const c_void, length: size_t) -> *const c_char;
195
196 pub fn magic_error(cookie: magic_t) -> *const c_char;
197 pub fn magic_getflags(cookie: magic_t) -> c_int;
198 #[must_use]
199 pub fn magic_setflags(cookie: magic_t, flags: c_int) -> c_int;
200
201 pub fn magic_version() -> c_int;
202 #[must_use]
203 pub fn magic_load(cookie: magic_t, filename: *const c_char) -> c_int;
204 #[must_use]
205 pub fn magic_load_buffers(
206 cookie: magic_t,
207 buffers: *mut *mut c_void,
208 sizes: *mut size_t,
209 nbuffers: size_t,
210 ) -> c_int;
211
212 #[must_use]
213 pub fn magic_compile(cookie: magic_t, filename: *const c_char) -> c_int;
214 #[must_use]
215 pub fn magic_check(cookie: magic_t, filename: *const c_char) -> c_int;
216 #[must_use]
217 pub fn magic_list(cookie: magic_t, filename: *const c_char) -> c_int;
218 pub fn magic_errno(cookie: magic_t) -> c_int;
219
220 #[must_use]
221 pub fn magic_setparam(cookie: magic_t, param: c_int, value: *const c_void) -> c_int;
222 #[must_use]
223 pub fn magic_getparam(cookie: magic_t, param: c_int, value: *mut c_void) -> c_int;
224}
225
226#[cfg(test)]
227mod tests {
228 use super::*;
229
230 #[test]
234 fn test_magic_open() {
235 unsafe {
236 magic_open(MAGIC_NONE);
237 }
238 }
239
240 #[test]
241 fn test_magic_close() {
242 unsafe {
243 magic_close(std::ptr::null_mut());
244 }
245 }
246
247 #[test]
248 fn test_magic_getpath() {
249 unsafe {
250 magic_getpath(std::ptr::null(), FILE_CHECK);
251 }
252 }
253
254 #[test]
255 fn test_magic_file() {
256 unsafe {
257 magic_file(std::ptr::null_mut(), std::ptr::null());
258 }
259 }
260
261 #[test]
262 fn test_magic_descriptor() {
263 unsafe {
264 magic_descriptor(std::ptr::null_mut(), -1);
265 }
266 }
267
268 #[test]
269 fn test_magic_buffer() {
270 unsafe {
271 magic_buffer(std::ptr::null_mut(), std::ptr::null(), 0);
272 }
273 }
274
275 #[test]
276 fn test_magic_error() {
277 unsafe {
278 magic_error(std::ptr::null_mut());
279 }
280 }
281
282 #[test]
283 fn test_magic_getflags() {
284 unsafe {
285 magic_getflags(std::ptr::null_mut());
286 }
287 }
288
289 #[test]
290 fn test_magic_setflags() {
291 unsafe {
292 let _ = magic_setflags(std::ptr::null_mut(), MAGIC_NONE);
293 }
294
295 }
297
298 #[test]
299 fn test_magic_version() {
300 unsafe {
301 magic_version();
302 }
303 }
304
305 #[test]
306 fn test_magic_load() {
307 unsafe {
308 let _ = magic_load(std::ptr::null_mut(), std::ptr::null());
309 }
310 }
311
312 #[test]
313 fn test_magic_load_buffers() {
314 unsafe {
315 let _ = magic_load_buffers(
316 std::ptr::null_mut(),
317 std::ptr::null_mut(),
318 std::ptr::null_mut(),
319 0,
320 );
321 }
322 }
323
324 #[test]
325 fn test_magic_compile() {
326 unsafe {
327 let _ = magic_compile(std::ptr::null_mut(), std::ptr::null());
328 }
329 }
330
331 #[test]
332 fn test_magic_check() {
333 unsafe {
334 let _ = magic_check(std::ptr::null_mut(), std::ptr::null());
335 }
336 }
337
338 #[test]
339 fn test_magic_list() {
340 unsafe {
341 let _ = magic_list(std::ptr::null_mut(), std::ptr::null());
342 }
343 }
344
345 #[test]
346 fn test_magic_errno() {
347 unsafe {
348 magic_errno(std::ptr::null_mut());
349 }
350 }
351
352 #[test]
353 fn test_magic_setparam() {
354 unsafe {
355 let _ = magic_setparam(
356 std::ptr::null_mut(),
357 MAGIC_PARAM_INDIR_MAX,
358 std::ptr::null(),
359 );
360 }
361 }
362
363 #[test]
364 fn test_magic_getparam() {
365 unsafe {
366 let _ = magic_getparam(
367 std::ptr::null_mut(),
368 MAGIC_PARAM_INDIR_MAX,
369 std::ptr::null_mut(),
370 );
371 }
372
373 #[cfg(feature = "v5-40")]
374 {
375 let mgc = unsafe { magic_open(MAGIC_NONE) };
376 assert_ne!(mgc, std::ptr::null_mut());
377
378 let mut val: size_t = 0;
379
380 let rv = unsafe {
381 magic_getparam(
382 mgc,
383 MAGIC_PARAM_ENCODING_MAX,
384 &mut val as *mut size_t as *mut _,
385 )
386 };
387 assert_ne!(rv, -1);
388
389 unsafe {
390 magic_close(mgc);
391 }
392 }
393
394 #[cfg(feature = "v5-45")]
395 {
396 let mgc = unsafe { magic_open(MAGIC_NONE) };
397 assert_ne!(mgc, std::ptr::null_mut());
398
399 let mut val: size_t = 0;
400
401 let rv = unsafe {
402 magic_getparam(
403 mgc,
404 MAGIC_PARAM_ELF_SHSIZE_MAX,
405 &mut val as *mut size_t as *mut _,
406 )
407 };
408 assert_ne!(rv, -1);
409
410 unsafe {
411 magic_close(mgc);
412 }
413 }
414
415 #[cfg(feature = "v5-46")]
416 {
417 let mgc = unsafe { magic_open(MAGIC_NONE) };
418 assert_ne!(mgc, std::ptr::null_mut());
419
420 let mut val: size_t = 0;
421
422 let rv = unsafe {
423 magic_getparam(
424 mgc,
425 MAGIC_PARAM_MAGWARN_MAX,
426 &mut val as *mut size_t as *mut _,
427 )
428 };
429 assert_ne!(rv, -1);
430
431 unsafe {
432 magic_close(mgc);
433 }
434 }
435 }
436}