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