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