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 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 pub fn with_variables(mut self, variables: Variables) -> Self {
187 self.variables = variables;
188 self
189 }
190
191 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 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 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 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 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 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 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 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 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, Rule::flow_control_pipeline_statement => {
565 let token = token.into_inner().try_next()?;
566 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, _ => 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 self.statement_block_collect_tokens(clause_body.clone());
619
620 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 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 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(), ¶meters);
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 }
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 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 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 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 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 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 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 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 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 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 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 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 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::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 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 }
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 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 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 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 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 _ => 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 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 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 => { }
2058 Rule::stop_parsing => { }
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 }
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 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 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 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 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 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}