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