ps_parser/
parser.rs

1mod command;
2mod error;
3mod predicates;
4mod script_result;
5mod stream_message;
6mod token;
7mod value;
8mod variables;
9
10use std::collections::HashMap;
11
12pub(crate) use command::CommandError;
13use command::{Command, CommandElem};
14pub(crate) use stream_message::StreamMessage;
15use value::{Param, RuntimeObjectTrait, ScriptBlock, ValResult};
16use variables::{Scope, SessionScope};
17type ParserResult<T> = core::result::Result<T, ParserError>;
18use error::ParserError;
19type PestError = pest::error::Error<Rule>;
20use pest::Parser;
21use pest_derive::Parser;
22use predicates::{ArithmeticPred, BitwisePred, LogicalPred, StringPred};
23pub use script_result::{PsValue, ScriptResult};
24pub use token::{CommandToken, ExpressionToken, MethodToken, StringExpandableToken, Token, Tokens};
25pub(crate) use value::Val;
26use value::ValType;
27pub use variables::Variables;
28use variables::{VarName, VariableError};
29
30use crate::parser::command::CommandOutput;
31
32type Pair<'i> = ::pest::iterators::Pair<'i, Rule>;
33type Pairs<'i> = ::pest::iterators::Pairs<'i, Rule>;
34
35pub(crate) const NEWLINE: &str = "\n";
36
37macro_rules! unexpected_token {
38    ($pair:expr) => {
39        panic!("Unexpected token: {:?}", $pair.as_rule())
40    };
41}
42
43macro_rules! check_rule {
44    ($pair:expr, $rule:pat) => {
45        if !matches!($pair.as_rule(), $rule) {
46            panic!(
47                "Unexpected token: {:?}, instead of {}",
48                $pair.as_rule(),
49                stringify!($rule)
50            );
51        }
52    };
53}
54
55macro_rules! not_implemented {
56    ($token:expr) => {
57        Err(ParserError::NotImplemented(format!(
58            "Not implemented: {:?}",
59            $token.as_rule()
60        )))
61    };
62}
63
64#[derive(Default)]
65pub(crate) struct Results {
66    output: Vec<StreamMessage>,
67    deobfuscated: Vec<String>,
68}
69
70impl Results {
71    fn new() -> Self {
72        Self {
73            output: Vec::new(),
74            deobfuscated: Vec::new(),
75        }
76    }
77}
78
79#[derive(Parser)]
80#[grammar = "powershell.pest"]
81pub struct PowerShellSession {
82    variables: Variables,
83    tokens: Tokens,
84    errors: Vec<ParserError>,
85    results: Vec<Results>,
86    skip_error: u32,
87}
88
89impl Default for PowerShellSession {
90    fn default() -> Self {
91        Self::new()
92    }
93}
94
95impl<'a> PowerShellSession {
96    /// Creates a new PowerShell parsing session with default settings.
97    ///
98    /// The session is initialized with built-in variables like `$true`,
99    /// `$false`, `$null`, and special variables like `$?` for error status
100    /// tracking.
101    ///
102    /// # Returns
103    ///
104    /// A new `PowerShellSession` instance ready for script evaluation.
105    ///
106    /// # Examples
107    ///
108    /// ```rust
109    /// use ps_parser::PowerShellSession;
110    ///
111    /// let mut session = PowerShellSession::new();
112    /// let result = session.safe_eval("$true").unwrap();
113    /// assert_eq!(result, "True");
114    /// ```
115    pub fn new() -> Self {
116        Self {
117            variables: Variables::new(),
118            tokens: Tokens::new(),
119            errors: Vec::new(),
120            results: Vec::new(),
121            skip_error: 0,
122        }
123    }
124
125    /// Creates a new PowerShell session with the provided variables.
126    ///
127    /// This constructor allows you to initialize the session with a custom set
128    /// of variables, such as environment variables or variables loaded from
129    /// configuration files.
130    ///
131    /// # Arguments
132    ///
133    /// * `variables` - A `Variables` instance containing the initial variable
134    ///   set.
135    ///
136    /// # Returns
137    ///
138    /// A new `PowerShellSession` instance with the provided variables.
139    ///
140    /// # Examples
141    ///
142    /// ```rust
143    /// use ps_parser::{PowerShellSession, Variables};
144    ///
145    /// let env_vars = Variables::env();
146    /// let mut session = PowerShellSession::new().with_variables(env_vars);
147    /// let username = session.safe_eval("$env:USERNAME").unwrap();
148    /// ```
149    pub fn with_variables(mut self, variables: Variables) -> Self {
150        self.variables = variables;
151        self
152    }
153
154    /// Safely evaluates a PowerShell script and returns the output as a string.
155    ///
156    /// This method parses and evaluates the provided PowerShell script,
157    /// handling errors gracefully and returning the result as a formatted
158    /// string. It's the recommended method for simple script evaluation.
159    ///
160    /// # Arguments
161    ///
162    /// * `script` - A string slice containing the PowerShell script to
163    ///   evaluate.
164    ///
165    /// # Returns
166    ///
167    /// * `Result<String, ParserError>` - The output of the script evaluation,
168    ///   or an error if parsing/evaluation fails.
169    ///
170    /// # Examples
171    ///
172    /// ```rust
173    /// use ps_parser::PowerShellSession;
174    ///
175    /// let mut session = PowerShellSession::new();
176    ///
177    /// // Simple arithmetic
178    /// let result = session.safe_eval("1 + 2 * 3").unwrap();
179    /// assert_eq!(result, "7");
180    ///
181    /// // Variable assignment and retrieval
182    /// let result = session.safe_eval("$name = 'World'; \"Hello $name\"").unwrap();
183    /// assert_eq!(result, "Hello World");
184    /// ```
185    pub fn safe_eval(&mut self, script: &str) -> Result<String, ParserError> {
186        let script_res = self.parse_input(script)?;
187        Ok(script_res.result().to_string())
188    }
189
190    pub fn deobfuscate_script(&mut self, script: &str) -> Result<String, ParserError> {
191        self.push_scope_session();
192        let script_res = self.parse_input(script)?;
193        self.pop_scope_session();
194        Ok(script_res.deobfuscated().to_string())
195    }
196
197    pub fn env_variables(&self) -> HashMap<String, PsValue> {
198        self.variables
199            .get_env()
200            .into_iter()
201            .map(|(k, v)| (k, v.into()))
202            .collect()
203    }
204
205    pub fn session_variables(&self) -> HashMap<String, PsValue> {
206        self.variables
207            .get_global()
208            .into_iter()
209            .map(|(k, v)| (k, v.into()))
210            .collect()
211    }
212
213    /// Parses and evaluates a PowerShell script, returning detailed results.
214    ///
215    /// This method provides comprehensive information about the parsing and
216    /// evaluation process, including the final result, generated output,
217    /// any errors encountered, and the tokenized representation of the
218    /// script. It's particularly useful for debugging and deobfuscation.
219    ///
220    /// # Arguments
221    ///
222    /// * `input` - A string slice containing the PowerShell script to parse and
223    ///   evaluate.
224    ///
225    /// # Returns
226    ///
227    /// * `Result<ScriptResult, ParserError>` - A detailed result containing the
228    ///   evaluation outcome, output, errors, and tokens, or a parsing error if
229    ///   the script is malformed.
230    ///
231    /// # Examples
232    ///
233    /// ```rust
234    /// use ps_parser::PowerShellSession;
235    ///
236    /// let mut session = PowerShellSession::new();
237    /// let script_result = session.parse_input("$a = 42; Write-Output $a").unwrap();
238    ///
239    /// println!("Final result: {:?}", script_result.result());
240    /// println!("Generated output: {:?}", script_result.output());
241    /// println!("Parsing errors: {:?}", script_result.errors());
242    /// println!("Deobfuscated code: {:?}", script_result.deobfuscated());
243    /// ```
244    pub fn parse_input(&mut self, input: &str) -> Result<ScriptResult, ParserError> {
245        self.variables.init();
246        let (script_last_output, mut result) = self.parse_subscript(input)?;
247        self.variables.clear_script_functions();
248        Ok(ScriptResult::new(
249            script_last_output,
250            std::mem::take(&mut result.output),
251            std::mem::take(&mut result.deobfuscated),
252            std::mem::take(&mut self.tokens),
253            std::mem::take(&mut self.errors),
254            self.variables
255                .script_scope()
256                .into_iter()
257                .map(|(k, v)| (k, v.into()))
258                .collect(),
259        ))
260    }
261
262    pub(crate) fn parse_subscript(&mut self, input: &str) -> Result<(Val, Results), ParserError> {
263        let mut pairs = PowerShellSession::parse(Rule::program, input)?;
264        //create new scope for script
265        self.results.push(Results::new());
266
267        let program_token = pairs.next().expect("");
268
269        let mut script_last_output = Val::default();
270
271        if let Rule::program = program_token.as_rule() {
272            let mut pairs = program_token.into_inner();
273            let _script_param_block_token = pairs.next().unwrap();
274            if let Some(named_blocks) = pairs.peek()
275                && named_blocks.as_rule() == Rule::named_blocks
276            {
277                //todo
278                let _ = pairs.next();
279            }
280            for token in pairs {
281                let token_str = token.as_str();
282                match token.as_rule() {
283                    Rule::statement_terminator => continue,
284                    Rule::EOI => break,
285                    _ => {}
286                };
287
288                let result = self.eval_statement(token.clone());
289                self.variables.set_status(result.is_ok());
290
291                if let Ok(Val::NonDisplayed(_)) = &result {
292                    continue;
293                }
294
295                script_last_output = match result {
296                    Ok(val) => {
297                        if val != Val::Null {
298                            self.add_output_statement(val.display().into());
299                            self.add_deobfuscated_statement(val.cast_to_script());
300                        }
301
302                        val
303                    }
304                    Err(e) => {
305                        self.errors.push(e);
306                        self.add_deobfuscated_statement(token_str.into());
307                        Val::Null
308                    }
309                };
310            }
311        }
312
313        Ok((script_last_output, self.results.pop().unwrap_or_default()))
314    }
315
316    fn add_function(
317        &mut self,
318        name: String,
319        func: ScriptBlock,
320        scope: Option<Scope>,
321    ) -> ParserResult<Val> {
322        // let func_str= func.to_function(&name, &scope);
323        // self.add_deobfuscated_statement(func_str);
324
325        if let Some(Scope::Global) = &scope {
326            self.variables.add_global_function(name.clone(), func);
327        } else {
328            self.variables.add_script_function(name.clone(), func);
329        }
330
331        Err(ParserError::Skip)
332    }
333
334    pub(crate) fn parse_function_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
335        check_rule!(token, Rule::function_statement);
336
337        let mut pair = token.into_inner();
338
339        let function_keyword_token = pair.next().unwrap();
340        check_rule!(function_keyword_token, Rule::function_keyword);
341
342        let mut next_token = pair.next().unwrap();
343        let scope = if next_token.as_rule() == Rule::scope_keyword {
344            let scope = Scope::from(next_token.as_str());
345            next_token = pair.next().unwrap();
346            Some(scope)
347        } else {
348            None
349        };
350
351        let function_name_token = next_token;
352        check_rule!(function_name_token, Rule::function_name);
353        let fname = function_name_token.as_str().to_ascii_lowercase();
354
355        let Some(mut next_token) = pair.next() else {
356            //empty function
357            return self.add_function(fname, ScriptBlock::empty(), scope);
358        };
359
360        let params = if next_token.as_rule() == Rule::parameter_list {
361            let param_list = self.parse_parameter_list(next_token)?;
362            if let Some(token) = pair.next() {
363                next_token = token;
364            } else {
365                return self.add_function(fname, ScriptBlock::empty(), scope);
366            }
367
368            param_list
369        } else {
370            Vec::new()
371        };
372        check_rule!(next_token, Rule::script_block);
373
374        let mut script_block = self.parse_script_block(next_token)?;
375
376        if script_block.params.0.is_empty() {
377            script_block = script_block.with_params(params);
378        }
379
380        self.add_function(fname, script_block, scope)
381    }
382
383    pub(crate) fn eval_if_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
384        check_rule!(token, Rule::if_statement);
385        let mut pair = token.into_inner();
386        let condition_token = pair.next().unwrap();
387        let true_token = pair.next().unwrap();
388        let condition_val = self.eval_pipeline(condition_token.clone())?;
389        let res = if condition_val.cast_to_bool() {
390            self.eval_statement_block(true_token)?
391        } else if let Some(mut token) = pair.next() {
392            if token.as_rule() == Rule::elseif_clauses {
393                for else_if in token.into_inner() {
394                    let mut pairs = else_if.into_inner();
395                    let condition_token = pairs.next().unwrap();
396                    let statement_token = pairs.next().unwrap();
397                    let condition_val = self.eval_pipeline(condition_token)?;
398                    if condition_val.cast_to_bool() {
399                        return self.eval_statement_block(statement_token);
400                    }
401                }
402                let Some(token2) = pair.next() else {
403                    return Ok(Val::Null);
404                };
405                token = token2;
406            }
407            if token.as_rule() == Rule::else_condition {
408                let statement_token = token.into_inner().next().unwrap();
409                self.eval_statement_block(statement_token)?
410            } else {
411                Val::Null
412            }
413        } else {
414            Val::Null
415        };
416
417        Ok(res)
418    }
419
420    fn eval_flow_control_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
421        check_rule!(token, Rule::flow_control_statement);
422        let token = token.into_inner().next().unwrap();
423
424        Ok(match token.as_rule() {
425            Rule::flow_control_label_statement => Val::Null, //TODO
426            Rule::flow_control_pipeline_statement => {
427                let token = token.into_inner().next().unwrap();
428                //todo: throw, return or exit
429                if let Some(pipeline_token) = token.into_inner().next() {
430                    self.eval_pipeline(pipeline_token)?
431                } else {
432                    Val::Null
433                }
434            }
435            _ => unexpected_token!(token),
436        })
437    }
438
439    fn eval_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
440        match token.as_rule() {
441            Rule::pipeline => self.eval_pipeline(token),
442            Rule::if_statement => self.eval_if_statement(token),
443            Rule::flow_control_statement => self.eval_flow_control_statement(token),
444            Rule::function_statement => self.parse_function_statement(token),
445            Rule::statement_terminator => Ok(Val::Null),
446            Rule::EOI => Ok(Val::Null),
447            _ => {
448                not_implemented!(token)
449            }
450        }
451    }
452
453    fn safe_eval_sub_expr(&mut self, token: Pair<'a>) -> ParserResult<Val> {
454        // match self.eval_statements(token.clone()) {
455        //     Ok(vals) => Ok(Val::Array(vals)),
456        //     Err(err) => {
457        //         self.errors.push(err);
458        //         Ok(Val::ScriptText(token.as_str().to_string()))
459        //     }
460        // }
461        check_rule!(token, Rule::sub_expression);
462        let Some(inner_token) = token.into_inner().next() else {
463            return Ok(Val::Null);
464        };
465        let mut inner_val = self.eval_pipeline(inner_token)?;
466        if let Val::ScriptText(script) = &mut inner_val {
467            *script = format!("$({})", script);
468            //self.tokens.push(Token::SubExpression(script.clone()));
469        }
470        Ok(inner_val)
471    }
472
473    fn eval_statement_block(&mut self, token: Pair<'a>) -> ParserResult<Val> {
474        Ok(self
475            .safe_eval_statements(token)?
476            .iter()
477            .last()
478            .cloned()
479            .unwrap_or(Val::Null))
480    }
481
482    fn eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
483        //check_rule!(token, Rule::statements);
484        let pairs = token.into_inner();
485        let mut statements = vec![];
486
487        for token in pairs {
488            let s = self.eval_statement(token)?;
489            statements.push(s);
490        }
491        Ok(statements)
492    }
493
494    fn safe_eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
495        //check_rule!(token, Rule::statements);
496        let pairs = token.into_inner();
497        let mut statements = vec![];
498
499        for token in pairs {
500            match self.eval_statement(token.clone()) {
501                Ok(s) => statements.push(s),
502                Err(err) => {
503                    self.errors.push(err);
504                    statements.push(Val::ScriptText(token.as_str().to_string()));
505                }
506            }
507        }
508        Ok(statements)
509    }
510
511    fn parse_dq(&mut self, token: Pair<'a>) -> ParserResult<String> {
512        let mut res_str = String::new();
513        let pairs = token.into_inner();
514        for token in pairs {
515            let token = token.into_inner().next().unwrap();
516            let s = match token.as_rule() {
517                Rule::variable => self.get_variable(token)?.cast_to_string(),
518                Rule::sub_expression => self.safe_eval_sub_expr(token)?.cast_to_string(),
519                Rule::backtick_escape => token
520                    .as_str()
521                    .strip_prefix("`")
522                    .unwrap_or_default()
523                    .to_string(),
524                _ => token.as_str().to_string(),
525            };
526            res_str.push_str(s.as_str());
527        }
528        Ok(res_str)
529    }
530
531    fn eval_string_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
532        check_rule!(token, Rule::string_literal);
533        let mut pair = token.into_inner();
534        let token = pair.next().unwrap();
535        let cloned_token = token.clone();
536
537        let mut is_expandable = false;
538        let res = match token.as_rule() {
539            Rule::doublequoted_string_literal | Rule::doublequoted_multiline_string_literal => {
540                is_expandable = true;
541                self.parse_dq(token)?
542            }
543            Rule::singlequoted_string_literal => {
544                let token_string = token.as_str().to_string();
545                let stripped_prefix = token_string
546                    .strip_prefix("'")
547                    .unwrap_or(token_string.as_str());
548                let stripped_suffix = stripped_prefix.strip_suffix("'").unwrap_or(stripped_prefix);
549                stripped_suffix.to_string()
550            }
551            Rule::singlequoted_multiline_string_literal => {
552                let mut res_str = String::new();
553                let pairs = token.into_inner();
554                for token in pairs {
555                    res_str.push_str(token.as_str());
556                }
557                res_str
558            }
559            _ => unexpected_token!(token),
560        };
561        let ps_token = if is_expandable {
562            Token::string_expandable(cloned_token.as_str().to_string(), res.clone())
563        } else {
564            Token::String(cloned_token.as_str().to_string())
565        };
566        self.tokens.push(ps_token);
567
568        Ok(Val::String(res.into()))
569    }
570
571    fn get_variable(&mut self, token: Pair<'a>) -> ParserResult<Val> {
572        check_rule!(token, Rule::variable);
573        let var_name = Self::parse_variable(token)?;
574        let Some(var) = self.variables.get(&var_name) else {
575            return Err(ParserError::VariableError(VariableError::NotDefined(
576                var_name.name,
577            )));
578        };
579        Ok(var)
580    }
581
582    fn parse_scoped_variable(token: Pair<'a>) -> ParserResult<VarName> {
583        //can be scoped or splatted
584        let mut pairs = token.into_inner();
585        let mut token = pairs.next().unwrap();
586
587        let scope = if token.as_rule() == Rule::scope_keyword {
588            let scope = token.as_str().to_ascii_lowercase();
589            token = pairs.next().unwrap();
590            check_rule!(token, Rule::var_name);
591            Some(Scope::from(scope.as_str()))
592        } else {
593            None
594        };
595        Ok(VarName::new(scope, token.as_str().to_ascii_lowercase()))
596    }
597
598    fn skip_value_access(&mut self, token: Pair<'a>) -> ParserResult<()> {
599        check_rule!(token, Rule::value_access);
600        let mut pair = token.into_inner();
601        let token = pair.next().unwrap();
602        let mut val = self.eval_value(token)?;
603        let _ = self.eval_element_access_ref(pair.next().unwrap(), &mut val)?;
604        Err(ParserError::Skip)
605    }
606
607    // fn get_assignable_variable<'b>(&mut self, pairs: Pairs<'a>, object: &'b mut
608    // Val) -> ParserResult<&'b mut Val> {     let mut var = object;
609    //     for token in pairs {
610    //             let tmp = self.variable_access(token, &mut var)?;
611    //             var = tmp;
612    //     }
613    //     Ok(var)
614    // }
615
616    fn parse_assignable_variable(
617        &mut self,
618        token: Pair<'a>,
619    ) -> ParserResult<(VarName, Option<Pairs<'a>>)> {
620        check_rule!(token, Rule::assignable_variable);
621        let mut pair = token.into_inner();
622        let token = pair.next().unwrap();
623        match token.as_rule() {
624            Rule::variable => {
625                let var_name = Self::parse_variable(token)?;
626
627                Ok((var_name, None))
628            }
629            Rule::variable_access => {
630                let mut pairs = token.into_inner();
631                let var_token = pairs.next().unwrap();
632                let var_name = Self::parse_variable(var_token)?;
633                // let mut object = &mut var;
634                // for token in pairs {
635                //     object = self.variable_access(token, &mut object)?;
636                // }
637                Ok((var_name, Some(pairs)))
638            }
639            Rule::value_access => self
640                .skip_value_access(token)
641                .map(|()| (Default::default(), None)),
642            _ => unexpected_token!(token),
643        }
644    }
645
646    fn parse_variable(token: Pair<'a>) -> ParserResult<VarName> {
647        check_rule!(token, Rule::variable);
648        let mut pair = token.into_inner();
649        let token = pair.next().unwrap();
650
651        Ok(match token.as_rule() {
652            Rule::special_variable => {
653                VarName::new_with_scope(Scope::Special, token.as_str().to_string())
654            }
655            Rule::parenthesized_variable => {
656                Self::parse_variable(token.into_inner().next().unwrap())?
657            }
658            Rule::braced_variable => {
659                let token = token.into_inner().next().unwrap();
660                let var = token.as_str().to_ascii_lowercase();
661                let splits: Vec<&str> = var.split(":").collect();
662                if splits.len() == 2 {
663                    VarName::new_with_scope(Scope::from(splits[0]), splits[1].to_string())
664                } else {
665                    VarName::new(None, var)
666                }
667            }
668            Rule::scoped_variable => Self::parse_scoped_variable(token)?,
669            _ => unexpected_token!(token),
670        })
671    }
672
673    fn eval_expression_with_unary_operator(&mut self, token: Pair<'a>) -> ParserResult<Val> {
674        check_rule!(token, Rule::expression_with_unary_operator);
675        let mut pair = token.into_inner();
676        let token = pair.next().unwrap();
677
678        let res = match token.as_rule() {
679            Rule::pre_inc_expression => {
680                let variable_token = token.into_inner().next().unwrap();
681                let var_name = Self::parse_variable(variable_token)?;
682                let mut var = self.variables.get(&var_name).unwrap_or_default();
683                var.inc()?;
684
685                self.variables.set(&var_name, var.clone())?;
686                var
687            }
688            Rule::pre_dec_expression => {
689                let variable_token = token.into_inner().next().unwrap();
690                let var_name = Self::parse_variable(variable_token)?;
691                let mut var = self.variables.get(&var_name).unwrap_or_default();
692                var.dec()?;
693
694                self.variables.set(&var_name, var.clone())?;
695                var
696            }
697            Rule::cast_expression => self.eval_cast_expression(token)?,
698            Rule::negate_op => {
699                let unary_token = pair.next().unwrap();
700                let unary = self.eval_unary_exp(unary_token)?;
701                Val::Bool(!unary.cast_to_bool())
702            }
703            Rule::bitwise_negate_op => {
704                let unary_token = pair.next().unwrap();
705                let unary = self.eval_unary_exp(unary_token)?;
706                Val::Int(!unary.cast_to_int()?)
707            }
708            _ => unexpected_token!(token),
709        };
710
711        Ok(res)
712    }
713
714    fn eval_argument_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
715        check_rule!(token, Rule::argument_list);
716        let mut pairs = token.into_inner();
717        let token = pairs.next().unwrap();
718
719        self.skip_error += 1;
720
721        let arg = self.eval_expression(token.clone())?;
722        self.skip_error -= 1;
723
724        if let Val::Array(vec) = arg {
725            Ok(vec)
726        } else {
727            Ok(vec![arg])
728        }
729    }
730
731    fn eval_member_access(&mut self, token: Pair<'a>) -> ParserResult<String> {
732        //check_rule!(token, Rule::member_access);
733        let member_name_token = token.into_inner().next().unwrap();
734        let member_name = member_name_token.as_str().to_ascii_lowercase();
735
736        Ok(member_name)
737    }
738
739    fn method_is_static(&mut self, token: Pair<'a>) -> bool {
740        check_rule!(token, Rule::method_invocation);
741        let mut pairs = token.into_inner();
742
743        let access = pairs.next().unwrap();
744        match access.as_rule() {
745            Rule::member_access => false,
746            Rule::static_access => true,
747            _ => unexpected_token!(access),
748        }
749    }
750
751    fn eval_method_invocation(
752        &mut self,
753        token: Pair<'a>,
754        object: &Val,
755    ) -> ParserResult<(String, Vec<Val>)> {
756        check_rule!(token, Rule::method_invocation);
757        let token_string = token.as_str().to_string();
758
759        let mut pairs = token.into_inner();
760
761        let access = pairs.next().unwrap();
762        let method_name = self.eval_member_access(access)?;
763
764        let args = if let Some(token) = pairs.next() {
765            check_rule!(token, Rule::argument_list);
766            match self.eval_argument_list(token) {
767                Ok(args) => args,
768                Err(e) => {
769                    log::info!("eval_argument_list error: {:?}", e);
770
771                    //nevertheless push the function token
772                    self.tokens.push(Token::method(
773                        token_string.clone(),
774                        object.clone().into(),
775                        method_name.clone(),
776                        Vec::new(),
777                    ));
778                    Err(e)?
779                }
780            }
781        } else {
782            Vec::new()
783        };
784
785        self.tokens.push(Token::method(
786            token_string,
787            object.clone().into(),
788            method_name.clone(),
789            args.clone().iter().map(|arg| arg.clone().into()).collect(),
790        ));
791        Ok((method_name, args))
792    }
793
794    fn eval_element_access_ref<'b>(
795        &mut self,
796        token: Pair<'a>,
797        object: &'b mut Val,
798    ) -> ParserResult<&'b mut Val> {
799        let mut pairs = token.into_inner();
800        let index_token = pairs.next().unwrap();
801        check_rule!(index_token, Rule::expression);
802        let index = self.eval_expression(index_token)?;
803        Ok(object.get_index_ref(index)?)
804    }
805
806    fn eval_element_access(&mut self, token: Pair<'a>, object: &Val) -> ParserResult<Val> {
807        let mut pairs = token.into_inner();
808        let index_token = pairs.next().unwrap();
809        check_rule!(index_token, Rule::expression);
810        let index = self.eval_expression(index_token)?;
811        Ok(object.get_index(index)?)
812    }
813
814    fn variable_access<'b>(
815        &mut self,
816        token: Pair<'a>,
817        object: &'b mut Val,
818    ) -> ParserResult<&'b mut Val> {
819        fn get_member_name(token: Pair<'_>) -> &'_ str {
820            token.into_inner().next().unwrap().as_str()
821        }
822        match token.as_rule() {
823            Rule::static_access => {
824                //todo
825                Err(ParserError::NotImplemented(
826                    "modificable static_member".into(),
827                ))
828            }
829            Rule::member_access => Ok(object.member(get_member_name(token))?),
830            Rule::element_access => Ok(self.eval_element_access_ref(token, object)?),
831            _ => unexpected_token!(token),
832        }
833    }
834
835    fn value_access(&mut self, token: Pair<'a>, object: &mut Val) -> ParserResult<Val> {
836        fn get_member_name(token: Pair<'_>) -> &'_ str {
837            token.into_inner().next().unwrap().as_str()
838        }
839        Ok(match token.as_rule() {
840            Rule::static_access => object.readonly_static_member(get_member_name(token))?,
841            Rule::member_access => object.readonly_member(get_member_name(token))?.clone(),
842            Rule::method_invocation => {
843                let static_method = self.method_is_static(token.clone());
844                let (function_name, args) = self.eval_method_invocation(token, object)?;
845                if static_method {
846                    let call = object.static_method(function_name.as_str())?;
847                    call(args)?
848                } else {
849                    let call = object.method(function_name.as_str())?;
850                    call(object, args)?
851                }
852            }
853            Rule::element_access => self.eval_element_access(token, object)?,
854            _ => unexpected_token!(token),
855        })
856    }
857
858    fn eval_value_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
859        check_rule!(token, Rule::value_access);
860        let mut pairs = token.into_inner();
861        let token = pairs.next().unwrap();
862
863        let mut object = self.eval_value(token)?;
864        for token in pairs {
865            object = self.value_access(token, &mut object)?;
866        }
867        log::debug!("Success eval_access: {:?}", object);
868        Ok(object)
869    }
870
871    fn parse_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
872        check_rule!(token, Rule::value_access);
873        let mut pairs = token.into_inner();
874        let token = pairs.next().unwrap();
875
876        let mut object = self
877            .eval_value(token.clone())
878            .map(|v| v.cast_to_script())
879            .unwrap_or(token.as_str().to_string());
880
881        for token in pairs {
882            match token.as_rule() {
883                Rule::static_access => {
884                    object.push_str(token.as_str());
885                }
886                Rule::member_access => {
887                    object.push_str(token.as_str());
888                }
889                Rule::method_invocation => {
890                    let static_method = self.method_is_static(token.clone());
891                    let (method_name, args) = self
892                        .eval_method_invocation(token.clone(), &Val::ScriptText(object.clone()))?;
893                    log::trace!("Method: {:?} {:?}", &method_name, &args);
894
895                    let separator = if static_method { "::" } else { "." };
896                    object = format!(
897                        "{}{separator}{}({})",
898                        object,
899                        method_name.to_ascii_lowercase(),
900                        args.iter()
901                            .map(|arg| arg.cast_to_script())
902                            .collect::<Vec<String>>()
903                            .join(", ")
904                    )
905                }
906                Rule::element_access => {
907                    let mut pairs = token.into_inner();
908                    let index_token = pairs.next().unwrap();
909                    check_rule!(index_token, Rule::expression);
910                    let index = self.eval_expression(index_token)?;
911                    object = format!("{}[{}]", object, index);
912                }
913                _ => unexpected_token!(token),
914            }
915        }
916        Ok(Val::String(object.into()))
917    }
918
919    fn eval_primary_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
920        check_rule!(token, Rule::primary_expression);
921        let mut pair = token.into_inner();
922        let token = pair.next().unwrap();
923        let res = match token.as_rule() {
924            Rule::value_access => match self.eval_value_access(token.clone()) {
925                Ok(res) => res,
926                Err(err) => {
927                    log::info!("eval_access error: {:?}", err);
928                    self.errors.push(err);
929                    self.parse_access(token)?
930                }
931            },
932            Rule::value => self.eval_value(token)?,
933            Rule::post_inc_expression => {
934                let variable_token = token.into_inner().next().unwrap();
935                let var_name = Self::parse_variable(variable_token)?;
936                let mut var = self.variables.get(&var_name).unwrap_or_default();
937                let var_to_return = var.clone();
938
939                var.inc()?;
940                self.variables.set(&var_name, var.clone())?;
941
942                //if var_to_return.ttype() ==
943                var_to_return
944            }
945            Rule::post_dec_expression => {
946                let variable_token = token.into_inner().next().unwrap();
947                let var_name = Self::parse_variable(variable_token)?;
948                let mut var = self.variables.get(&var_name).unwrap_or_default();
949                let var_to_return = var.clone();
950
951                var.dec()?;
952                self.variables.set(&var_name, var.clone())?;
953
954                var_to_return
955            }
956            _ => unexpected_token!(token),
957        };
958
959        Ok(res)
960    }
961
962    fn get_valtype_from_type_literal(&mut self, token: Pair<'a>) -> ParserResult<ValType> {
963        check_rule!(token, Rule::type_literal);
964
965        let token = token.into_inner().next().unwrap();
966        check_rule!(token, Rule::type_spec);
967        Ok(ValType::cast(token.as_str())?)
968    }
969
970    fn eval_type_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
971        check_rule!(token, Rule::type_literal);
972
973        let token = token.into_inner().next().unwrap();
974        check_rule!(token, Rule::type_spec);
975        Ok(ValType::runtime_type_from_str(token.as_str())?)
976    }
977
978    fn parse_script_block(&mut self, token: Pair<'a>) -> ParserResult<ScriptBlock> {
979        check_rule!(token, Rule::script_block);
980
981        let raw_text = token.as_str().to_string();
982
983        let mut pairs = token.into_inner();
984        let Some(token) = pairs.next() else {
985            return Ok(ScriptBlock::new(vec![], String::new(), raw_text));
986        };
987
988        let params = self.parse_script_param_block(token.clone())?;
989        //let params_str = token.as_str().to_string();
990
991        let script_body = if let Some(token) = pairs.next() {
992            check_rule!(token, Rule::script_block_body);
993            token.as_str().to_string()
994        } else {
995            String::new()
996        };
997
998        Ok(ScriptBlock::new(params, script_body, raw_text))
999
1000        //todo is it necessary?
1001        // Ok(if let Ok(deobfuscated_body) =
1002        // self.deobfuscate_script(&script_body) {
1003        //     ScriptBlock::new(params, deobfuscated_body.clone(),
1004        // format!("{};{}", params_str, deobfuscated_body)) } else {
1005        //     ScriptBlock::new(params, script_body, raw_text)
1006        // })
1007    }
1008
1009    fn parse_script_block_expression(&mut self, token: Pair<'a>) -> ParserResult<ScriptBlock> {
1010        check_rule!(token, Rule::script_block_expression);
1011        let mut pairs = token.into_inner();
1012        self.parse_script_block(pairs.next().unwrap())
1013    }
1014
1015    fn eval_hash_key(&mut self, token: Pair<'a>) -> ParserResult<String> {
1016        check_rule!(token, Rule::key_expression);
1017        let mut pairs = token.into_inner();
1018        let key_token = pairs.next().unwrap();
1019
1020        Ok(match key_token.as_rule() {
1021            Rule::simple_name => key_token.as_str().to_ascii_lowercase(),
1022            Rule::unary_exp => self
1023                .eval_unary_exp(key_token)?
1024                .cast_to_string()
1025                .to_ascii_lowercase(),
1026            _ => unexpected_token!(key_token),
1027        })
1028    }
1029
1030    fn eval_hash_entry(&mut self, token: Pair<'a>) -> ParserResult<(String, Val)> {
1031        check_rule!(token, Rule::hash_entry);
1032
1033        let mut pairs = token.into_inner();
1034        let token_key = pairs.next().unwrap();
1035        let token_value = pairs.next().unwrap();
1036        let value = match token_value.as_rule() {
1037            //Rule::statement => self.eval_statement(token_value)?,
1038            Rule::type_literal => self.eval_type_literal(token_value)?,
1039            _ => self.eval_statement(token_value)?,
1040        };
1041
1042        Ok((self.eval_hash_key(token_key)?, value))
1043    }
1044
1045    fn eval_hash_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1046        check_rule!(token, Rule::hash_literal_expression);
1047        let pairs = token.into_inner();
1048        let mut hash = HashMap::new();
1049        for token in pairs {
1050            let (key, value) = self.eval_hash_entry(token)?;
1051            hash.insert(key, value);
1052        }
1053        Ok(Val::HashTable(hash))
1054    }
1055
1056    // fn get_variable_access(&mut self, token: Pair<'a>) -> ParserResult<&mut Val>
1057    // {     check_rule!(token, Rule::variable_access);
1058    //     let mut pair = token.into_inner();
1059    //     let var_token = pair.next().unwrap();
1060    //     let mut object = self.get_variable(var_token)?;
1061    //     let access_token = pair.next().unwrap();
1062    //     Ok(self.eval_element_access(access_token, &mut object)?)
1063    // }
1064
1065    fn eval_value(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1066        check_rule!(token, Rule::value);
1067        let mut pair = token.into_inner();
1068        let token = pair.next().unwrap();
1069
1070        let res = match token.as_rule() {
1071            Rule::parenthesized_expression => {
1072                let token = token.into_inner().next().unwrap();
1073                self.safe_eval_pipeline(token)?
1074            }
1075            Rule::sub_expression | Rule::array_expression => {
1076                let statements = self.eval_statements(token)?;
1077                if statements.len() == 1 {
1078                    if let Val::Array(_) = statements[0] {
1079                        statements[0].clone()
1080                    } else {
1081                        Val::Array(statements)
1082                    }
1083                } else {
1084                    Val::Array(statements)
1085                }
1086            }
1087            Rule::script_block_expression => {
1088                Val::ScriptBlock(self.parse_script_block_expression(token)?)
1089            }
1090            Rule::hash_literal_expression => self.eval_hash_literal(token)?,
1091            Rule::string_literal => self.eval_string_literal(token)?,
1092            Rule::number_literal => self.eval_number_literal(token)?,
1093            Rule::type_literal => self.eval_type_literal(token)?,
1094            Rule::variable => self.get_variable(token)?,
1095            _ => unexpected_token!(token),
1096        };
1097        log::debug!("eval_value - res: {:?}", res);
1098        Ok(res)
1099    }
1100
1101    fn eval_number_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1102        check_rule!(token, Rule::number_literal);
1103        let mut negate = false;
1104        let mut pairs = token.into_inner();
1105        let mut token = pairs.next().unwrap();
1106
1107        //first handle prefix sign: + or -
1108        if token.as_rule() == Rule::minus {
1109            negate = true;
1110            token = pairs.next().unwrap();
1111        } else if token.as_rule() == Rule::plus {
1112            token = pairs.next().unwrap();
1113        }
1114
1115        let mut val = self.eval_number(token)?;
1116
1117        if negate {
1118            val.neg()?;
1119        }
1120
1121        if let Some(unit) = pairs.next() {
1122            let unit = unit.as_str().to_ascii_lowercase();
1123            let unit_int = match unit.as_str() {
1124                "k" => 1024,
1125                "m" => 1024 * 1024,
1126                "g" => 1024 * 1024 * 1024,
1127                "t" => 1024 * 1024 * 1024 * 1024,
1128                "p" => 1024 * 1024 * 1024 * 1024 * 1024,
1129                _ => 1,
1130            };
1131            val.mul(Val::Int(unit_int))?;
1132        }
1133        Ok(val)
1134    }
1135
1136    fn eval_number(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1137        check_rule!(token, Rule::number);
1138        let mut pairs = token.into_inner();
1139        let token = pairs.next().unwrap();
1140        let v = match token.as_rule() {
1141            Rule::decimal_integer => {
1142                let int_val = token.into_inner().next().unwrap();
1143                Val::Int(int_val.as_str().parse::<i64>().unwrap())
1144            }
1145            Rule::hex_integer => {
1146                let int_val = token.into_inner().next().unwrap();
1147                Val::Int(i64::from_str_radix(int_val.as_str(), 16).unwrap())
1148            }
1149            Rule::float => {
1150                let float_str = token.as_str().trim();
1151                Val::Float(float_str.parse::<f64>()?)
1152                //todo: handle all border cases
1153            }
1154            _ => unexpected_token!(token),
1155        };
1156        Ok(v)
1157    }
1158
1159    fn eval_unary_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1160        check_rule!(token, Rule::unary_exp);
1161        let token = token.into_inner().next().unwrap();
1162        match token.as_rule() {
1163            Rule::expression_with_unary_operator => self.eval_expression_with_unary_operator(token),
1164            Rule::primary_expression => self.eval_primary_expression(token),
1165            _ => unexpected_token!(token),
1166        }
1167    }
1168
1169    fn eval_array_literal_exp_special_case(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1170        check_rule!(token, Rule::array_literal_exp_special_case);
1171        let mut pairs = token.into_inner();
1172        let token = pairs.next().unwrap();
1173
1174        let val = self.eval_array_literal_exp(token)?;
1175        Ok(Val::Array(vec![val]))
1176    }
1177
1178    fn safe_parse_arg(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1179        Ok(if self.skip_error > 0 {
1180            match self.eval_unary_exp(token.clone()) {
1181                Ok(val) => val,
1182                Err(err) => {
1183                    self.errors.push(err);
1184                    Val::ScriptText(token.as_str().to_string())
1185                }
1186            }
1187        } else {
1188            self.eval_unary_exp(token.clone())?
1189        })
1190    }
1191
1192    fn eval_array_literal_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1193        check_rule!(token, Rule::array_literal_exp);
1194        let mut arr = Vec::new();
1195        let mut pairs = token.into_inner();
1196        let token = pairs.next().unwrap();
1197
1198        //if array literal starts with ',' we must eval single element as array too
1199        if let Rule::array_literal_exp_special_case = token.as_rule() {
1200            return self.eval_array_literal_exp_special_case(token);
1201        }
1202
1203        arr.push(self.safe_parse_arg(token)?);
1204        for token in pairs {
1205            arr.push(self.safe_parse_arg(token)?);
1206        }
1207
1208        Ok(if arr.len() == 1 {
1209            arr[0].clone()
1210        } else {
1211            Val::Array(arr)
1212        })
1213    }
1214
1215    fn eval_range_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1216        fn range(mut left: i64, right: i64) -> Vec<Val> {
1217            let mut v = Vec::new();
1218            if left <= right {
1219                loop {
1220                    v.push(left);
1221                    if left == right {
1222                        break;
1223                    }
1224                    left += 1;
1225                }
1226            } else {
1227                loop {
1228                    v.push(left);
1229                    if left == right {
1230                        break;
1231                    }
1232                    left -= 1;
1233                }
1234            }
1235            v.into_iter().map(Val::Int).collect()
1236        }
1237        check_rule!(token, Rule::range_exp);
1238        let mut pairs = token.into_inner();
1239        let token = pairs.next().unwrap();
1240        let res = match token.as_rule() {
1241            Rule::decimal_integer => {
1242                let int_val = token.into_inner().next().unwrap();
1243                let left = int_val.as_str().parse::<i64>().unwrap();
1244                let token = pairs.next().unwrap();
1245                let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
1246                Val::Array(range(left, right))
1247            }
1248            Rule::array_literal_exp => {
1249                let res = self.eval_array_literal_exp(token)?;
1250                if let Some(token) = pairs.next() {
1251                    let left = res.cast_to_int()?;
1252                    let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
1253                    Val::Array(range(left, right))
1254                } else {
1255                    res
1256                }
1257            }
1258            _ => unexpected_token!(token),
1259        };
1260
1261        Ok(res)
1262    }
1263
1264    fn eval_format_impl(&mut self, format: Val, mut pairs: Pairs<'a>) -> ParserResult<Val> {
1265        fn format_with_vec(fmt: &str, args: Vec<Val>) -> ParserResult<String> {
1266            fn strange_special_case(fmt: &str, n: i64) -> String {
1267                fn split_digits(n: i64) -> Vec<u8> {
1268                    n.abs() // ignore sign for digit splitting
1269                        .to_string()
1270                        .chars()
1271                        .filter_map(|c| c.to_digit(10).map(|opt| opt as u8))
1272                        .collect()
1273                }
1274
1275                //"{0:31sdfg,0100a0b00}" -f 578 evals to 310100a5b78
1276                let mut digits = split_digits(n);
1277                digits.reverse();
1278                let mut fmt_vec = fmt.as_bytes().to_vec();
1279                fmt_vec.reverse();
1280
1281                let mut i = 0;
1282                for digit in digits {
1283                    while i < fmt_vec.len() {
1284                        if fmt_vec[i] != b'0' {
1285                            i += 1
1286                        } else {
1287                            fmt_vec[i] = digit + b'0';
1288                            break;
1289                        }
1290                    }
1291                }
1292                fmt_vec.reverse();
1293                String::from_utf8(fmt_vec).unwrap_or_default()
1294            }
1295
1296            let mut output = String::new();
1297            let mut i = 0;
1298
1299            while i < fmt.len() {
1300                if fmt[i..].starts_with('{') {
1301                    if let Some(end) = fmt[i..].find('}') {
1302                        let token = &fmt[i + 1..i + end];
1303                        let formatted = if token.contains(':') {
1304                            let mut parts = token.split(':');
1305                            let index: usize = if let Some(p) = parts.next() {
1306                                p.parse().unwrap_or(0)
1307                            } else {
1308                                0
1309                            };
1310
1311                            let spec = parts.next();
1312                            match args.get(index) {
1313                                Some(val) => match spec {
1314                                    Some(s) if s.starts_with('N') => {
1315                                        let precision = s[1..].parse::<usize>().unwrap_or(2);
1316                                        if let Ok(f) = val.cast_to_float() {
1317                                            format!("{:.1$}", f, precision)
1318                                        } else {
1319                                            val.cast_to_string().to_string()
1320                                        }
1321                                    }
1322                                    Some(s) => strange_special_case(s, val.cast_to_int()?),
1323                                    None => val.cast_to_string().to_string(),
1324                                },
1325                                None => format!("{{{}}}", token), /* leave as-is if index out of
1326                                                                   * bounds */
1327                            }
1328                        } else if token.contains(',') {
1329                            let mut parts = token.split(',');
1330                            let index: usize = parts.next().unwrap().parse().unwrap_or(0);
1331                            let spec = parts.next();
1332                            match args.get(index) {
1333                                Some(val) => match spec {
1334                                    Some(s) => {
1335                                        let spaces = s.parse::<usize>().unwrap_or(0);
1336                                        let spaces_str = " ".repeat(spaces);
1337                                        format!("{spaces_str}{}", val.cast_to_string())
1338                                    }
1339                                    _ => val.cast_to_string().to_string(),
1340                                },
1341                                None => format!("{{{}}}", token), /* leave as-is if index out of
1342                                                                   * bounds */
1343                            }
1344                        } else {
1345                            let index: usize =
1346                                Val::String(token.to_string().into()).cast_to_int()? as usize;
1347                            match args.get(index) {
1348                                Some(val) => val.cast_to_string().to_string(),
1349                                None => format!("{{{}}}", token), /* leave as-is if index out of
1350                                                                   * bounds */
1351                            }
1352                        };
1353
1354                        output.push_str(&formatted);
1355                        i += end + 1;
1356                    } else {
1357                        output.push('{');
1358                        i += 1;
1359                    }
1360                } else {
1361                    output.push(fmt[i..].chars().next().unwrap());
1362                    i += 1;
1363                }
1364            }
1365
1366            Ok(output)
1367        }
1368
1369        Ok(if let Some(token) = pairs.next() {
1370            let first_fmt = format.cast_to_string();
1371
1372            let second_fmt = self.eval_range_exp(token)?;
1373            let res = self.eval_format_impl(second_fmt, pairs)?;
1374            Val::String(format_with_vec(first_fmt.as_str(), res.cast_to_array())?.into())
1375        } else {
1376            format
1377        })
1378    }
1379
1380    fn eval_format_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1381        check_rule!(token, Rule::format_exp);
1382        let mut pairs = token.into_inner();
1383        let format = self.eval_range_exp(pairs.next().unwrap())?;
1384        self.eval_format_impl(format, pairs)
1385    }
1386
1387    fn eval_mult(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1388        check_rule!(token, Rule::multiplicative_exp);
1389        let mut pairs = token.into_inner();
1390        let mut res = self.eval_format_exp(pairs.next().unwrap())?;
1391        while let Some(op) = pairs.next() {
1392            let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1393                log::error!("No arithmetic function for operator: {}", op.as_str());
1394                return Err(ParserError::NotImplemented(format!(
1395                    "No arithmetic function for operator: {}",
1396                    op.as_str()
1397                )));
1398            };
1399
1400            let postfix = pairs.next().unwrap();
1401            let right_op = self.eval_format_exp(postfix)?;
1402            res = fun(res, right_op)?;
1403        }
1404
1405        Ok(res)
1406    }
1407
1408    fn eval_additive(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1409        check_rule!(token, Rule::additive_exp);
1410
1411        let mut pairs = token.into_inner();
1412        let mut res = self.eval_mult(pairs.next().unwrap())?;
1413        while let Some(op) = pairs.next() {
1414            //check_rule!(op, Rule::additive_op); plus or minus
1415            let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1416                log::error!("No arithmetic function for operator: {}", op.as_str());
1417                return Err(ParserError::NotImplemented(format!(
1418                    "No arithmetic function for operator: {}",
1419                    op.as_str()
1420                )));
1421            };
1422
1423            let mult = pairs.next().unwrap();
1424            let right_op = self.eval_mult(mult)?;
1425            res = fun(res, right_op)?;
1426        }
1427
1428        Ok(res)
1429    }
1430
1431    fn eval_split_special_case(
1432        &mut self,
1433        script_block: ScriptBlock,
1434        input: Val,
1435    ) -> ParserResult<Vec<String>> {
1436        let mut res_vec = vec![];
1437        let mut parts = String::new();
1438        let input_str = input.cast_to_string();
1439        let characters = input_str.chars();
1440
1441        // filtered_elements.join("")
1442        for ch in characters {
1443            let b = match script_block.run(vec![], self, Some(Val::String(ch.to_string().into()))) {
1444                Err(er) => {
1445                    self.errors.push(er);
1446                    false
1447                }
1448                Ok(res) => res.val.cast_to_bool(),
1449            };
1450
1451            if b {
1452                res_vec.push(parts);
1453                parts = String::new();
1454            } else {
1455                parts.push(ch);
1456            }
1457        }
1458        self.variables.reset_ps_item();
1459        Ok(res_vec)
1460    }
1461
1462    fn eval_comparison_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1463        check_rule!(token, Rule::comparison_exp);
1464        let mut pairs = token.into_inner();
1465        let token = pairs.next().unwrap();
1466
1467        // we need to handle strange case. -split and -join can be invoke without
1468        // previous expression, eg. "-join 'some'"
1469        let mut res = if token.as_rule() == Rule::additive_exp {
1470            self.eval_additive(token)?
1471        } else {
1472            Val::Null
1473        };
1474
1475        while let Some(op) = pairs.next() {
1476            let Some(fun) = StringPred::get(op.as_str()) else {
1477                log::error!("No string predicate for operator: {}", op.as_str());
1478                return Err(ParserError::NotImplemented(format!(
1479                    "No string predicate for operator: {}",
1480                    op.as_str()
1481                )));
1482            };
1483
1484            let token = pairs.next().unwrap();
1485            let right_op = match token.as_rule() {
1486                Rule::script_block_expression => {
1487                    let script_block = self.parse_script_block_expression(token)?;
1488
1489                    return Ok(Val::Array(
1490                        self.eval_split_special_case(script_block, res)?
1491                            .into_iter()
1492                            .map(|s| Val::String(s.into()))
1493                            .collect::<Vec<_>>(),
1494                    ));
1495                }
1496                Rule::additive_exp => self.eval_additive(token)?,
1497                //Rule::type_literal => self.eval_type_literal(token)?,
1498                _ => unexpected_token!(token),
1499            };
1500            log::trace!("res: {:?}, right_op: {:?}", &res, &right_op);
1501            res = fun(res, right_op)?;
1502            log::trace!("res: {:?}", &res);
1503        }
1504
1505        Ok(res)
1506    }
1507
1508    fn parse_script_param_block(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1509        check_rule!(token, Rule::script_param_block);
1510        let mut pairs = token.into_inner();
1511        let Some(param_block_token) = pairs.next() else {
1512            return Ok(vec![]);
1513        };
1514        self.parse_param_block(param_block_token)
1515    }
1516
1517    fn parse_param_block(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1518        check_rule!(token, Rule::param_block);
1519        let mut pairs = token.into_inner();
1520
1521        let Some(token) = pairs.next() else {
1522            return Ok(vec![]);
1523        };
1524
1525        let option_param_token = match token.as_rule() {
1526            Rule::attribute_list => {
1527                //self.parse_attribute_list(token)?;
1528                pairs.next()
1529            }
1530            Rule::parameter_list => Some(token),
1531            _ => unexpected_token!(token),
1532        };
1533
1534        let Some(param_token) = option_param_token else {
1535            return Ok(vec![]);
1536        };
1537        self.parse_parameter_list(param_token)
1538    }
1539
1540    fn parse_parameter_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1541        check_rule!(token, Rule::parameter_list);
1542        let mut params = vec![];
1543        let param_list_pairs = token.into_inner();
1544        for script_parameter_token in param_list_pairs {
1545            check_rule!(script_parameter_token, Rule::script_parameter);
1546            params.push(self.parse_script_parameter(script_parameter_token)?);
1547        }
1548        Ok(params)
1549    }
1550
1551    fn parse_attribute_list(&mut self, token: Pair<'a>) -> ParserResult<Option<ValType>> {
1552        check_rule!(token, Rule::attribute_list);
1553        let attribute_list_pairs = token.into_inner();
1554        for attribute_token in attribute_list_pairs {
1555            check_rule!(attribute_token, Rule::attribute);
1556            let attribute_type_token = attribute_token.into_inner().next().unwrap();
1557            match attribute_type_token.as_rule() {
1558                Rule::attribute_info => {
1559                    //skip for now
1560                    continue;
1561                }
1562                Rule::type_literal => {
1563                    return Ok(Some(
1564                        self.get_valtype_from_type_literal(attribute_type_token)?,
1565                    ));
1566                }
1567                _ => unexpected_token!(attribute_type_token),
1568            }
1569        }
1570        Ok(None)
1571    }
1572    fn parse_script_parameter(&mut self, token: Pair<'a>) -> ParserResult<Param> {
1573        check_rule!(token, Rule::script_parameter);
1574        let mut pairs = token.into_inner();
1575        let mut token = pairs.next().unwrap();
1576
1577        let type_literal = if token.as_rule() == Rule::attribute_list {
1578            let type_literal = self.parse_attribute_list(token)?;
1579            token = pairs.next().unwrap();
1580            type_literal
1581        } else {
1582            None
1583        };
1584
1585        check_rule!(token, Rule::variable);
1586        let var_name = Self::parse_variable(token)?;
1587
1588        let default_value = if let Some(default_value_token) = pairs.next() {
1589            check_rule!(default_value_token, Rule::script_parameter_default);
1590            let default_value_expr = default_value_token.into_inner().next().unwrap();
1591            let default_value = self.eval_value(default_value_expr)?;
1592            Some(default_value)
1593        } else {
1594            None
1595        };
1596        Ok(Param::new(type_literal, var_name.name, default_value))
1597    }
1598
1599    fn eval_bitwise_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1600        check_rule!(token, Rule::bitwise_exp);
1601
1602        let mut pairs = token.into_inner();
1603        let mut res = self.eval_as_exp(pairs.next().unwrap())?;
1604        while let Some(op) = pairs.next() {
1605            check_rule!(op, Rule::bitwise_operator);
1606            let Some(fun) = BitwisePred::get(op.as_str()) else {
1607                log::error!("No bitwise predicate for operator: {}", op.as_str());
1608                return Err(ParserError::NotImplemented(format!(
1609                    "No bitwise predicate for operator: {}",
1610                    op.as_str()
1611                )));
1612            };
1613
1614            let mult = pairs.next().unwrap();
1615            let right_op = self.eval_as_exp(mult)?;
1616            res = fun(res, right_op)?;
1617        }
1618
1619        Ok(res)
1620    }
1621
1622    fn eval_as_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1623        check_rule!(token, Rule::as_expression);
1624
1625        let mut pairs = token.into_inner();
1626        let mut res = self.eval_comparison_exp(pairs.next().unwrap())?;
1627        for token in pairs {
1628            let runtime_object = match token.as_rule() {
1629                Rule::type_literal => self.eval_type_literal(token)?,
1630                Rule::comparison_exp => self.eval_comparison_exp(token)?,
1631                _ => unexpected_token!(token),
1632            };
1633
1634            res = res.cast(&runtime_object).unwrap_or_default();
1635        }
1636
1637        Ok(res)
1638    }
1639
1640    fn parse_cmdlet_command_name(&mut self, token: Pair<'a>) -> ParserResult<Command> {
1641        check_rule!(token, Rule::cmdlet_command);
1642
1643        let mut pairs = token.into_inner();
1644        let token = pairs.next().unwrap();
1645        let command_name = match token.as_rule() {
1646            Rule::command_name => token.as_str(),
1647            Rule::where_command_name => "where-object",
1648            Rule::foreach_command_name => "foreach-object",
1649            Rule::powershell_command_name => "powershell",
1650            _ => unexpected_token!(token),
1651        };
1652
1653        let mut command = Command::cmdlet(command_name);
1654        if Rule::command_name == token.as_rule() {
1655            command.set_session_scope(SessionScope::New);
1656        }
1657        Ok(command)
1658    }
1659
1660    fn parse_command_args(&mut self, pairs: Pairs<'a>) -> ParserResult<Vec<CommandElem>> {
1661        let mut args = vec![];
1662        for command_element_token in pairs {
1663            let token_string = command_element_token.as_str().to_string();
1664            match command_element_token.as_rule() {
1665                Rule::command_argument => {
1666                    let arg_token = command_element_token.into_inner().next().unwrap();
1667                    let arg = match arg_token.as_rule() {
1668                        Rule::array_literal_exp => self.eval_array_literal_exp(arg_token)?,
1669                        Rule::script_block_expression => {
1670                            Val::ScriptBlock(self.parse_script_block_expression(arg_token)?)
1671                        }
1672                        Rule::parenthesized_expression => {
1673                            let token = arg_token.into_inner().next().unwrap();
1674                            self.eval_pipeline(token)?
1675                        }
1676                        _ => Val::ScriptText(arg_token.as_str().to_string()),
1677                    };
1678                    args.push(CommandElem::Argument(arg));
1679                }
1680                Rule::command_parameter => {
1681                    args.push(CommandElem::Parameter(token_string.to_ascii_lowercase()))
1682                }
1683                Rule::argument_list => args.push(CommandElem::ArgList(token_string)),
1684                Rule::splatten_arg => {
1685                    let var_name = Self::parse_scoped_variable(command_element_token)?;
1686                    let var = self.variables.get(&var_name).unwrap_or_default();
1687                    if let Val::HashTable(h) = var {
1688                        for (k, v) in h {
1689                            args.push(CommandElem::Parameter(format!("-{}", k)));
1690                            args.push(CommandElem::Argument(v));
1691                        }
1692                    }
1693                }
1694                Rule::redirection => { //todo: implement redirection
1695                }
1696                Rule::stop_parsing => { //todo: stop parsing
1697                }
1698                _ => unexpected_token!(command_element_token),
1699            }
1700        }
1701        Ok(args)
1702    }
1703
1704    fn eval_command(&mut self, token: Pair<'a>, piped_arg: Option<Val>) -> ParserResult<Val> {
1705        check_rule!(token, Rule::command);
1706        let command_str = token.as_str().to_string();
1707
1708        let mut pairs = token.into_inner();
1709        let command_token = pairs.next().unwrap();
1710        let mut command = match command_token.as_rule() {
1711            Rule::cmdlet_command => self.parse_cmdlet_command_name(command_token)?,
1712            Rule::invocation_command => self.parse_invocation_command(command_token)?,
1713            _ => unexpected_token!(command_token),
1714        };
1715
1716        let mut args = self.parse_command_args(pairs)?;
1717        if let Some(arg) = piped_arg {
1718            args.insert(0, CommandElem::Argument(arg));
1719        }
1720
1721        command.with_args(args);
1722        self.tokens
1723            .push(Token::command(command_str, command.name(), command.args()));
1724
1725        match command.execute(self) {
1726            Ok(CommandOutput {
1727                val,
1728                deobfuscated: _deobfuscated,
1729            }) => Ok(val),
1730            Err(e) => {
1731                self.errors.push(e);
1732                Ok(Val::ScriptText(command.to_string()))
1733            }
1734        }
1735
1736        // if let Some(msg) = deobfuscated {
1737        //     self.add_deobfuscated_statement(msg);
1738        // }
1739    }
1740
1741    fn add_deobfuscated_statement(&mut self, msg: String) {
1742        if let Some(last) = self.results.last_mut() {
1743            last.deobfuscated.push(msg);
1744        }
1745    }
1746
1747    fn add_output_statement(&mut self, msg: StreamMessage) {
1748        if let Some(last) = self.results.last_mut() {
1749            last.output.push(msg);
1750        }
1751    }
1752
1753    fn parse_invocation_command(&mut self, token: Pair<'a>) -> ParserResult<Command> {
1754        check_rule!(token, Rule::invocation_command);
1755
1756        let invocation_command_token = token.into_inner().next().unwrap();
1757
1758        let mut session_scope = match invocation_command_token.as_rule() {
1759            Rule::current_scope_invocation_command => SessionScope::Current,
1760            Rule::new_scope_invocation_command => SessionScope::New,
1761            _ => unexpected_token!(invocation_command_token),
1762        };
1763
1764        let token_inner = invocation_command_token.into_inner().next().unwrap();
1765
1766        let mut command = match token_inner.as_rule() {
1767            Rule::cmdlet_command => {
1768                session_scope = SessionScope::New;
1769                self.parse_cmdlet_command_name(token_inner)?
1770            }
1771            Rule::primary_expression => {
1772                let primary = self.eval_primary_expression(token_inner)?;
1773                if let Val::ScriptBlock(script_block) = primary {
1774                    Command::script_block(script_block)
1775                } else {
1776                    Command::cmdlet(&primary.cast_to_script())
1777                }
1778            }
1779            Rule::path_command_name => Command::path(token_inner.as_str()),
1780            _ => unexpected_token!(token_inner),
1781        };
1782
1783        command.set_session_scope(session_scope);
1784        Ok(command)
1785    }
1786
1787    fn eval_redirected_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1788        check_rule!(token, Rule::redirected_expression);
1789
1790        let expression_token = token.into_inner().next().unwrap();
1791        //todo: handle redirections
1792
1793        self.eval_expression(expression_token)
1794    }
1795
1796    fn eval_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1797        check_rule!(token, Rule::expression);
1798        let token_string = token.as_str().trim().to_string();
1799
1800        let mut pairs = token.into_inner();
1801        let mut res = self.eval_bitwise_exp(pairs.next().unwrap())?;
1802        while let Some(op) = pairs.next() {
1803            check_rule!(op, Rule::logical_operator);
1804            let Some(fun) = LogicalPred::get(op.as_str()) else {
1805                log::error!("No logical predicate for operator: {}", op.as_str());
1806                return Err(ParserError::NotImplemented(format!(
1807                    "No logical predicate for operator: {}",
1808                    op.as_str()
1809                )));
1810            };
1811
1812            let mult = pairs.next().unwrap();
1813            let right_op = self.eval_bitwise_exp(mult)?;
1814            res = Val::Bool(fun(res, right_op));
1815        }
1816        self.tokens
1817            .push(Token::expression(token_string, res.clone().into()));
1818
1819        if let Val::String(value::PsString(s)) = &res {
1820            self.tokens.push(Token::String(s.clone()));
1821        }
1822
1823        Ok(res)
1824    }
1825
1826    fn eval_pipeline_tail(&mut self, token: Pair<'a>, mut piped_arg: Val) -> ParserResult<Val> {
1827        check_rule!(token, Rule::pipeline_tail);
1828        let pairs = token.into_inner();
1829
1830        for token in pairs {
1831            //self.variables.set_ps_item(arg);
1832            piped_arg = self.eval_command(token, Some(piped_arg))?;
1833        }
1834
1835        Ok(piped_arg)
1836    }
1837
1838    fn eval_pipeline_with_tail(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1839        check_rule!(token, Rule::pipeline_with_tail);
1840        let mut pairs = token.into_inner();
1841        let token = pairs.next().unwrap();
1842
1843        let result: Val = match token.as_rule() {
1844            Rule::redirected_expression => self.eval_redirected_expression(token)?,
1845            Rule::command => self.eval_command(token, None)?,
1846            _ => unexpected_token!(token),
1847        };
1848
1849        if let Some(token) = pairs.next() {
1850            match token.as_rule() {
1851                Rule::pipeline_tail => Ok(self.eval_pipeline_tail(token, result)?),
1852                _ => unexpected_token!(token),
1853            }
1854        } else {
1855            Ok(result)
1856        }
1857    }
1858
1859    fn eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1860        check_rule!(token, Rule::pipeline);
1861        let mut pairs = token.into_inner();
1862        let token = pairs.next().unwrap();
1863
1864        match token.as_rule() {
1865            Rule::assignment_exp => self.eval_assigment_exp(token),
1866            Rule::pipeline_with_tail => self.eval_pipeline_with_tail(token),
1867            _ => unexpected_token!(token),
1868        }
1869    }
1870
1871    fn safe_eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1872        let res = self.eval_pipeline(token.clone());
1873
1874        let v = match res {
1875            Ok(val) => val,
1876            Err(err) => {
1877                self.errors.push(err);
1878                Val::ScriptText(token.as_str().to_string())
1879            }
1880        };
1881
1882        Ok(v)
1883    }
1884
1885    fn eval_cast_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1886        check_rule!(token, Rule::cast_expression);
1887
1888        let mut pairs = token.into_inner();
1889        let type_token = pairs.next().unwrap();
1890        check_rule!(type_token, Rule::type_literal);
1891        let val_type = self.eval_type_literal(type_token)?;
1892        let token = pairs.next().unwrap();
1893        let res = match token.as_rule() {
1894            Rule::parenthesized_expression => {
1895                let token = token.into_inner().next().unwrap();
1896                self.safe_eval_pipeline(token)?
1897            }
1898            Rule::unary_exp => self.eval_unary_exp(token)?,
1899            _ => unexpected_token!(token),
1900        };
1901        Ok(res.cast(&val_type)?)
1902    }
1903
1904    fn eval_assigment_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1905        check_rule!(token, Rule::assignment_exp);
1906
1907        let mut specified_type = None;
1908
1909        let mut pairs = token.into_inner();
1910        let mut token = pairs.next().unwrap();
1911        if token.as_rule() == Rule::type_literal {
1912            specified_type = Some(self.eval_type_literal(token)?);
1913            token = pairs.next().unwrap();
1914        }
1915        let (var_name, access) = self.parse_assignable_variable(token)?;
1916        let mut variable = self.variables.get(&var_name).unwrap_or_default();
1917        let mut accessed_elem = &mut variable;
1918
1919        // sometimes we have variable access like $a[0].Property, and we need access
1920        // property by reference
1921        if let Some(access) = access {
1922            for token in access {
1923                accessed_elem = self.variable_access(token, accessed_elem)?;
1924            }
1925        }
1926        let assignement_op = pairs.next().unwrap();
1927
1928        //get operand
1929        let op = assignement_op.into_inner().next().unwrap();
1930        let pred = ArithmeticPred::get(op.as_str());
1931
1932        let right_token = pairs.next().unwrap();
1933        let right_op = self.eval_statement(right_token.clone())?;
1934
1935        let Some(pred) = pred else {
1936            log::error!("No arithmetic function for operator: {}", op.as_str());
1937            return Err(ParserError::NotImplemented(format!(
1938                "No arithmetic function for operator: {}",
1939                op.as_str()
1940            )));
1941        };
1942        *accessed_elem = pred(accessed_elem.clone(), right_op)?;
1943        if let Some(runtime_type) = specified_type {
1944            *accessed_elem = accessed_elem.cast(&runtime_type)?;
1945        }
1946        self.variables.set(&var_name, variable.clone())?;
1947
1948        //we want save each assignment statement
1949        self.add_deobfuscated_statement(format!("{} = {}", var_name, variable.cast_to_script()));
1950
1951        Ok(Val::NonDisplayed(Box::new(variable)))
1952    }
1953
1954    fn push_scope_session(&mut self) {
1955        self.variables.push_scope_session();
1956    }
1957
1958    fn pop_scope_session(&mut self) {
1959        self.variables.pop_scope_session();
1960    }
1961}
1962
1963#[cfg(test)]
1964mod tests {
1965    use pest::Parser;
1966
1967    use super::*;
1968
1969    #[test]
1970    fn comment_and_semicolon() {
1971        let input = r#"
1972# This is a single line comment
1973$a = 1; $b = 2; Write-Output $a
1974
1975Write-Output "Hello"  # Another comment
1976
1977<#
1978    This is a
1979    multi-line block comment
1980#>
1981"#;
1982
1983        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1984    }
1985
1986    #[test]
1987    fn while_loop() {
1988        let input = r#"
1989while ($true) {
1990    if ($someCondition) {
1991        break
1992    }
1993    # other code
1994}
1995"#;
1996
1997        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1998    }
1999
2000    #[test]
2001    fn foreach_loop() {
2002        let input = r#"
2003foreach ($n in $numbers) {
2004    Write-Output $n
2005}
2006"#;
2007
2008        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2009    }
2010
2011    #[test]
2012    fn for_loop() {
2013        let input = r#"
2014# Comma separated assignment expressions enclosed in parentheses.
2015for (($i = 0), ($j = 0); $i -lt 10; $i++)
2016{
2017    "`$i:$i"
2018    "`$j:$j"
2019}
2020"#;
2021
2022        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2023    }
2024
2025    #[test]
2026    fn switch() {
2027        let input = r#"
2028switch ($var) {
2029    "a" { Write-Output "A" }
2030    1 { Write-Output "One" }
2031    default { Write-Output "Other" }
2032}
2033"#;
2034
2035        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2036    }
2037
2038    #[test]
2039    fn functions() {
2040        let input = r#"
2041function Get-Square {
2042    param($x)
2043    return $x * $x
2044}
2045
2046function Say-Hello {
2047    Write-Output "Hello"
2048}
2049"#;
2050
2051        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2052    }
2053
2054    #[test]
2055    fn if_expression() {
2056        let input = r#"
2057$x="hello"
2058        Write-Host $x
2059        $y = 42
2060        Start-Process "notepad.exe"
2061
2062        $x = 42
2063if ($x -eq 1) {
2064    Write-Output "One"
2065} elseif ($x -eq 2) {
2066    Write-Output "Two"
2067} else {
2068    Write-Output "Other"
2069}
2070"#;
2071
2072        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2073    }
2074
2075    #[test]
2076    fn command() {
2077        let input = r#"
2078Get-Process | Where-Object { $_.CPU -gt 100 }
2079"#;
2080
2081        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2082    }
2083
2084    #[test]
2085    fn range() {
2086        let input = r#"
2087$numbers = 1..5
2088"#;
2089
2090        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2091    }
2092
2093    #[test]
2094    fn literals() {
2095        let input = r#"
2096$hex = 0xFF
2097
2098$name = "Alice"
2099$msg = "Hello, $name. Today is $day."
2100$escaped = "She said: `"Hi`""
2101$literal = 'Hello, $name'
2102"#;
2103
2104        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2105    }
2106
2107    #[test]
2108    fn floats() {
2109        let input = r#"
2110    $pi = 3.1415
2111$half = .5
2112"#;
2113
2114        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2115    }
2116
2117    #[test]
2118    fn arrays() {
2119        let input = r#"
2120$a = 1, 2, 3
2121$b = @("one", "two", "three")
2122$c = @(1, 2, @(3, 4))
2123"#;
2124
2125        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2126    }
2127
2128    #[test]
2129    fn static_method_call() {
2130        let input = r#"
2131[Threading.Thread]::Sleep(399)
2132"#;
2133
2134        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2135    }
2136
2137    #[test]
2138    fn neg_pipeline() {
2139        let input = r#"
2140-not $input | Where-Object { $_ -gt 5 }
2141"#;
2142
2143        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2144    }
2145
2146    #[test]
2147    fn amsi_fail() {
2148        let input = r#"
2149#Matt Graebers second Reflection method 
2150$VMRviwsbtehQfPtxbt=$null;
2151$ilryNQSTt="System.$([cHAR]([ByTE]0x4d)+[ChAR]([byte]0x61)+[chAr](110)+[cHar]([byTE]0x61)+[cHaR](103)+[cHar](101*64/64)+[chaR]([byTE]0x6d)+[cHAr](101)+[CHAr]([byTE]0x6e)+[Char](116*103/103)).$([Char]([ByTe]0x41)+[Char](117+70-70)+[CHAr]([ByTE]0x74)+[CHar]([bYte]0x6f)+[CHar]([bytE]0x6d)+[ChaR]([ByTe]0x61)+[CHar]([bYte]0x74)+[CHAR]([byte]0x69)+[Char](111*26/26)+[chAr]([BYTe]0x6e)).$(('Âmsí'+'Ùtìl'+'s').NORmalizE([ChAR](44+26)+[chAR](111*9/9)+[cHar](82+32)+[ChaR](109*34/34)+[cHaR](68+24-24)) -replace [ChAr](92)+[CHaR]([BYTe]0x70)+[Char]([BytE]0x7b)+[CHaR]([BYTe]0x4d)+[chAR](110)+[ChAr](15+110))"
2152
2153"#;
2154
2155        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2156    }
2157}