Skip to main content

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