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