ps_parser/
parser.rs

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