neutralts/bif/
parse_bif_var.rs

1#![doc = include_str!("../../doc/bif-var.md")]
2
3use crate::{bif::constants::*, bif::Bif, bif::BifError, constants::*, utils::*};
4
5impl<'a> Bif<'a> {
6    /*
7        {:;varname:}
8        {:;:}
9    */
10    pub(crate) fn parse_bif_var(&mut self) -> Result<(), BifError> {
11        if self.mod_scope {
12            return Err(self.bif_error(BIF_ERROR_MODIFIER_NOT_ALLOWED));
13        }
14
15        // Unprintable: {:;:} / {:; :}
16        if self.src.is_empty() {
17            // "bif.alias" is used and not "bif.name" because in "var" or "unprintable"
18            // its name is an empty string.
19            self.alias = "unprintable".to_string();
20
21            self.out = UNPRINTABLE.to_string();
22
23            return Ok(());
24        }
25
26        // Var: {:;varname:}
27        self.alias = "var".to_string();
28        let var_name;
29
30        // For security requires {:allow; in some cases.
31        if self.src.contains(BIF_OPEN) {
32            if !self.contains_allow(&self.src) {
33                self.out = EMPTY_STRING;
34
35                return Err(self.bif_error(BIF_ERROR_INSECURE_VARNAME));
36            }
37
38            var_name = new_child_parse!(self, &self.src, self.mod_scope);
39        } else {
40            var_name = self.src.clone();
41        }
42
43        self.out = self.get_data(&var_name).to_string();
44
45        if (self.mod_filter || self.shared.filter_all) && !self.mod_negate {
46            if !var_name.starts_with("CONTEXT->") {
47                // unescape_chars for prevent double encoding
48                self.out = unescape_chars(&self.get_data(&var_name), true).to_string();
49                self.out = escape_chars(&self.out, true).to_string();
50            }
51        } else {
52            if self.shared.filter_bifs {
53                // Avoid reevaluation in cache
54                self.out = self.out.replace(BIF_OPEN, BIF_SANITIZE_OPEN);
55                self.out = self.out.replace(BIF_CLOSE, BIF_SANITIZE_CLOSE);
56            }
57        }
58
59        if self.mod_negate && !self.shared.filter_bifs && var_name.starts_with("CONTEXT->") {
60            self.out = unescape_chars(&self.out, true).to_string();
61        }
62
63        Ok(())
64    }
65}
66
67#[cfg(test)]
68#[path = "parse_bif_var_tests.rs"]
69mod tests;