file_mode/
parser.rs

1use crate::{Mode, User, Protection, ProtectionBit, Special, SpecialBit};
2use std::str::FromStr;
3use std::iter::Peekable;
4use std::str::Chars;
5use std::num::ParseIntError;
6use std::fmt::{self, Display};
7use std::error::Error;
8
9/// Error parsing mode string.
10#[derive(Debug)]
11pub enum ModeParseError {
12    UnexpectedChar(&'static str, char),
13    UnexpectedEnd(&'static str),
14    OctalParseError(ParseIntError),
15}
16
17impl Display for ModeParseError {
18    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19        use ModeParseError::*;
20        match self {
21            UnexpectedChar(expected, c) => write!(f, "unexpected character '{}', expected: {}", c, expected),
22            UnexpectedEnd(expected) => write!(f, "unexpected end of string, expected: {}", expected),
23            OctalParseError(_) => write!(f, "failed to parse octal value"),
24        }
25    }
26}
27
28impl Error for ModeParseError {
29    fn source(&self) -> Option<&(dyn Error + 'static)> {
30        use ModeParseError::*;
31        match self {
32            UnexpectedChar(_, _) => None,
33            UnexpectedEnd(_) => None,
34            OctalParseError(err) => Some(err),
35        }
36    }
37}
38
39// [ugoa]*
40//
41// Empty set: "If none of these are given, the effect is as if (a) were given, but bits that are set in the umask are not affected."
42// So for empty mode needs to be masked by umask.
43#[derive(Debug)]
44struct Users(Vec<User>);
45
46impl Users {
47    fn parse(chars: &mut Peekable<Chars>) -> Users {
48        use User::*;
49        let mut users = Vec::new();
50        loop {
51            match chars.peek() {
52                Some('u') => { users.push(Owner); },
53                Some('g') => { users.push(Group); },
54                Some('o') => { users.push(Other); },
55                Some('a') => {
56                    users.push(Owner);
57                    users.push(Group);
58                    users.push(Other);
59                }
60                _ => return Users(users)
61            }
62            chars.next();
63        }
64    }
65}
66
67// [-+=]
68#[derive(Debug)]
69enum Operator {
70    Add,
71    Sub,
72    Set,
73}
74
75impl Operator {
76    fn parse(chars: &mut Peekable<Chars>) -> Result<Operator, ModeParseError> {
77        use Operator::*;
78        let c = chars.next().ok_or(ModeParseError::UnexpectedEnd("operator"))?;
79        match c {
80            '-' => Ok(Sub),
81            '+' => Ok(Add),
82            '=' => Ok(Set),
83            c => Err(ModeParseError::UnexpectedChar("[-+=]", c))
84        }
85    }
86}
87
88// [rwxXst]
89#[derive(Debug)]
90enum Bit {
91    Protection(ProtectionBit),
92    Special(SpecialBit),
93}
94
95impl Bit {
96    fn parse(chars: &mut Peekable<Chars>) -> Result<Bit, ModeParseError> {
97        use ProtectionBit::*;
98        use SpecialBit::*;
99        let c = chars.next().ok_or(ModeParseError::UnexpectedEnd("operator"))?;
100        match c {
101            'r' => Ok(Bit::Protection(Read)),
102            'w' => Ok(Bit::Protection(Write)),
103            'x' => Ok(Bit::Protection(Execute)),
104            'X' => Ok(Bit::Protection(Search)),
105            's' => Ok(Bit::Special(SetId)),
106            't' => Ok(Bit::Special(Sticky)),
107            c => Err(ModeParseError::UnexpectedChar("[rwxXst]", c))
108        }
109    }
110}
111
112// [rwxXst]*|[ugo]
113#[derive(Debug)]
114enum Value {
115    Bits(Vec<Bit>),
116    Source(User),
117}
118
119impl Value {
120    fn parse(chars: &mut Peekable<Chars>) -> Result<Value, ModeParseError> {
121        use Value::*;
122        use User::*;
123
124        if let Some(c) = chars.peek() {
125            let user = match c {
126                'u' => Some(Owner),
127                'g' => Some(Group),
128                'o' => Some(Other),
129                _ => None,
130            };
131
132            if let Some(user) = user {
133                chars.next();
134                Ok(Source(user))
135            } else {
136                let mut bits = Vec::new();
137
138                while chars.peek().is_some() {
139                    bits.push(Bit::parse(chars).unwrap());
140                }
141
142                Ok(Value::Bits(bits))
143            }
144        } else {
145            Ok(Value::Bits(Vec::new()))
146        }
147    }
148}
149
150// [-+=]([rwxXst]*|[ugo])
151#[derive(Debug)]
152struct Expression {
153    operator: Operator,
154    value: Value,
155}
156
157impl Expression {
158    fn parse(chars: &mut Peekable<Chars>) -> Result<Expression, ModeParseError> {
159        Ok(Expression {
160            operator: Operator::parse(chars)?,
161            value: Value::parse(chars)?,
162        })
163    }
164}
165
166// [ugoa]*([-+=]([rwxXst]*|[ugo]))+
167#[derive(Debug)]
168struct SymbolicMode {
169    users: Users,
170    // non-empty
171    expressions: Vec<Expression>,
172}
173
174impl SymbolicMode {
175    fn parse(chars: &mut Peekable<Chars>) -> Result<SymbolicMode, ModeParseError> {
176        let users = Users::parse(chars);
177        let mut expressions = Vec::new();
178
179        loop {
180            if chars.peek().is_none() {
181                break
182            }
183
184            expressions.push(Expression::parse(chars)?);
185        }
186
187        if expressions.is_empty() {
188           Err(ModeParseError::UnexpectedEnd("bits or user flags"))
189        } else {
190            Ok(SymbolicMode {
191                users,
192                expressions,
193            })
194        }
195    }
196}
197
198// [-+=][0-7]+
199#[derive(Debug)]
200struct OctalMode {
201    operator: Operator,
202    mode: Mode,
203}
204
205impl OctalMode {
206    fn parse(chars: &mut Peekable<Chars>) -> Result<OctalMode, ModeParseError> {
207        let operator = Operator::parse(chars)?;
208
209        let mut mode = String::new();
210        for c in chars {
211            match c {
212                c @ '0'..='7' => mode.push(c),
213                c => return Err(ModeParseError::UnexpectedChar("[0-7]", c)),
214            }
215        }
216
217        if mode.is_empty() {
218            mode.push('0')
219        }
220
221        let mode = u32::from_str_radix(&mode, 8).map_err(ModeParseError::OctalParseError)?;
222
223        Ok(OctalMode {
224            operator,
225            mode: Mode::new(mode, 0o7777),
226        })
227    }
228}
229
230// [ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+
231#[derive(Debug)]
232enum ModeString {
233    Symbolic(SymbolicMode),
234    Octal(OctalMode),
235}
236
237impl FromStr for ModeString {
238    type Err = ModeParseError;
239
240    fn from_str(s: &str) -> Result<Self, Self::Err> {
241        let mut chars = s.chars().peekable();
242
243        let mode_string = if s.ends_with(|c| ('0'..='7').contains(&c)) {
244            ModeString::Octal(OctalMode::parse(&mut chars)?)
245        } else {
246            ModeString::Symbolic(SymbolicMode::parse(&mut chars)?)
247        };
248
249        if let Some(c) = chars.next() {
250            Err(ModeParseError::UnexpectedChar("no more characters", c))
251        } else {
252            Ok(mode_string)
253        }
254    }
255}
256
257impl ModeString {
258    //TODO: rewrite as an iterator to avoid allocation
259    fn into_operations(self, ref_mode: u32, umask: u32) -> Vec<(Operator, Mode)> {
260        let mut ops = Vec::new();
261
262        match self {
263            ModeString::Symbolic(symbolic) =>  {
264                let (users, umask) = if symbolic.users.0.is_empty() {
265                    (vec![User::Owner, User::Group, User::Other], umask)
266                } else {
267                    (symbolic.users.0, 0o0)
268                };
269
270                for expr in symbolic.expressions {
271                    let mut mode = Mode::empty();
272
273                    let mut protection = match &expr.operator {
274                        Operator::Set => Protection::all_clear(), // for = all bits needs to be managed
275                        _ => Protection::empty(),
276                    };
277
278                    let mut special = Special::empty();
279
280                    match expr.value {
281                        Value::Bits(bits) => for bit in bits {
282                            match bit {
283                                Bit::Protection(protection_bit) => protection.set(protection_bit),
284                                Bit::Special(special_bit) => special.set(special_bit),
285                            }
286                        }
287                        Value::Source(source_user) => {
288                            let mask = match &expr.operator {
289                                Operator::Set => 0o777, // copy all bits
290                                _ => ref_mode, // copy only bits set
291                            };
292
293                            let mut ref_mode = Mode::new(ref_mode, mask);
294                            ref_mode.set(&mode);
295                            protection = ref_mode.user_protection(source_user);
296                        }
297                    }
298
299                    for user in &users {
300                        mode.set_protection(*user, &protection);
301                        mode.set_special(*user, &special);
302                    }
303
304                    mode.apply_umask(umask);
305
306                    ops.push((expr.operator, mode));
307                }
308            }
309            ModeString::Octal(OctalMode { operator, mode }) => ops.push((operator, mode)),
310        }
311
312        ops
313    }
314}
315
316pub(crate) fn mode_set_from_str(mode: &mut Mode, mode_str: &str, umask: u32) -> Result<(), ModeParseError> {
317    for mode_str in mode_str.split(',') {
318        set(mode, mode_str, umask)?;
319    }
320    Ok(())
321}
322
323/* Examples:
324 * g=r+w
325 * g=o
326 * =
327 */
328fn set(target: &mut Mode, mode_str: &str, umask: u32) -> Result<(), ModeParseError> {
329    let ms = ModeString::from_str(mode_str)?;
330
331    for (operator, mode) in ms.into_operations(target.mode, umask) {
332        match operator {
333            Operator::Add => target.add(&mode),
334            Operator::Sub => target.sub(&mode),
335            Operator::Set => target.set(&mode),
336        }
337    }
338
339    Ok(())
340}
341
342#[cfg(test)]
343mod tests {
344    use super::*;
345    use assert_matches::assert_matches;
346
347    #[test]
348    fn test_parse_users() {
349        use User::*;
350
351        let mut i = "a".chars().peekable();
352        assert_eq!(Users::parse(&mut i).0, vec![Owner, Group, Other]);
353        assert!(i.next().is_none());
354
355        let mut i = "uog".chars().peekable();
356        assert_eq!(Users::parse(&mut i).0, vec![Owner, Other, Group]);
357        assert!(i.next().is_none());
358
359        let mut i = "uxog".chars().peekable();
360        assert_eq!(Users::parse(&mut i).0, vec![Owner]);
361        assert_eq!(&i.collect::<String>(), "xog");
362
363        let mut i = "uoxg".chars().peekable();
364        assert_eq!(Users::parse(&mut i).0, vec![Owner, Other]);
365        assert_eq!(&i.collect::<String>(), "xg");
366
367        let mut i = "uogx".chars().peekable();
368        assert_eq!(Users::parse(&mut i).0, vec![Owner, Other, Group]);
369        assert_eq!(&i.collect::<String>(), "x");
370    }
371
372    #[test]
373    fn test_parse_value() {
374        use ProtectionBit::*;
375        use SpecialBit::*;
376
377        let mut i = "".chars().peekable();
378        assert_matches!(Value::parse(&mut i).unwrap(), Value::Bits(bits) => {
379            assert!(bits.is_empty());
380        });
381        assert!(i.next().is_none());
382
383        let mut i = "rwxst".chars().peekable();
384        assert_matches!(Value::parse(&mut i).unwrap(), Value::Bits(bits) => {
385            let mut b = bits.into_iter();
386            assert_matches!(b.next().unwrap(), Bit::Protection(Read));
387            assert_matches!(b.next().unwrap(), Bit::Protection(Write));
388            assert_matches!(b.next().unwrap(), Bit::Protection(Execute));
389            assert_matches!(b.next().unwrap(), Bit::Special(SetId));
390            assert_matches!(b.next().unwrap(), Bit::Special(Sticky));
391            assert!(b.next().is_none());
392        });
393        assert!(i.next().is_none());
394
395        let mut i = "xw".chars().peekable();
396        assert_matches!(Value::parse(&mut i).unwrap(), Value::Bits(bits) => {
397            let mut b = bits.into_iter();
398            assert_matches!(b.next().unwrap(), Bit::Protection(Execute));
399            assert_matches!(b.next().unwrap(), Bit::Protection(Write));
400            assert!(b.next().is_none());
401        });
402        assert!(i.next().is_none());
403
404        let mut i = "u".chars().peekable();
405        assert_matches!(Value::parse(&mut i).unwrap(), Value::Source(User::Owner));
406        assert!(i.next().is_none());
407
408        let mut i = "g".chars().peekable();
409        assert_matches!(Value::parse(&mut i).unwrap(), Value::Source(User::Group));
410        assert!(i.next().is_none());
411
412        let mut i = "o".chars().peekable();
413        assert_matches!(Value::parse(&mut i).unwrap(), Value::Source(User::Other));
414        assert!(i.next().is_none());
415
416        let mut i = "oo?".chars().peekable();
417        assert_matches!(Value::parse(&mut i).unwrap(), Value::Source(User::Other));
418        assert_eq!(i.next(), Some('o'));
419    }
420
421    #[test]
422    fn test_parse_symbolic_mode() {
423        use User::*;
424
425        let mut i = "u+r".chars().peekable();
426        assert_matches!(SymbolicMode::parse(&mut i).unwrap(), SymbolicMode { users, expressions } => {
427            assert_eq!(users.0, vec![Owner]);
428
429            let mut e = expressions.into_iter();
430            assert_matches!(e.next().unwrap(), Expression { operator: Operator::Add, value } => {
431                assert_matches!(value, Value::Bits(bits) => {
432                    let mut b = bits.into_iter();
433                    assert_matches!(b.next().unwrap(), Bit::Protection(ProtectionBit::Read));
434                    assert!(b.next().is_none());
435                });
436            });
437            assert!(e.next().is_none());
438        });
439        assert!(i.next().is_none());
440
441        let mut i = "=rs".chars().peekable();
442        assert_matches!(SymbolicMode::parse(&mut i).unwrap(), SymbolicMode { users, expressions } => {
443            assert_eq!(users.0, vec![]);
444
445            let mut e = expressions.into_iter();
446            assert_matches!(e.next().unwrap(), Expression { operator: Operator::Set, value } => {
447                assert_matches!(value, Value::Bits(bits) => {
448                    let mut b = bits.into_iter();
449                    assert_matches!(b.next().unwrap(), Bit::Protection(ProtectionBit::Read));
450                    assert_matches!(b.next().unwrap(), Bit::Special(SpecialBit::SetId));
451                    assert!(b.next().is_none());
452                });
453            });
454            assert!(e.next().is_none());
455        });
456        assert!(i.next().is_none());
457
458        let mut i = "a=u".chars().peekable();
459        assert_matches!(SymbolicMode::parse(&mut i).unwrap(), SymbolicMode { users, expressions } => {
460            assert_eq!(users.0, vec![Owner, Group, Other]);
461
462            let mut e = expressions.into_iter();
463            assert_matches!(e.next().unwrap(), Expression { operator: Operator::Set, value } => {
464                assert_matches!(value, Value::Source(Owner));
465            });
466            assert!(e.next().is_none());
467        });
468        assert!(i.next().is_none());
469    }
470
471    #[test]
472    fn test_parse_octal_mode() {
473        let mut i = "=777".chars().peekable();
474        assert_matches!(OctalMode::parse(&mut i).unwrap(), OctalMode { operator: Operator::Set, mode } => {
475            assert_eq!(mode, Mode::new(0o777, 0o7777));
476        });
477        assert!(i.next().is_none());
478
479        let mut i = "-7".chars().peekable();
480        assert_matches!(OctalMode::parse(&mut i).unwrap(), OctalMode { operator: Operator::Sub, mode } => {
481            assert_eq!(mode, Mode::new(0o007, 0o7777));
482        });
483        assert!(i.next().is_none());
484
485        let mut i = "+23".chars().peekable();
486        assert_matches!(OctalMode::parse(&mut i).unwrap(), OctalMode { operator: Operator::Add, mode } => {
487            assert_eq!(mode, Mode::new(0o023, 0o7777));
488        });
489        assert!(i.next().is_none());
490
491        let mut i = "+023".chars().peekable();
492        assert_matches!(OctalMode::parse(&mut i).unwrap(), OctalMode { operator: Operator::Add, mode } => {
493            assert_eq!(mode, Mode::new(0o023, 0o7777));
494        });
495        assert!(i.next().is_none());
496
497        let mut i = "=".chars().peekable();
498        assert_matches!(OctalMode::parse(&mut i).unwrap(), OctalMode { operator: Operator::Set, mode } => {
499            assert_eq!(mode, Mode::new(0o000, 0o7777));
500        });
501        assert!(i.next().is_none());
502    }
503}