Skip to main content

luaur_analysis/methods/
lint_format_string_check_string_format.rs

1use crate::records::lint_format_string::LintFormatString;
2use core::ffi::c_char;
3
4impl LintFormatString {
5    pub fn check_string_format(&self, data: *const c_char, size: usize) -> *const c_char {
6        let flags = b"-+ #0";
7        let options = b"cdiouxXeEfgGqs*";
8
9        let mut i = 0;
10        while i < size {
11            let ch = unsafe { *data.add(i) };
12            if ch == b'%' as i8 {
13                i += 1;
14
15                if i < size && unsafe { *data.add(i) } == b'%' as i8 {
16                    i += 1;
17                    continue;
18                }
19
20                while i < size && flags.contains(&(unsafe { *data.add(i) } as u8)) {
21                    i += 1;
22                }
23
24                if i < size && self.is_digit(unsafe { *data.add(i) }) {
25                    i += 1;
26                }
27                if i < size && self.is_digit(unsafe { *data.add(i) }) {
28                    i += 1;
29                }
30
31                if i < size && unsafe { *data.add(i) } == b'.' as i8 {
32                    i += 1;
33
34                    if i < size && self.is_digit(unsafe { *data.add(i) }) {
35                        i += 1;
36                    }
37                    if i < size && self.is_digit(unsafe { *data.add(i) }) {
38                        i += 1;
39                    }
40                }
41
42                if i == size {
43                    return c"unfinished format specifier".as_ptr();
44                }
45
46                if !options.contains(&(unsafe { *data.add(i) } as u8)) {
47                    return c"invalid format specifier: must be a string format specifier or %"
48                        .as_ptr();
49                }
50            }
51            i += 1;
52        }
53
54        core::ptr::null()
55    }
56}