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 not_implemented!(token)
961 }
962 }
963 }
964
965 fn safe_eval_sub_expr(&mut self, token: Pair<'a>) -> ParserResult<Val> {
966 check_rule!(token, Rule::sub_expression);
967 let Some(inner_token) = token.into_inner().next() else {
968 return Ok(Val::Null);
969 };
970 let mut inner_val = self.eval_pipeline(inner_token)?;
971 if let Val::ScriptText(script) = &mut inner_val {
972 *script = format!("$({})", script);
973 }
975 Ok(inner_val)
976 }
977
978 fn eval_statement_block(&mut self, token: Pair<'a>) -> ParserResult<Val> {
979 Ok(self
980 .safe_eval_statements(token)?
981 .iter()
982 .last()
983 .cloned()
984 .unwrap_or(Val::Null))
985 }
986
987 fn eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
988 let pairs = token.into_inner();
990 let mut statements = vec![];
991
992 for token in pairs {
993 let s = self.eval_statement(token)?;
994 statements.push(s);
995 }
996 Ok(statements)
997 }
998
999 fn safe_eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
1000 let pairs = token.into_inner();
1002 let mut statements = vec![];
1003
1004 for token in pairs {
1005 match self.eval_statement(token.clone()) {
1006 Ok(s) => statements.push(s),
1007 Err(err) => {
1008 self.errors.push(err);
1009 statements.push(Val::ScriptText(token.as_str().to_string()));
1010 }
1011 }
1012 }
1013 Ok(statements)
1014 }
1015
1016 fn parse_dq(&mut self, token: Pair<'a>) -> ParserResult<String> {
1017 let mut res_str = String::new();
1018 let pairs = token.into_inner();
1019 for token in pairs {
1020 let token = token.into_inner().next().unwrap();
1021 let token_str = token.as_str();
1022 let res = match token.as_rule() {
1023 Rule::variable => self.get_variable(token).map(|v| v.cast_to_string()),
1024 Rule::sub_expression => self.safe_eval_sub_expr(token).map(|v| v.cast_to_string()),
1025 Rule::backtick_escape => Ok(token
1026 .as_str()
1027 .strip_prefix("`")
1028 .unwrap_or_default()
1029 .to_string()),
1030 _ => Ok(token.as_str().to_string()),
1031 };
1032 match res {
1033 Ok(s) => res_str.push_str(s.as_str()),
1034 Err(err) => {
1035 self.errors.push(err);
1036 res_str.push_str(token_str);
1037 }
1038 }
1039 }
1040 Ok(res_str)
1041 }
1042
1043 fn eval_string_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1044 check_rule!(token, Rule::string_literal);
1045 let mut pair = token.into_inner();
1046 let token = pair.next().unwrap();
1047 let cloned_token = token.clone();
1048
1049 let mut is_expandable = false;
1050 let res = match token.as_rule() {
1051 Rule::doublequoted_string_literal | Rule::doublequoted_multiline_string_literal => {
1052 is_expandable = true;
1053 self.parse_dq(token)?
1054 }
1055 Rule::singlequoted_string_literal => {
1056 let token_string = token.as_str().to_string();
1057 let stripped_prefix = token_string
1058 .strip_prefix("'")
1059 .unwrap_or(token_string.as_str());
1060 let stripped_suffix = stripped_prefix.strip_suffix("'").unwrap_or(stripped_prefix);
1061 stripped_suffix.to_string()
1062 }
1063 Rule::singlequoted_multiline_string_literal => {
1064 let mut res_str = String::new();
1065 let pairs = token.into_inner();
1066 for token in pairs {
1067 res_str.push_str(token.as_str());
1068 }
1069 res_str
1070 }
1071 _ => unexpected_token!(token),
1072 };
1073 let ps_token = if is_expandable {
1074 Token::string_expandable(cloned_token.as_str().to_string(), res.clone())
1075 } else {
1076 Token::String(res.clone())
1077 };
1078 self.tokens.push(ps_token);
1079
1080 Ok(Val::String(res.into()))
1081 }
1082
1083 fn get_variable(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1084 check_rule!(token, Rule::variable);
1085 let var_name = Self::parse_variable(token)?;
1086 let Some(var) = self.variables.get(&var_name, &self.types_map) else {
1087 return Err(ParserError::VariableError(VariableError::NotDefined(
1088 var_name.name,
1089 )));
1090 };
1091 Ok(var)
1092 }
1093
1094 fn parse_scoped_variable(token: Pair<'a>) -> ParserResult<VarName> {
1095 let mut pairs = token.into_inner();
1097 let mut token = pairs.next().unwrap();
1098
1099 let scope = if token.as_rule() == Rule::scope_keyword {
1100 let scope = token.as_str().to_ascii_lowercase();
1101 token = pairs.next().unwrap();
1102 check_rule!(token, Rule::var_name);
1103 Some(Scope::from(scope.as_str()))
1104 } else {
1105 None
1106 };
1107 Ok(VarName::new(scope, token.as_str().to_ascii_lowercase()))
1108 }
1109
1110 fn skip_value_access(&mut self, token: Pair<'a>) -> ParserResult<()> {
1111 check_rule!(token, Rule::value_access);
1112 let mut pair = token.into_inner();
1113 let token = pair.next().unwrap();
1114 let mut val = self.eval_value(token)?;
1115 if let Some(access) = pair.next() {
1116 let _ = self.eval_element_access_ref(access, &mut val)?;
1117 }
1118 Err(ParserError::Skip)
1119 }
1120
1121 fn parse_assignable_variable(
1131 &mut self,
1132 token: Pair<'a>,
1133 ) -> ParserResult<(VarName, Option<Pairs<'a>>)> {
1134 check_rule!(token, Rule::assignable_variable);
1135 let mut pair = token.into_inner();
1136 let token = pair.next().unwrap();
1137 match token.as_rule() {
1138 Rule::variable => {
1139 let var_name = Self::parse_variable(token)?;
1140
1141 Ok((var_name, None))
1142 }
1143 Rule::variable_access => {
1144 let mut pairs = token.into_inner();
1145 let var_token = pairs.next().unwrap();
1146 let var_name = Self::parse_variable(var_token)?;
1147 Ok((var_name, Some(pairs)))
1152 }
1153 Rule::value_access => self
1154 .skip_value_access(token)
1155 .map(|()| (Default::default(), None)),
1156 _ => unexpected_token!(token),
1157 }
1158 }
1159
1160 fn parse_variable(token: Pair<'a>) -> ParserResult<VarName> {
1161 check_rule!(token, Rule::variable);
1162 let mut pair = token.into_inner();
1163 let token = pair.next().unwrap();
1164
1165 Ok(match token.as_rule() {
1166 Rule::special_variable => {
1167 VarName::new_with_scope(Scope::Special, token.as_str().to_string())
1168 }
1169 Rule::parenthesized_variable => {
1170 Self::parse_variable(token.into_inner().next().unwrap())?
1171 }
1172 Rule::braced_variable => {
1173 let token = token.into_inner().next().unwrap();
1174 let var = token.as_str().to_ascii_lowercase();
1175 let splits: Vec<&str> = var.split(":").collect();
1176 if splits.len() == 2 {
1177 VarName::new_with_scope(Scope::from(splits[0]), splits[1].to_string())
1178 } else {
1179 VarName::new(None, var)
1180 }
1181 }
1182 Rule::scoped_variable => Self::parse_scoped_variable(token)?,
1183 _ => unexpected_token!(token),
1184 })
1185 }
1186
1187 fn eval_pre_arithmetic(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1188 check_rule!(token, Rule::pre_arithmetic);
1189 let mut pair = token.into_inner();
1190 let token = pair.next().unwrap();
1191
1192 let res = match token.as_rule() {
1193 Rule::pre_plus_expression => {
1194 let token = token.into_inner().next().unwrap();
1195 match token.as_rule() {
1196 Rule::variable => {
1197 let var_name = Self::parse_variable(token)?;
1198 self.variables
1199 .get(&var_name, &self.types_map)
1200 .unwrap_or_default()
1201 }
1202 Rule::parenthesized_expression => self.eval_parenthesized_expression(token)?,
1203 _ => unexpected_token!(token),
1204 }
1205 }
1206 Rule::pre_minus_expression => {
1207 let token = token.into_inner().next().unwrap();
1208 let mut v = Val::default();
1209 let to_sub = match token.as_rule() {
1210 Rule::variable => {
1211 let var_name = Self::parse_variable(token)?;
1212 self.variables
1213 .get(&var_name, &self.types_map)
1214 .unwrap_or_default()
1215 }
1216 Rule::parenthesized_expression => self.eval_parenthesized_expression(token)?,
1217 _ => unexpected_token!(token),
1218 };
1219 v.sub(to_sub)?;
1220 v
1221 }
1222 Rule::pre_inc_expression => {
1223 let variable_token = token.into_inner().next().unwrap();
1224 let var_name = Self::parse_variable(variable_token)?;
1225 let mut var = self
1226 .variables
1227 .get(&var_name, &self.types_map)
1228 .unwrap_or_default();
1229 var.inc()?;
1230
1231 self.variables.set(&var_name, var.clone())?;
1232 var
1233 }
1234 Rule::pre_dec_expression => {
1235 let variable_token = token.into_inner().next().unwrap();
1236 let var_name = Self::parse_variable(variable_token)?;
1237 let mut var = self
1238 .variables
1239 .get(&var_name, &self.types_map)
1240 .unwrap_or_default();
1241 var.dec()?;
1242
1243 self.variables.set(&var_name, var.clone())?;
1244 var
1245 }
1246 _ => unexpected_token!(token),
1247 };
1248
1249 Ok(res)
1250 }
1251
1252 fn eval_expression_with_unary_operator(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1253 check_rule!(token, Rule::expression_with_unary_operator);
1254 let mut pair = token.into_inner();
1255 let token = pair.next().unwrap();
1256
1257 let res = match token.as_rule() {
1258 Rule::pre_arithmetic => self.eval_pre_arithmetic(token)?,
1259 Rule::cast_expression => self.eval_cast_expression(token)?,
1260 Rule::negate_op => {
1261 let unary_token = pair.next().unwrap();
1262 let unary = self.eval_unary_exp(unary_token)?;
1263 Val::Bool(!unary.cast_to_bool())
1264 }
1265 Rule::bitwise_negate_op => {
1266 let unary_token = pair.next().unwrap();
1267 let unary = self.eval_unary_exp(unary_token)?;
1268 Val::Int(!unary.cast_to_int()?)
1269 }
1270 _ => unexpected_token!(token),
1271 };
1272
1273 Ok(res)
1274 }
1275
1276 fn eval_argument_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
1277 check_rule!(token, Rule::argument_list);
1278 let mut pairs = token.into_inner();
1279 let token = pairs.next().unwrap();
1280
1281 self.skip_error += 1;
1282
1283 let arg = self.eval_expression(token.clone())?;
1284 self.skip_error -= 1;
1285
1286 if let Val::Array(vec) = arg {
1287 Ok(vec)
1288 } else {
1289 Ok(vec![arg])
1290 }
1291 }
1292
1293 fn eval_member_access(&mut self, token: Pair<'a>) -> ParserResult<String> {
1294 let member_name_token = token.into_inner().next().unwrap();
1296 let member_name = member_name_token.as_str().to_ascii_lowercase();
1297
1298 Ok(member_name)
1299 }
1300
1301 fn method_is_static(&mut self, token: Pair<'a>) -> bool {
1302 check_rule!(token, Rule::method_invocation);
1303 let mut pairs = token.into_inner();
1304
1305 let access = pairs.next().unwrap();
1306 match access.as_rule() {
1307 Rule::member_access => false,
1308 Rule::static_access => true,
1309 _ => unexpected_token!(access),
1310 }
1311 }
1312
1313 fn eval_method_invocation(
1314 &mut self,
1315 token: Pair<'a>,
1316 object: &Val,
1317 ) -> ParserResult<(String, Vec<Val>)> {
1318 check_rule!(token, Rule::method_invocation);
1319 let token_string = token.as_str().to_string();
1320
1321 let mut pairs = token.into_inner();
1322
1323 let access = pairs.next().unwrap();
1324 let method_name = self.eval_member_access(access)?;
1325
1326 let args = if let Some(token) = pairs.next() {
1327 check_rule!(token, Rule::argument_list);
1328 match self.eval_argument_list(token) {
1329 Ok(args) => args,
1330 Err(e) => {
1331 log::debug!("eval_argument_list error: {:?}", e);
1332
1333 self.tokens.push(Token::method(
1335 token_string.clone(),
1336 object.clone().into(),
1337 method_name.clone(),
1338 Vec::new(),
1339 ));
1340 Err(e)?
1341 }
1342 }
1343 } else {
1344 Vec::new()
1345 };
1346
1347 self.tokens.push(Token::method(
1348 token_string,
1349 object.clone().into(),
1350 method_name.clone(),
1351 args.clone().iter().map(|arg| arg.clone().into()).collect(),
1352 ));
1353 Ok((method_name, args))
1354 }
1355
1356 fn eval_element_access_ref<'b>(
1357 &mut self,
1358 token: Pair<'a>,
1359 object: &'b mut Val,
1360 ) -> ParserResult<&'b mut Val> {
1361 let mut pairs = token.into_inner();
1362 let index_token = pairs.next().unwrap();
1363 check_rule!(index_token, Rule::expression);
1364 let index = self.eval_expression(index_token)?;
1365 Ok(object.get_index_ref(index)?)
1366 }
1367
1368 fn eval_element_access(&mut self, token: Pair<'a>, object: &Val) -> ParserResult<Val> {
1369 let key = (token.as_str().as_ptr() as usize, token.as_str().len());
1370 let mut pairs = token.into_inner();
1371 let index_token = pairs.next().unwrap();
1372 check_rule!(index_token, Rule::expression);
1373 let index = self.eval_expression(index_token)?;
1374 object.get_index(index.clone()).map_err(|err| {
1375 self.failed_index = Some((key, index));
1376 err.into()
1377 })
1378 }
1379
1380 fn variable_access<'b>(
1381 &mut self,
1382 token: Pair<'a>,
1383 object: &'b mut Val,
1384 ) -> ParserResult<&'b mut Val> {
1385 fn get_member_name(token: Pair<'_>) -> &'_ str {
1386 token.into_inner().next().unwrap().as_str()
1387 }
1388 match token.as_rule() {
1389 Rule::static_access => {
1390 Err(ParserError::NotImplemented(
1392 "modificable static_member".into(),
1393 ))
1394 }
1395 Rule::member_access => Ok(object.member(get_member_name(token))?),
1396 Rule::element_access => Ok(self.eval_element_access_ref(token, object)?),
1397 _ => unexpected_token!(token),
1398 }
1399 }
1400
1401 fn value_access(&mut self, token: Pair<'a>, object: &mut Val) -> ParserResult<Val> {
1402 fn get_member_name(token: Pair<'_>) -> &'_ str {
1403 token.into_inner().next().unwrap().as_str()
1404 }
1405 Ok(match token.as_rule() {
1406 Rule::static_access => {
1407 let Val::RuntimeType(rt) = object else {
1408 return Err(RuntimeError::MethodNotFound(
1409 "Readonly static members can only be accessed on types".to_string(),
1410 )
1411 .into());
1412 };
1413 rt.readonly_static_member(get_member_name(token))?
1414 }
1415 Rule::member_access => object.readonly_member(get_member_name(token))?.clone(),
1416 Rule::method_invocation => {
1417 let static_method = self.method_is_static(token.clone());
1418 let (function_name, args) = self.eval_method_invocation(token, object)?;
1419 let mangled_name = MethodName::from_args(function_name.as_str(), &args);
1420
1421 if static_method {
1422 let Val::RuntimeType(rt) = object else {
1423 return Err(RuntimeError::MethodNotFound(
1424 "Static method can be called only on type".to_string(),
1425 )
1426 .into());
1427 };
1428
1429 let mut call = rt.static_method(mangled_name)?;
1430 call(args)?
1431 } else {
1432 let mut call = object.method(mangled_name)?;
1433 call(object, args)?
1434 }
1435 }
1436 Rule::element_access => self.eval_element_access(token, object)?,
1437 _ => unexpected_token!(token),
1438 })
1439 }
1440
1441 fn eval_value_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1442 check_rule!(token, Rule::value_access);
1443 let mut pairs = token.into_inner();
1444 let token = pairs.next().unwrap();
1445
1446 let mut object = self.eval_value(token)?;
1447 for token in pairs {
1448 object = self.value_access(token, &mut object)?;
1449 }
1450 log::debug!("Success eval_access: {:?}", object);
1451 Ok(object)
1452 }
1453
1454 fn parse_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1455 check_rule!(token, Rule::value_access);
1456 let mut pairs = token.into_inner();
1457 let token = pairs.next().unwrap();
1458
1459 let mut object = self
1460 .eval_value(token.clone())
1461 .map(|v| v.cast_to_script())
1462 .unwrap_or(token.as_str().to_string());
1463
1464 for token in pairs {
1465 match token.as_rule() {
1466 Rule::static_access => {
1467 object.push_str(token.as_str());
1468 }
1469 Rule::member_access => {
1470 object.push_str(token.as_str());
1471 }
1472 Rule::method_invocation => {
1473 let static_method = self.method_is_static(token.clone());
1474 let (method_name, args) = self
1475 .eval_method_invocation(token.clone(), &Val::ScriptText(object.clone()))?;
1476 log::trace!("Method: {:?} {:?}", &method_name, &args);
1477
1478 let separator = if static_method { "::" } else { "." };
1479 object = format!(
1480 "{}{separator}{}({})",
1481 object,
1482 method_name.to_ascii_lowercase(),
1483 args.iter()
1484 .map(|arg| arg.cast_to_script())
1485 .collect::<Vec<String>>()
1486 .join(", ")
1487 )
1488 }
1489 Rule::element_access => {
1490 let key = (token.as_str().as_ptr() as usize, token.as_str().len());
1491 let index = match self.failed_index.take_if(|(failed_key, _)| *failed_key == key) {
1492 Some((_, index)) => index,
1493 _ => {
1494 let mut pairs = token.into_inner();
1495 let index_token = pairs.next().unwrap();
1496 check_rule!(index_token, Rule::expression);
1497 self.eval_expression(index_token)?
1498 }
1499 };
1500 object = format!("{}[{}]", object, index);
1501 }
1502 _ => unexpected_token!(token),
1503 }
1504 }
1505 Ok(Val::String(object.into()))
1506 }
1507
1508 fn eval_primary_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1509 check_rule!(token, Rule::primary_expression);
1510 let mut pair = token.into_inner();
1511 let token = pair.next().unwrap();
1512 let res = match token.as_rule() {
1513 Rule::value_access if token.clone().into_inner().count() == 1 => {
1514 self.eval_value(token.into_inner().next().unwrap())?
1515 }
1516 Rule::value_access => match self.eval_value_access(token.clone()) {
1517 Ok(res) => res,
1518 Err(ParserError::NestingTooDeep) => Err(ParserError::NestingTooDeep)?,
1519 Err(err) => {
1520 log::debug!("eval_access error: {:?}", err);
1521 self.errors.push(err);
1522 self.parse_access(token)?
1523 }
1524 },
1525 Rule::value => self.eval_value(token)?,
1526 Rule::post_inc_expression => {
1527 let variable_token = token.into_inner().next().unwrap();
1528 let var_name = Self::parse_variable(variable_token)?;
1529 let mut var = self
1530 .variables
1531 .get(&var_name, &self.types_map)
1532 .unwrap_or_default();
1533 let var_to_return = var.clone();
1534
1535 var.inc()?;
1536 self.variables.set(&var_name, var.clone())?;
1537
1538 var_to_return
1540 }
1541 Rule::post_dec_expression => {
1542 let variable_token = token.into_inner().next().unwrap();
1543 let var_name = Self::parse_variable(variable_token)?;
1544 let mut var = self
1545 .variables
1546 .get(&var_name, &self.types_map)
1547 .unwrap_or_default();
1548 let var_to_return = var.clone();
1549
1550 var.dec()?;
1551 self.variables.set(&var_name, var.clone())?;
1552
1553 var_to_return
1554 }
1555 _ => unexpected_token!(token),
1556 };
1557
1558 Ok(res)
1559 }
1560
1561 fn get_valtype_from_type_literal(&mut self, token: Pair<'a>) -> ParserResult<ValType> {
1562 let type_literal = self.parse_type_literal(token)?;
1563 Ok(ValType::cast(type_literal.as_str(), &self.types_map)?)
1564 }
1565
1566 fn eval_type_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1567 let type_literal = self.parse_type_literal(token)?;
1568 match ValType::runtime_type_from_str(type_literal.as_str(), &self.types_map) {
1569 Ok(val_type) => Ok(val_type),
1570 Err(err) => {
1571 self.errors.push(err.into());
1572 Ok(Val::Null)
1573 }
1574 }
1575 }
1576
1577 fn parse_type_literal(&mut self, token: Pair<'a>) -> ParserResult<String> {
1578 check_rule!(token, Rule::type_literal);
1579
1580 let token = token.into_inner().next().unwrap();
1581 check_rule!(token, Rule::type_spec);
1582 let type_literal = token.as_str().to_ascii_lowercase();
1583 self.tokens.push(Token::type_literal(type_literal.clone()));
1584 Ok(type_literal)
1585 }
1586
1587 fn parse_script_block(&mut self, token: Pair<'a>) -> ParserResult<ScriptBlock> {
1588 check_rule!(token, Rule::script_block);
1589
1590 let raw_text = token.as_str().to_string();
1591
1592 let mut pairs = token.into_inner();
1593 let Some(token) = pairs.next() else {
1594 return Ok(ScriptBlock::new(vec![], String::new(), raw_text));
1595 };
1596
1597 let params = self.parse_script_param_block(token.clone())?;
1598 let script_body = if let Some(token) = pairs.next() {
1601 check_rule!(token, Rule::script_block_body);
1602 token.as_str().to_string()
1603 } else {
1604 String::new()
1605 };
1606 self.script_block_collect_tokens(&script_body);
1614
1615 Ok(ScriptBlock::new(params, script_body, raw_text))
1616 }
1617
1618 pub(crate) fn script_block_collect_tokens(&mut self, script_body: &str) {
1619 if !self.collected.insert(script_body.to_string()) {
1623 return;
1624 }
1625 let results = self.results.clone();
1626 let current_variables = self.variables.clone();
1627 let errors = self.errors.clone();
1628 if let Err(err) = self.parse_subscript(script_body) {
1629 log::debug!("Error during script_block_collect_tokens: {:?}", err);
1630 }
1631 self.variables = current_variables;
1632 self.results = results;
1633 self.errors = errors;
1634 }
1635
1636 fn parse_script_block_expression(&mut self, token: Pair<'a>) -> ParserResult<ScriptBlock> {
1637 check_rule!(token, Rule::script_block_expression);
1638 let mut pairs = token.into_inner();
1639 self.parse_script_block(pairs.next().unwrap())
1640 }
1641
1642 fn eval_hash_key(&mut self, token: Pair<'a>) -> ParserResult<String> {
1643 check_rule!(token, Rule::key_expression);
1644 let mut pairs = token.into_inner();
1645 let key_token = pairs.next().unwrap();
1646
1647 Ok(match key_token.as_rule() {
1648 Rule::simple_name => key_token.as_str().to_ascii_lowercase(),
1649 Rule::unary_exp => self
1650 .eval_unary_exp(key_token)?
1651 .cast_to_string()
1652 .to_ascii_lowercase(),
1653 _ => unexpected_token!(key_token),
1654 })
1655 }
1656
1657 fn eval_hash_entry(&mut self, token: Pair<'a>) -> ParserResult<(String, Val)> {
1658 check_rule!(token, Rule::hash_entry);
1659
1660 let mut pairs = token.into_inner();
1661 let token_key = pairs.next().unwrap();
1662 let token_value = pairs.next().unwrap();
1663 let value = match token_value.as_rule() {
1664 Rule::type_literal => self.eval_type_literal(token_value)?,
1666 _ => self.eval_statement(token_value)?,
1667 };
1668
1669 Ok((self.eval_hash_key(token_key)?, value))
1670 }
1671
1672 fn eval_hash_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1673 check_rule!(token, Rule::hash_literal_expression);
1674 let pairs = token.into_inner();
1675 let mut hash = HashMap::new();
1676 for token in pairs {
1677 let (key, value) = self.eval_hash_entry(token)?;
1678 hash.insert(key, value);
1679 }
1680 Ok(Val::HashTable(hash))
1681 }
1682
1683 fn eval_parenthesized_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1684 check_rule!(token, Rule::parenthesized_expression);
1685 let token = token.into_inner().next().unwrap();
1686 self.safe_eval_pipeline(token)
1687 }
1688
1689 fn eval_value(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1690 check_rule!(token, Rule::value);
1691 let mut pair = token.into_inner();
1692 let token = pair.next().unwrap();
1693
1694 let res = match token.as_rule() {
1695 Rule::parenthesized_expression => self.eval_parenthesized_expression(token)?,
1696 Rule::sub_expression | Rule::array_expression => {
1697 let statements = self.eval_statements(token)?;
1698 if statements.len() == 1 {
1699 if let Val::Array(_) = statements[0] {
1700 statements[0].clone()
1701 } else {
1702 Val::Array(statements)
1703 }
1704 } else {
1705 Val::Array(statements)
1706 }
1707 }
1708 Rule::script_block_expression => {
1709 Val::ScriptBlock(self.parse_script_block_expression(token)?)
1710 }
1711 Rule::hash_literal_expression => self.eval_hash_literal(token)?,
1712 Rule::string_literal => self.eval_string_literal(token)?,
1713 Rule::number_literal => self.eval_number_literal(token)?,
1714 Rule::type_literal => self.eval_type_literal(token)?,
1715 Rule::variable => self.get_variable(token)?,
1716 _ => unexpected_token!(token),
1717 };
1718 log::debug!("eval_value - res: {:?}", res);
1719 Ok(res)
1720 }
1721
1722 fn eval_number_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1723 check_rule!(token, Rule::number_literal);
1724 let mut negate = false;
1725 let mut pairs = token.into_inner();
1726 let mut token = pairs.next().unwrap();
1727
1728 if token.as_rule() == Rule::minus {
1730 negate = true;
1731 token = pairs.next().unwrap();
1732 } else if token.as_rule() == Rule::plus {
1733 token = pairs.next().unwrap();
1734 }
1735
1736 let mut val = self.eval_number(token)?;
1737
1738 if negate {
1739 val.neg()?;
1740 }
1741
1742 if let Some(unit) = pairs.next() {
1743 let unit = unit.as_str().to_ascii_lowercase();
1744 let unit_int = match unit.as_str() {
1745 "k" => 1024,
1746 "m" => 1024 * 1024,
1747 "g" => 1024 * 1024 * 1024,
1748 "t" => 1024 * 1024 * 1024 * 1024,
1749 "p" => 1024 * 1024 * 1024 * 1024 * 1024,
1750 _ => 1,
1751 };
1752 val.mul(Val::Int(unit_int))?;
1753 }
1754 Ok(val)
1755 }
1756
1757 fn eval_number(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1758 check_rule!(token, Rule::number);
1759 let mut pairs = token.into_inner();
1760 let token = pairs.next().unwrap();
1761 let v = match token.as_rule() {
1762 Rule::decimal_integer => {
1763 let int_val = token.into_inner().next().unwrap();
1764 Val::Int(int_val.as_str().parse::<i64>().unwrap())
1765 }
1766 Rule::hex_integer => {
1767 let int_val = token.into_inner().next().unwrap();
1768 Val::Int(i64::from_str_radix(int_val.as_str(), 16).unwrap())
1769 }
1770 Rule::float => {
1771 let float_str = token.as_str().trim();
1772 Val::Float(float_str.parse::<f64>()?)
1773 }
1775 _ => unexpected_token!(token),
1776 };
1777 Ok(v)
1778 }
1779
1780 fn eval_unary_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1781 check_rule!(token, Rule::unary_exp);
1782 let token = token.into_inner().next().unwrap();
1783 match token.as_rule() {
1784 Rule::expression_with_unary_operator => self.eval_expression_with_unary_operator(token),
1785 Rule::primary_expression => self.eval_primary_expression(token),
1786 _ => unexpected_token!(token),
1787 }
1788 }
1789
1790 fn eval_array_literal_exp_special_case(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1791 check_rule!(token, Rule::array_literal_exp_special_case);
1792 let mut pairs = token.into_inner();
1793 let token = pairs.next().unwrap();
1794
1795 let val = self.eval_array_literal_exp(token)?;
1796 Ok(Val::Array(vec![val]))
1797 }
1798
1799 fn safe_parse_arg(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1800 Ok(if self.skip_error > 0 {
1801 match self.eval_unary_exp(token.clone()) {
1802 Ok(val) => val,
1803 Err(err) => {
1804 self.errors.push(err);
1805 Val::ScriptText(token.as_str().to_string())
1806 }
1807 }
1808 } else {
1809 self.eval_unary_exp(token.clone())?
1810 })
1811 }
1812
1813 fn eval_array_literal_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1814 check_rule!(token, Rule::array_literal_exp);
1815 let mut arr = Vec::new();
1816 let mut pairs = token.into_inner();
1817 let token = pairs.next().unwrap();
1818
1819 if let Rule::array_literal_exp_special_case = token.as_rule() {
1821 return self.eval_array_literal_exp_special_case(token);
1822 }
1823
1824 arr.push(self.safe_parse_arg(token)?);
1825 for token in pairs {
1826 arr.push(self.safe_parse_arg(token)?);
1827 }
1828
1829 Ok(if arr.len() == 1 {
1830 arr[0].clone()
1831 } else {
1832 Val::Array(arr)
1833 })
1834 }
1835
1836 fn eval_range_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1837 fn range(mut left: i64, right: i64) -> ParserResult<Vec<Val>> {
1838 if left.abs_diff(right) >= value::MAX_ARRAY_LEN as u64 {
1839 Err(ValError::ArgumentOutOfRange("..".to_string(), right))?
1840 }
1841 let mut v = Vec::new();
1842 if left <= right {
1843 loop {
1844 v.push(left);
1845 if left == right {
1846 break;
1847 }
1848 left += 1;
1849 }
1850 } else {
1851 loop {
1852 v.push(left);
1853 if left == right {
1854 break;
1855 }
1856 left -= 1;
1857 }
1858 }
1859 Ok(v.into_iter().map(Val::Int).collect())
1860 }
1861 check_rule!(token, Rule::range_exp);
1862 let mut pairs = token.into_inner();
1863 let mut token = pairs.next().unwrap();
1864
1865 let _is_minus = if let Rule::additive_op = token.as_rule() {
1866 token = pairs.next().unwrap();
1867 true
1868 } else {
1869 false
1870 };
1871
1872 let res = match token.as_rule() {
1873 Rule::decimal_integer => {
1874 let int_val = token.into_inner().next().unwrap();
1875 let left = int_val.as_str().parse::<i64>().map_err(|_| {
1876 ValError::InvalidCast(int_val.as_str().to_string(), "Int64".to_string())
1877 })?;
1878 let mut token = pairs.next().unwrap();
1879 let _is_minus = if let Rule::additive_op = token.as_rule() {
1880 token = pairs.next().unwrap();
1881 true
1882 } else {
1883 false
1884 };
1885 let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
1886 Val::Array(range(left, right)?)
1887 }
1888 Rule::array_literal_exp => {
1889 let res = self.eval_array_literal_exp(token)?;
1890 if let Some(token) = pairs.next() {
1891 let left = res.cast_to_int()?;
1892 let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
1893 Val::Array(range(left, right)?)
1894 } else {
1895 res
1896 }
1897 }
1898 _ => unexpected_token!(token),
1899 };
1900
1901 Ok(res)
1902 }
1903
1904 fn eval_format_impl(
1905 &mut self,
1906 format: Vec<Val>,
1907 mut pairs: Pairs<'a>,
1908 ) -> ParserResult<Option<Vec<Val>>> {
1909 Ok(if let Some(token) = pairs.next() {
1910 let second_fmt = self.eval_range_exp(token)?;
1911 let format_arg =
1912 if let Some(vec_args) = self.eval_format_impl(second_fmt.cast_to_array(), pairs)? {
1913 vec_args
1914 } else {
1915 second_fmt.into_array()
1916 };
1917
1918 Some(
1919 formatting::format_ps_vec(format, &format_arg)?
1920 .iter()
1921 .map(|v| Val::String(v.into()))
1922 .collect(),
1923 )
1924 } else {
1925 None
1926 })
1927 }
1928
1929 fn eval_format_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1930 check_rule!(token, Rule::format_exp);
1931 let mut pairs = token.into_inner();
1932 let format = self.eval_range_exp(pairs.next().unwrap())?;
1933 if let Some(vec_args) = self.eval_format_impl(format.cast_to_array(), pairs)? {
1934 Ok(Val::String(
1935 vec_args
1936 .iter()
1937 .map(|v| v.cast_to_string())
1938 .collect::<Vec<_>>()
1939 .join(" ")
1940 .into(),
1941 ))
1942 } else {
1943 Ok(format)
1944 }
1945 }
1946
1947 fn eval_mult(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1948 check_rule!(token, Rule::multiplicative_exp);
1949 let mut pairs = token.into_inner();
1950 let mut res = self.eval_format_exp(pairs.next().unwrap())?;
1951 while let Some(op) = pairs.next() {
1952 let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1953 log::error!("No arithmetic function for operator: {}", op.as_str());
1954 return Err(ParserError::NotImplemented(format!(
1955 "No arithmetic function for operator: {}",
1956 op.as_str()
1957 )));
1958 };
1959
1960 let postfix = pairs.next().unwrap();
1961 let right_op = self.eval_format_exp(postfix)?;
1962 res = fun(res, right_op)?;
1963 }
1964
1965 Ok(res)
1966 }
1967
1968 fn eval_additive(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1969 check_rule!(token, Rule::additive_exp);
1970
1971 let mut pairs = token.into_inner();
1972 let token = pairs.next().unwrap();
1973 let mut res = match token.as_rule() {
1974 Rule::multiplicative_exp => self.eval_mult(token)?,
1975 _ => unexpected_token!(token),
1976 };
1977 while let Some(op) = pairs.next() {
1978 let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1980 log::error!("No arithmetic function for operator: {}", op.as_str());
1981 return Err(ParserError::NotImplemented(format!(
1982 "No arithmetic function for operator: {}",
1983 op.as_str()
1984 )));
1985 };
1986
1987 let mult = pairs.next().unwrap();
1988 let right_op = match mult.as_rule() {
1989 Rule::multiplicative_exp => self.eval_mult(mult)?,
1990 Rule::pre_arithmetic => self.eval_pre_arithmetic(mult)?,
1991 _ => unexpected_token!(mult),
1992 };
1993 res = fun(res, right_op)?;
1994 }
1995
1996 Ok(res)
1997 }
1998
1999 fn eval_split_special_case(
2000 &mut self,
2001 script_block: ScriptBlock,
2002 input: Val,
2003 ) -> ParserResult<Vec<String>> {
2004 let mut res_vec = vec![];
2005 let mut parts = String::new();
2006 let input_str = input.cast_to_string();
2007 let characters = input_str.chars();
2008
2009 for ch in characters {
2011 let b = match script_block.run(vec![], self, Some(Val::String(ch.to_string().into()))) {
2012 Err(er) => {
2013 self.errors.push(er);
2014 false
2015 }
2016 Ok(res) => res.val.cast_to_bool(),
2017 };
2018
2019 if b {
2020 res_vec.push(parts);
2021 parts = String::new();
2022 } else {
2023 parts.push(ch);
2024 }
2025 }
2026 self.variables.reset_ps_item();
2027 Ok(res_vec)
2028 }
2029
2030 fn eval_comparison_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2031 check_rule!(token, Rule::comparison_exp);
2032 let mut pairs = token.into_inner();
2033 let token = pairs.next().unwrap();
2034
2035 let mut res = if token.as_rule() == Rule::additive_exp {
2038 self.eval_additive(token)?
2039 } else {
2040 Val::Null
2041 };
2042
2043 while let Some(op) = pairs.next() {
2044 let Some(fun) = StringPred::get(op.as_str()) else {
2045 log::error!("No string predicate for operator: {}", op.as_str());
2046 return Err(ParserError::NotImplemented(format!(
2047 "No string predicate for operator: {}",
2048 op.as_str()
2049 )));
2050 };
2051
2052 let token = pairs.next().unwrap();
2053 let right_op = match token.as_rule() {
2054 Rule::script_block_expression => {
2055 let script_block = self.parse_script_block_expression(token)?;
2056
2057 return Ok(Val::Array(
2058 self.eval_split_special_case(script_block, res)?
2059 .into_iter()
2060 .map(|s| Val::String(s.into()))
2061 .collect::<Vec<_>>(),
2062 ));
2063 }
2064 Rule::additive_exp => self.eval_additive(token)?,
2065 _ => unexpected_token!(token),
2067 };
2068 log::trace!("res: {:?}, right_op: {:?}", &res, &right_op);
2069 res = fun(res, right_op)?;
2070 log::trace!("res: {:?}", &res);
2071 }
2072
2073 Ok(res)
2074 }
2075
2076 fn parse_script_param_block(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
2077 check_rule!(token, Rule::script_param_block);
2078 let mut pairs = token.into_inner();
2079 let Some(param_block_token) = pairs.next() else {
2080 return Ok(vec![]);
2081 };
2082 self.parse_param_block(param_block_token)
2083 }
2084
2085 fn parse_param_block(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
2086 check_rule!(token, Rule::param_block);
2087 let mut pairs = token.into_inner();
2088
2089 let Some(token) = pairs.next() else {
2090 return Ok(vec![]);
2091 };
2092
2093 let option_param_token = match token.as_rule() {
2094 Rule::attribute_list => {
2095 pairs.next()
2097 }
2098 Rule::parameter_list => Some(token),
2099 _ => unexpected_token!(token),
2100 };
2101
2102 let Some(param_token) = option_param_token else {
2103 return Ok(vec![]);
2104 };
2105 self.parse_parameter_list(param_token)
2106 }
2107
2108 fn parse_parameter_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
2109 check_rule!(token, Rule::parameter_list);
2110 let mut params = vec![];
2111 let param_list_pairs = token.into_inner();
2112 for script_parameter_token in param_list_pairs {
2113 check_rule!(script_parameter_token, Rule::script_parameter);
2114 params.push(self.parse_script_parameter(script_parameter_token)?);
2115 }
2116 Ok(params)
2117 }
2118
2119 fn parse_attribute_list(&mut self, token: Pair<'a>) -> ParserResult<Option<ValType>> {
2120 check_rule!(token, Rule::attribute_list);
2121 let attribute_list_pairs = token.into_inner();
2122 for attribute_token in attribute_list_pairs {
2123 check_rule!(attribute_token, Rule::attribute);
2124 let attribute_type_token = attribute_token.into_inner().next().unwrap();
2125 match attribute_type_token.as_rule() {
2126 Rule::attribute_info => {
2127 continue;
2129 }
2130 Rule::type_literal => {
2131 return Ok(Some(
2132 self.get_valtype_from_type_literal(attribute_type_token)?,
2133 ));
2134 }
2135 _ => unexpected_token!(attribute_type_token),
2136 }
2137 }
2138 Ok(None)
2139 }
2140 fn parse_script_parameter(&mut self, token: Pair<'a>) -> ParserResult<Param> {
2141 check_rule!(token, Rule::script_parameter);
2142 let mut pairs = token.into_inner();
2143 let mut token = pairs.next().unwrap();
2144
2145 let type_literal = if token.as_rule() == Rule::attribute_list {
2146 let type_literal = self.parse_attribute_list(token).unwrap_or(None);
2147 token = pairs.next().unwrap();
2148 type_literal
2149 } else {
2150 None
2151 };
2152
2153 check_rule!(token, Rule::variable);
2154 let var_name = Self::parse_variable(token)?;
2155
2156 let default_value = if let Some(default_value_token) = pairs.next() {
2157 check_rule!(default_value_token, Rule::script_parameter_default);
2158 let default_value_expr = default_value_token.into_inner().next().unwrap();
2159 let default_value = self.eval_primary_expression(default_value_expr)?;
2160 Some(default_value)
2161 } else {
2162 None
2163 };
2164 Ok(Param::new(type_literal, var_name.name, default_value))
2165 }
2166
2167 fn eval_bitwise_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2168 check_rule!(token, Rule::bitwise_exp);
2169
2170 let mut pairs = token.into_inner();
2171 let mut res = self.eval_as_exp(pairs.next().unwrap())?;
2172 while let Some(op) = pairs.next() {
2173 check_rule!(op, Rule::bitwise_operator);
2174 let Some(fun) = BitwisePred::get(op.as_str()) else {
2175 log::error!("No bitwise predicate for operator: {}", op.as_str());
2176 return Err(ParserError::NotImplemented(format!(
2177 "No bitwise predicate for operator: {}",
2178 op.as_str()
2179 )));
2180 };
2181
2182 let mult = pairs.next().unwrap();
2183 let right_op = self.eval_as_exp(mult)?;
2184 res = fun(res, right_op)?;
2185 }
2186
2187 Ok(res)
2188 }
2189
2190 fn eval_as_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2191 check_rule!(token, Rule::as_expression);
2192
2193 let mut pairs = token.into_inner();
2194 let mut res = self.eval_comparison_exp(pairs.next().unwrap())?;
2195 for token in pairs {
2196 let runtime_object = match token.as_rule() {
2197 Rule::primary_expression => self.eval_primary_expression(token)?,
2198 _ => unexpected_token!(token),
2199 };
2200
2201 res = res.cast(&runtime_object).unwrap_or_default();
2202 }
2203
2204 Ok(res)
2205 }
2206
2207 fn parse_cmdlet_command_name(&mut self, token: Pair<'a>) -> ParserResult<Command> {
2208 check_rule!(token, Rule::cmdlet_command);
2209
2210 let mut pairs = token.into_inner();
2211 let token = pairs.next().unwrap();
2212 let command_name = match token.as_rule() {
2213 Rule::command_name => token.as_str(),
2214 Rule::where_command_name => "where-object",
2215 Rule::foreach_command_name => "foreach-object",
2216 Rule::powershell_command_name => "powershell",
2217 _ => unexpected_token!(token),
2218 };
2219
2220 let mut command = Command::cmdlet(command_name);
2221 if Rule::command_name == token.as_rule() {
2222 command.set_session_scope(SessionScope::New);
2223 }
2224 Ok(command)
2225 }
2226
2227 fn parse_command_args(&mut self, pairs: Pairs<'a>) -> ParserResult<Vec<CommandElem>> {
2228 let mut args = vec![];
2229 for command_element_token in pairs {
2230 let token_string = command_element_token.as_str().to_string();
2231 match command_element_token.as_rule() {
2232 Rule::command_argument => {
2233 let arg_token = command_element_token.into_inner().next().unwrap();
2234 let arg = match arg_token.as_rule() {
2235 Rule::array_literal_exp => self.eval_array_literal_exp(arg_token)?,
2236 Rule::script_block_expression => {
2237 Val::ScriptBlock(self.parse_script_block_expression(arg_token)?)
2238 }
2239 Rule::parenthesized_expression => {
2240 self.eval_parenthesized_expression(arg_token)?
2241 }
2242 Rule::generic_token => {
2243 let s = arg_token.as_str();
2244 self.tokens.push(Token::String(s.into()));
2245 Val::ScriptText(s.into())
2246 }
2247 _ => Val::ScriptText(arg_token.as_str().to_string()),
2248 };
2249 args.push(CommandElem::Argument(arg));
2250 }
2251 Rule::command_parameter => {
2252 args.push(CommandElem::Parameter(token_string.to_ascii_lowercase()))
2253 }
2254 Rule::argument_list => {
2255 let expression_token = command_element_token.into_inner().next().unwrap();
2256 let Ok(expr_res) = self.eval_expression(expression_token) else {
2257 continue;
2258 };
2259 if let Val::Array(arr) = expr_res {
2260 for v in arr {
2261 args.push(CommandElem::Argument(v));
2262 }
2263 } else {
2264 args.push(CommandElem::Argument(expr_res));
2265 }
2266 }
2267 Rule::splatten_arg => {
2268 let var_name = Self::parse_scoped_variable(command_element_token)?;
2269 let var = self
2270 .variables
2271 .get(&var_name, &self.types_map)
2272 .unwrap_or_default();
2273 if let Val::HashTable(h) = var {
2274 for (k, v) in h {
2275 args.push(CommandElem::Parameter(format!("-{}", k)));
2276 args.push(CommandElem::Argument(v));
2277 }
2278 }
2279 }
2280 Rule::redirection => { }
2282 Rule::stop_parsing => { }
2284 _ => unexpected_token!(command_element_token),
2285 }
2286 }
2287 Ok(args)
2288 }
2289
2290 fn eval_command(&mut self, token: Pair<'a>, piped_arg: Option<Val>) -> ParserResult<Val> {
2291 check_rule!(token, Rule::command);
2292 let command_str = token.as_str().to_string();
2293
2294 let mut pairs = token.into_inner();
2295 let command_token = pairs.next().unwrap();
2296 let mut command = match command_token.as_rule() {
2297 Rule::cmdlet_command => self.parse_cmdlet_command_name(command_token)?,
2298 Rule::invocation_command => self.parse_invocation_command(command_token)?,
2299 _ => unexpected_token!(command_token),
2300 };
2301
2302 let mut args = self.parse_command_args(pairs)?;
2303 let token_args = args.iter().map(CommandElem::display).collect();
2305 if let Some(arg) = piped_arg {
2306 args.insert(0, CommandElem::Argument(arg));
2307 }
2308
2309 command.with_args(args);
2310 self.tokens
2311 .push(Token::command(command_str, command.name(), token_args));
2312
2313 match command.execute(self) {
2314 Ok(CommandOutput {
2315 val,
2316 deobfuscated: _deobfuscated,
2317 }) => Ok(val),
2318 Err(e) => {
2319 self.errors.push(e);
2320 Ok(Val::ScriptText(command.to_string()))
2321 }
2322 }
2323
2324 }
2328
2329 fn add_deobfuscated_statement(&mut self, msg: String) {
2330 if let Some(last) = self.results.last_mut() {
2331 last.deobfuscated.push(msg);
2332 }
2333 }
2334
2335 fn add_output_statement(&mut self, msg: StreamMessage) {
2336 if let Some(last) = self.results.last_mut() {
2337 last.output.push(msg);
2338 }
2339 }
2340
2341 fn parse_invocation_command(&mut self, token: Pair<'a>) -> ParserResult<Command> {
2342 check_rule!(token, Rule::invocation_command);
2343
2344 let invocation_command_token = token.into_inner().next().unwrap();
2345
2346 let mut session_scope = match invocation_command_token.as_rule() {
2347 Rule::current_scope_invocation_command => SessionScope::Current,
2348 Rule::new_scope_invocation_command => SessionScope::New,
2349 _ => unexpected_token!(invocation_command_token),
2350 };
2351
2352 let token_inner = invocation_command_token.into_inner().next().unwrap();
2353
2354 let mut command = match token_inner.as_rule() {
2355 Rule::cmdlet_command => {
2356 session_scope = SessionScope::New;
2357 self.parse_cmdlet_command_name(token_inner)?
2358 }
2359 Rule::primary_expression => {
2360 let primary = self.eval_primary_expression(token_inner)?;
2361 if let Val::ScriptBlock(script_block) = primary {
2362 Command::script_block(script_block)
2363 } else {
2364 Command::cmdlet(&primary.cast_to_script())
2365 }
2366 }
2367 Rule::path_command_name => Command::path(token_inner.as_str()),
2368 _ => unexpected_token!(token_inner),
2369 };
2370
2371 command.set_session_scope(session_scope);
2372 Ok(command)
2373 }
2374
2375 fn eval_redirected_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2376 check_rule!(token, Rule::redirected_expression);
2377
2378 let expression_token = token.into_inner().next().unwrap();
2379 self.eval_expression(expression_token)
2382 }
2383
2384 fn eval_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2385 check_stack(0)?;
2386 eval_step()?;
2387 check_rule!(token, Rule::expression);
2388 let token_string = token.as_str().trim().to_string();
2389
2390 let mut pairs = token.into_inner();
2391 let mut res = self.eval_bitwise_exp(pairs.next().unwrap())?;
2392 while let Some(op) = pairs.next() {
2393 check_rule!(op, Rule::logical_operator);
2394 let Some(fun) = LogicalPred::get(op.as_str()) else {
2395 log::error!("No logical predicate for operator: {}", op.as_str());
2396 return Err(ParserError::NotImplemented(format!(
2397 "No logical predicate for operator: {}",
2398 op.as_str()
2399 )));
2400 };
2401
2402 let mult = pairs.next().unwrap();
2403 let right_op = self.eval_bitwise_exp(mult)?;
2404 res = Val::Bool(fun(res, right_op));
2405 }
2406 self.tokens
2407 .push(Token::expression(token_string, res.clone().into()));
2408
2409 if let Val::String(value::PsString(s)) = &res {
2410 self.tokens.push(Token::String(s.clone()));
2411 }
2412
2413 Ok(res)
2414 }
2415
2416 fn eval_pipeline_tail(&mut self, token: Pair<'a>, mut piped_arg: Val) -> ParserResult<Val> {
2417 check_rule!(token, Rule::pipeline_tail);
2418 let pairs = token.into_inner();
2419
2420 for token in pairs {
2421 piped_arg = self.eval_command(token, Some(piped_arg))?;
2423 }
2424
2425 Ok(piped_arg)
2426 }
2427
2428 fn eval_pipeline_with_tail(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2429 check_rule!(token, Rule::pipeline_with_tail);
2430 let mut pairs = token.into_inner();
2431 let token = pairs.next().unwrap();
2432
2433 let result: Val = match token.as_rule() {
2434 Rule::redirected_expression => self.eval_redirected_expression(token)?,
2435 Rule::command => self.eval_command(token, None)?,
2436 _ => unexpected_token!(token),
2437 };
2438
2439 if let Some(token) = pairs.next() {
2440 match token.as_rule() {
2441 Rule::pipeline_tail => Ok(self.eval_pipeline_tail(token, result)?),
2442 _ => unexpected_token!(token),
2443 }
2444 } else {
2445 Ok(result)
2446 }
2447 }
2448
2449 fn eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2450 check_stack(0)?;
2451 check_rule!(token, Rule::pipeline);
2452 let mut pairs = token.into_inner();
2453 let token = pairs.next().unwrap();
2454
2455 match token.as_rule() {
2456 Rule::assignment_exp => self.eval_assigment_exp(token),
2457 Rule::pipeline_with_tail => self.eval_pipeline_with_tail(token),
2458 _ => unexpected_token!(token),
2459 }
2460 }
2461
2462 fn safe_eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2463 let res = self.eval_pipeline(token.clone());
2464
2465 let v = match res {
2466 Ok(val) => val,
2467 Err(err) => {
2468 self.errors.push(err);
2469 Val::ScriptText(token.as_str().to_string())
2470 }
2471 };
2472
2473 Ok(v)
2474 }
2475
2476 fn eval_cast_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2477 check_rule!(token, Rule::cast_expression);
2478
2479 let mut pairs = token.into_inner();
2480 let type_token = pairs.next().unwrap();
2481 check_rule!(type_token, Rule::type_literal);
2482 let val_type = self.eval_type_literal(type_token)?;
2483 let token = pairs.next().unwrap();
2484 let res = match token.as_rule() {
2485 Rule::parenthesized_expression => self.eval_parenthesized_expression(token)?,
2486 Rule::unary_exp => self.eval_unary_exp(token)?,
2487 _ => unexpected_token!(token),
2488 };
2489 Ok(res.cast(&val_type)?)
2490 }
2491
2492 fn eval_assigment_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2493 check_rule!(token, Rule::assignment_exp);
2494
2495 let mut specified_type = None;
2496
2497 let mut pairs = token.into_inner();
2498 let mut token = pairs.next().unwrap();
2499 if token.as_rule() == Rule::type_literal {
2500 specified_type = Some(self.eval_type_literal(token)?);
2501 token = pairs.next().unwrap();
2502 }
2503 let (var_name, access) = self.parse_assignable_variable(token)?;
2504 let mut variable = self
2505 .variables
2506 .get(&var_name, &self.types_map)
2507 .unwrap_or_default();
2508 let mut accessed_elem = &mut variable;
2509
2510 if let Some(access) = access {
2513 for token in access {
2514 accessed_elem = self.variable_access(token, accessed_elem)?;
2515 }
2516 }
2517 let assignement_op = pairs.next().unwrap();
2518
2519 let op = assignement_op.into_inner().next().unwrap();
2521 let pred = ArithmeticPred::get(op.as_str());
2522
2523 let right_token = pairs.next().unwrap();
2524 let right_op = self.eval_statement(right_token.clone())?;
2525
2526 let Some(pred) = pred else {
2527 log::error!("No arithmetic function for operator: {}", op.as_str());
2528 return Err(ParserError::NotImplemented(format!(
2529 "No arithmetic function for operator: {}",
2530 op.as_str()
2531 )));
2532 };
2533
2534 *accessed_elem = pred(accessed_elem.clone(), right_op)?;
2535 if let Some(runtime_type) = specified_type {
2536 *accessed_elem = accessed_elem.cast(&runtime_type)?;
2537 }
2538 self.variables.set(&var_name, variable.clone())?;
2539 self.add_deobfuscated_statement(format!("{} = {}", var_name, variable.cast_to_script()));
2541
2542 Ok(Val::NonDisplayed(Box::new(variable)))
2543 }
2544
2545 fn push_scope_session(&mut self) {
2546 self.variables.push_scope_session();
2547 }
2548
2549 fn pop_scope_session(&mut self) {
2550 self.variables.pop_scope_session();
2551 }
2552}
2553
2554#[cfg(test)]
2555mod tests {
2556 use pest::Parser;
2557
2558 use super::*;
2559
2560 #[test]
2561 fn comment_and_semicolon() {
2562 let input = r#"
2563# This is a single line comment
2564$a = 1; $b = 2; Write-Output $a
2565
2566Write-Output "Hello" # Another comment
2567
2568<#
2569 This is a
2570 multi-line block comment
2571#>
2572"#;
2573
2574 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2575 }
2576
2577 #[test]
2578 fn while_loop() {
2579 let input = r#"
2580while ($true) {
2581 if ($someCondition) {
2582 break
2583 }
2584 # other code
2585}
2586"#;
2587
2588 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2589 }
2590
2591 #[test]
2592 fn foreach_loop() {
2593 let input = r#"
2594foreach ($n in $numbers) {
2595 Write-Output $n
2596}
2597"#;
2598
2599 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2600 }
2601
2602 #[test]
2603 fn for_loop() {
2604 let input = r#"
2605# Comma separated assignment expressions enclosed in parentheses.
2606for (($i = 0), ($j = 0); $i -lt 10; $i++)
2607{
2608 "`$i:$i"
2609 "`$j:$j"
2610}
2611"#;
2612
2613 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2614 }
2615
2616 #[test]
2617 fn switch() {
2618 let input = r#"
2619switch ($var) {
2620 "a" { Write-Output "A" }
2621 1 { Write-Output "One" }
2622 default { Write-Output "Other" }
2623}
2624"#;
2625
2626 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2627 }
2628
2629 #[test]
2630 fn functions() {
2631 let input = r#"
2632function Get-Square {
2633 param($x)
2634 return $x * $x
2635}
2636
2637function Say-Hello {
2638 Write-Output "Hello"
2639}
2640"#;
2641
2642 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2643 }
2644
2645 #[test]
2646 fn if_expression() {
2647 let input = r#"
2648$x="hello"
2649 Write-Host $x
2650 $y = 42
2651 Start-Process "notepad.exe"
2652
2653 $x = 42
2654if ($x -eq 1) {
2655 Write-Output "One"
2656} elseif ($x -eq 2) {
2657 Write-Output "Two"
2658} else {
2659 Write-Output "Other"
2660}
2661"#;
2662
2663 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2664 }
2665
2666 #[test]
2667 fn command() {
2668 let input = r#"
2669Get-Process | Where-Object { $_.CPU -gt 100 }
2670"#;
2671
2672 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2673 }
2674
2675 #[test]
2676 fn range() {
2677 let input = r#"
2678$numbers = 1..5
2679"#;
2680
2681 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2682 }
2683
2684 #[test]
2685 fn literals() {
2686 let input = r#"
2687$hex = 0xFF
2688
2689$name = "Alice"
2690$msg = "Hello, $name. Today is $day."
2691$escaped = "She said: `"Hi`""
2692$literal = 'Hello, $name'
2693"#;
2694
2695 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2696 }
2697
2698 #[test]
2699 fn floats() {
2700 let input = r#"
2701 $pi = 3.1415
2702$half = .5
2703"#;
2704
2705 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2706 }
2707
2708 #[test]
2709 fn arrays() {
2710 let input = r#"
2711$a = 1, 2, 3
2712$b = @("one", "two", "three")
2713$c = @(1, 2, @(3, 4))
2714"#;
2715
2716 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2717 }
2718
2719 #[test]
2720 fn static_method_call() {
2721 let input = r#"
2722[Threading.Thread]::Sleep(399)
2723"#;
2724
2725 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2726 }
2727
2728 #[test]
2729 fn neg_pipeline() {
2730 let input = r#"
2731-not $input | Where-Object { $_ -gt 5 }
2732"#;
2733
2734 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2735 }
2736
2737 #[test]
2738 fn amsi_fail() {
2739 let input = r#"
2740#Matt Graebers second Reflection method
2741$VMRviwsbtehQfPtxbt=$null;
2742$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))"
2743
2744"#;
2745
2746 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2747 }
2748
2749 #[test]
2750 fn max_nesting_ignores_strings_and_comments() {
2751 assert_eq!(max_nesting("((1))"), 2);
2752 assert_eq!(max_nesting("$x -replace '\\(', ''"), 0);
2753 assert_eq!(max_nesting(&"$x = $x -replace '\\(', ''\n".repeat(100)), 0);
2754 assert_eq!(max_nesting("\"(((\""), 0);
2755 assert_eq!(max_nesting("\"$(1 + $(2))\""), 2);
2756 assert_eq!(max_nesting("\"a $(\"b $(1)\")\""), 2);
2757 assert_eq!(max_nesting("# ((((\n(1)"), 1);
2758 assert_eq!(max_nesting("<# (((( #> (1)"), 1);
2759 assert_eq!(max_nesting("@'\n((((\n'@\n(1)"), 1);
2760 assert_eq!(max_nesting("@\"\n(( \" $(1)\n\"@"), 1);
2761 assert_eq!(max_nesting("'it''s ((' + (1)"), 1);
2762 assert_eq!(max_nesting("\"say \"\"(\"\" $(1)\""), 1);
2763 assert_eq!(max_nesting("\"`\"(\" + (1)"), 1);
2764 assert_eq!(max_nesting("`(1"), 0);
2765 }
2766
2767 #[test]
2768 fn failed_index_not_evaluated_twice() {
2769 let mut ps = PowerShellSession::new();
2770 assert_eq!(ps.safe_eval("$a=@(1,2); $i=5; $a[0][$i++]; $i").unwrap(), "6");
2771 }
2772
2773 #[test]
2774 fn unclosed_nesting_hits_parse_budget() {
2775 for open in ["(", "$(", "@(", "{"] {
2776 let start = std::time::Instant::now();
2777 let input = open.repeat(24);
2779 let res = parse_program(&input);
2780 assert_eq!(res.err(), Some(ParserError::ParseBudgetExceeded), "{open}");
2781 assert!(start.elapsed().as_secs() < 5, "{open}: {:?}", start.elapsed());
2782 }
2783 }
2784
2785 #[test]
2786 fn pipeline_tokens_do_not_grow_with_piped_values() {
2787 let script = vec!["Foo-Bar"; 2000].join(" | ");
2788 let res = PowerShellSession::new().parse_command(&script).unwrap();
2789 let arg_bytes: usize = res
2790 .tokens()
2791 .all()
2792 .iter()
2793 .filter_map(|t| match t {
2794 Token::Command(cmd) => Some(cmd.args().iter().map(String::len).sum::<usize>()),
2795 _ => None,
2796 })
2797 .sum();
2798 assert!(arg_bytes < script.len(), "{arg_bytes}");
2799 }
2800
2801 #[test]
2802 fn wide_call_tree_hits_eval_budget() {
2803 let mut script = "function f0 { 1 }\n".to_string();
2805 for i in 1..7 {
2806 script += &format!("function f{i} {{ {} }}\n", vec![format!("f{}", i - 1); 10].join("; "));
2807 }
2808 script += "f6";
2809
2810 let start = std::time::Instant::now();
2811 let res = PowerShellSession::new().parse_command(&script).unwrap();
2812 assert!(res.errors().contains(&ParserError::EvalBudgetExceeded));
2813 assert!(start.elapsed().as_secs() < 60, "{:?}", start.elapsed());
2814 }
2815
2816 #[test]
2817 fn recursion_with_large_body_hits_eval_deadline() {
2818 let repeat = if cfg!(debug_assertions) { 2000 } else { 8000 };
2820 let script = format!("function f {{ f; f; {} }}; f", "$a = 1; ".repeat(repeat));
2821
2822 let start = std::time::Instant::now();
2823 let hit_budget = match PowerShellSession::new().parse_command(&script) {
2824 Ok(res) => res.errors().contains(&ParserError::EvalBudgetExceeded),
2825 Err(err) => err == ParserError::ParseBudgetExceeded,
2827 };
2828 assert!(hit_budget);
2829 assert!(start.elapsed().as_secs() < 10, "{:?}", start.elapsed());
2830 }
2831}