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