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