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)]
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 let mut pair = token.into_inner();
387 let condition_token = pair.next().unwrap();
388 let true_token = pair.next().unwrap();
389 let condition_val = self.eval_pipeline(condition_token.clone())?;
390 let res = if condition_val.cast_to_bool() {
391 self.eval_statement_block(true_token)?
392 } else if let Some(mut token) = pair.next() {
393 if token.as_rule() == Rule::elseif_clauses {
394 for else_if in token.into_inner() {
395 let mut pairs = else_if.into_inner();
396 let condition_token = pairs.next().unwrap();
397 let statement_token = pairs.next().unwrap();
398 let condition_val = self.eval_pipeline(condition_token)?;
399 if condition_val.cast_to_bool() {
400 return self.eval_statement_block(statement_token);
401 }
402 }
403 let Some(token2) = pair.next() else {
404 return Ok(Val::Null);
405 };
406 token = token2;
407 }
408 if token.as_rule() == Rule::else_condition {
409 let statement_token = token.into_inner().next().unwrap();
410 self.eval_statement_block(statement_token)?
411 } else {
412 Val::Null
413 }
414 } else {
415 Val::Null
416 };
417
418 Ok(res)
419 }
420
421 fn eval_flow_control_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
422 check_rule!(token, Rule::flow_control_statement);
423 let token = token.into_inner().next().unwrap();
424
425 Ok(match token.as_rule() {
426 Rule::flow_control_label_statement => Val::Null, Rule::flow_control_pipeline_statement => {
428 let token = token.into_inner().next().unwrap();
429 if let Some(pipeline_token) = token.into_inner().next() {
431 self.eval_pipeline(pipeline_token)?
432 } else {
433 Val::Null
434 }
435 }
436 _ => unexpected_token!(token),
437 })
438 }
439
440 fn parse_class_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
441 check_rule!(token, Rule::class_statement);
442 let mut pair = token.into_inner();
443
444 let class_name_token = pair.next().unwrap();
445 check_rule!(class_name_token, Rule::simple_name);
446 let class_name = class_name_token.as_str().to_string();
447
448 let mut properties = ClassProperties::new();
449 let mut methods: HashMap<String, ScriptBlock> = HashMap::new();
450
451 for member_token in pair {
452 match member_token.as_rule() {
453 Rule::class_property_definition => {
454 let prop_pair = member_token.into_inner();
455
456 let mut prop_pair = prop_pair.skip_while(|p| p.as_rule() == Rule::attribute);
458
459 let mut token = prop_pair.next().unwrap();
460 let _is_static = if token.as_rule() == Rule::class_attribute_static {
461 token = prop_pair.next().unwrap();
462 true
463 } else {
464 false
465 };
466
467 let _is_hidden = if token.as_rule() == Rule::class_attribute_hidden {
468 token = prop_pair.next().unwrap();
469 true
470 } else {
471 false
472 };
473
474 let ttype = if token.as_rule() == Rule::type_literal {
475 let ttype = self.get_valtype_from_type_literal(token)?;
476 token = prop_pair.next().unwrap();
477 Some(ttype)
478 } else {
479 None
480 };
481 check_rule!(token, Rule::variable);
482 let var_name = Self::parse_variable(token)?;
483 let default_val = if let Some(expression_token) = prop_pair.next() {
484 Some(self.eval_expression(expression_token)?)
485 } else {
486 None
487 };
488 properties.add_property(var_name.name, ttype, default_val);
489 }
490 Rule::class_method_definition => {
491 let prop_pair = member_token.into_inner();
492
493 let mut prop_pair = prop_pair.skip_while(|p| p.as_rule() == Rule::attribute);
495
496 let mut token = prop_pair.next().unwrap();
497 let _is_static = if token.as_rule() == Rule::class_attribute_static {
498 token = prop_pair.next().unwrap();
499 true
500 } else {
501 false
502 };
503
504 let _is_hidden = if token.as_rule() == Rule::class_attribute_hidden {
505 token = prop_pair.next().unwrap();
506 true
507 } else {
508 false
509 };
510
511 let _ttype = if token.as_rule() == Rule::type_literal {
512 let ttype = self.eval_type_literal(token)?.ttype();
513 token = prop_pair.next().unwrap();
514 Some(ttype)
515 } else {
516 None
517 };
518 check_rule!(token, Rule::simple_name);
519 let method_name = token.as_str().to_ascii_lowercase();
520
521 let mut token = prop_pair.next().unwrap();
522 let parameters = if token.as_rule() == Rule::parameter_list {
523 let params = self.parse_parameter_list(token)?;
524 token = prop_pair.next().unwrap();
525 params
526 } else {
527 vec![]
528 };
529 check_rule!(token, Rule::script_block);
530
531 let method_name = MethodName::new(method_name.as_str(), ¶meters);
532 let script_block = self.parse_script_block(token)?.with_params(parameters);
533 methods.insert(method_name.full_name().to_string(), script_block);
534 }
535 _ => unexpected_token!(member_token),
536 }
537 }
538 let class_type = ClassType::new(class_name.clone(), properties, HashMap::new(), methods);
539 if let Ok(mut value) = value::RUNTIME_TYPE_MAP.try_lock() {
540 value.insert(
541 class_name.to_ascii_lowercase(),
542 Box::new(class_type.clone()),
543 );
544 }
545 Ok(Val::Null)
546 }
547
548 fn eval_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
549 match token.as_rule() {
550 Rule::pipeline => self.eval_pipeline(token),
551 Rule::if_statement => self.eval_if_statement(token),
552 Rule::flow_control_statement => self.eval_flow_control_statement(token),
553 Rule::function_statement => self.parse_function_statement(token),
554 Rule::statement_terminator => Ok(Val::Null),
555 Rule::class_statement => self.parse_class_statement(token),
556 Rule::EOI => Ok(Val::Null),
557 _ => {
558 not_implemented!(token)
559 }
560 }
561 }
562
563 fn safe_eval_sub_expr(&mut self, token: Pair<'a>) -> ParserResult<Val> {
564 check_rule!(token, Rule::sub_expression);
565 let Some(inner_token) = token.into_inner().next() else {
566 return Ok(Val::Null);
567 };
568 let mut inner_val = self.eval_pipeline(inner_token)?;
569 if let Val::ScriptText(script) = &mut inner_val {
570 *script = format!("$({})", script);
571 }
573 Ok(inner_val)
574 }
575
576 fn eval_statement_block(&mut self, token: Pair<'a>) -> ParserResult<Val> {
577 Ok(self
578 .safe_eval_statements(token)?
579 .iter()
580 .last()
581 .cloned()
582 .unwrap_or(Val::Null))
583 }
584
585 fn eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
586 let pairs = token.into_inner();
588 let mut statements = vec![];
589
590 for token in pairs {
591 let s = self.eval_statement(token)?;
592 statements.push(s);
593 }
594 Ok(statements)
595 }
596
597 fn safe_eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
598 let pairs = token.into_inner();
600 let mut statements = vec![];
601
602 for token in pairs {
603 match self.eval_statement(token.clone()) {
604 Ok(s) => statements.push(s),
605 Err(err) => {
606 self.errors.push(err);
607 statements.push(Val::ScriptText(token.as_str().to_string()));
608 }
609 }
610 }
611 Ok(statements)
612 }
613
614 fn parse_dq(&mut self, token: Pair<'a>) -> ParserResult<String> {
615 let mut res_str = String::new();
616 let pairs = token.into_inner();
617 for token in pairs {
618 let token = token.into_inner().next().unwrap();
619 let s = match token.as_rule() {
620 Rule::variable => self.get_variable(token)?.cast_to_string(),
621 Rule::sub_expression => self.safe_eval_sub_expr(token)?.cast_to_string(),
622 Rule::backtick_escape => token
623 .as_str()
624 .strip_prefix("`")
625 .unwrap_or_default()
626 .to_string(),
627 _ => token.as_str().to_string(),
628 };
629 res_str.push_str(s.as_str());
630 }
631 Ok(res_str)
632 }
633
634 fn eval_string_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
635 check_rule!(token, Rule::string_literal);
636 let mut pair = token.into_inner();
637 let token = pair.next().unwrap();
638 let cloned_token = token.clone();
639
640 let mut is_expandable = false;
641 let res = match token.as_rule() {
642 Rule::doublequoted_string_literal | Rule::doublequoted_multiline_string_literal => {
643 is_expandable = true;
644 self.parse_dq(token)?
645 }
646 Rule::singlequoted_string_literal => {
647 let token_string = token.as_str().to_string();
648 let stripped_prefix = token_string
649 .strip_prefix("'")
650 .unwrap_or(token_string.as_str());
651 let stripped_suffix = stripped_prefix.strip_suffix("'").unwrap_or(stripped_prefix);
652 stripped_suffix.to_string()
653 }
654 Rule::singlequoted_multiline_string_literal => {
655 let mut res_str = String::new();
656 let pairs = token.into_inner();
657 for token in pairs {
658 res_str.push_str(token.as_str());
659 }
660 res_str
661 }
662 _ => unexpected_token!(token),
663 };
664 let ps_token = if is_expandable {
665 Token::string_expandable(cloned_token.as_str().to_string(), res.clone())
666 } else {
667 Token::String(cloned_token.as_str().to_string())
668 };
669 self.tokens.push(ps_token);
670
671 Ok(Val::String(res.into()))
672 }
673
674 fn get_variable(&mut self, token: Pair<'a>) -> ParserResult<Val> {
675 check_rule!(token, Rule::variable);
676 let var_name = Self::parse_variable(token)?;
677 let Some(var) = self.variables.get(&var_name) else {
678 return Err(ParserError::VariableError(VariableError::NotDefined(
679 var_name.name,
680 )));
681 };
682 Ok(var)
683 }
684
685 fn parse_scoped_variable(token: Pair<'a>) -> ParserResult<VarName> {
686 let mut pairs = token.into_inner();
688 let mut token = pairs.next().unwrap();
689
690 let scope = if token.as_rule() == Rule::scope_keyword {
691 let scope = token.as_str().to_ascii_lowercase();
692 token = pairs.next().unwrap();
693 check_rule!(token, Rule::var_name);
694 Some(Scope::from(scope.as_str()))
695 } else {
696 None
697 };
698 Ok(VarName::new(scope, token.as_str().to_ascii_lowercase()))
699 }
700
701 fn skip_value_access(&mut self, token: Pair<'a>) -> ParserResult<()> {
702 check_rule!(token, Rule::value_access);
703 let mut pair = token.into_inner();
704 let token = pair.next().unwrap();
705 let mut val = self.eval_value(token)?;
706 let _ = self.eval_element_access_ref(pair.next().unwrap(), &mut val)?;
707 Err(ParserError::Skip)
708 }
709
710 fn parse_assignable_variable(
720 &mut self,
721 token: Pair<'a>,
722 ) -> ParserResult<(VarName, Option<Pairs<'a>>)> {
723 check_rule!(token, Rule::assignable_variable);
724 let mut pair = token.into_inner();
725 let token = pair.next().unwrap();
726 match token.as_rule() {
727 Rule::variable => {
728 let var_name = Self::parse_variable(token)?;
729
730 Ok((var_name, None))
731 }
732 Rule::variable_access => {
733 let mut pairs = token.into_inner();
734 let var_token = pairs.next().unwrap();
735 let var_name = Self::parse_variable(var_token)?;
736 Ok((var_name, Some(pairs)))
741 }
742 Rule::value_access => self
743 .skip_value_access(token)
744 .map(|()| (Default::default(), None)),
745 _ => unexpected_token!(token),
746 }
747 }
748
749 fn parse_variable(token: Pair<'a>) -> ParserResult<VarName> {
750 check_rule!(token, Rule::variable);
751 let mut pair = token.into_inner();
752 let token = pair.next().unwrap();
753
754 Ok(match token.as_rule() {
755 Rule::special_variable => {
756 VarName::new_with_scope(Scope::Special, token.as_str().to_string())
757 }
758 Rule::parenthesized_variable => {
759 Self::parse_variable(token.into_inner().next().unwrap())?
760 }
761 Rule::braced_variable => {
762 let token = token.into_inner().next().unwrap();
763 let var = token.as_str().to_ascii_lowercase();
764 let splits: Vec<&str> = var.split(":").collect();
765 if splits.len() == 2 {
766 VarName::new_with_scope(Scope::from(splits[0]), splits[1].to_string())
767 } else {
768 VarName::new(None, var)
769 }
770 }
771 Rule::scoped_variable => Self::parse_scoped_variable(token)?,
772 _ => unexpected_token!(token),
773 })
774 }
775
776 fn eval_expression_with_unary_operator(&mut self, token: Pair<'a>) -> ParserResult<Val> {
777 check_rule!(token, Rule::expression_with_unary_operator);
778 let mut pair = token.into_inner();
779 let token = pair.next().unwrap();
780
781 let res = match token.as_rule() {
782 Rule::pre_inc_expression => {
783 let variable_token = token.into_inner().next().unwrap();
784 let var_name = Self::parse_variable(variable_token)?;
785 let mut var = self.variables.get(&var_name).unwrap_or_default();
786 var.inc()?;
787
788 self.variables.set(&var_name, var.clone())?;
789 var
790 }
791 Rule::pre_dec_expression => {
792 let variable_token = token.into_inner().next().unwrap();
793 let var_name = Self::parse_variable(variable_token)?;
794 let mut var = self.variables.get(&var_name).unwrap_or_default();
795 var.dec()?;
796
797 self.variables.set(&var_name, var.clone())?;
798 var
799 }
800 Rule::cast_expression => self.eval_cast_expression(token)?,
801 Rule::negate_op => {
802 let unary_token = pair.next().unwrap();
803 let unary = self.eval_unary_exp(unary_token)?;
804 Val::Bool(!unary.cast_to_bool())
805 }
806 Rule::bitwise_negate_op => {
807 let unary_token = pair.next().unwrap();
808 let unary = self.eval_unary_exp(unary_token)?;
809 Val::Int(!unary.cast_to_int()?)
810 }
811 _ => unexpected_token!(token),
812 };
813
814 Ok(res)
815 }
816
817 fn eval_argument_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
818 check_rule!(token, Rule::argument_list);
819 let mut pairs = token.into_inner();
820 let token = pairs.next().unwrap();
821
822 self.skip_error += 1;
823
824 let arg = self.eval_expression(token.clone())?;
825 self.skip_error -= 1;
826
827 if let Val::Array(vec) = arg {
828 Ok(vec)
829 } else {
830 Ok(vec![arg])
831 }
832 }
833
834 fn eval_member_access(&mut self, token: Pair<'a>) -> ParserResult<String> {
835 let member_name_token = token.into_inner().next().unwrap();
837 let member_name = member_name_token.as_str().to_ascii_lowercase();
838
839 Ok(member_name)
840 }
841
842 fn method_is_static(&mut self, token: Pair<'a>) -> bool {
843 check_rule!(token, Rule::method_invocation);
844 let mut pairs = token.into_inner();
845
846 let access = pairs.next().unwrap();
847 match access.as_rule() {
848 Rule::member_access => false,
849 Rule::static_access => true,
850 _ => unexpected_token!(access),
851 }
852 }
853
854 fn eval_method_invocation(
855 &mut self,
856 token: Pair<'a>,
857 object: &Val,
858 ) -> ParserResult<(String, Vec<Val>)> {
859 check_rule!(token, Rule::method_invocation);
860 let token_string = token.as_str().to_string();
861
862 let mut pairs = token.into_inner();
863
864 let access = pairs.next().unwrap();
865 let method_name = self.eval_member_access(access)?;
866
867 let args = if let Some(token) = pairs.next() {
868 check_rule!(token, Rule::argument_list);
869 match self.eval_argument_list(token) {
870 Ok(args) => args,
871 Err(e) => {
872 log::info!("eval_argument_list error: {:?}", e);
873
874 self.tokens.push(Token::method(
876 token_string.clone(),
877 object.clone().into(),
878 method_name.clone(),
879 Vec::new(),
880 ));
881 Err(e)?
882 }
883 }
884 } else {
885 Vec::new()
886 };
887
888 self.tokens.push(Token::method(
889 token_string,
890 object.clone().into(),
891 method_name.clone(),
892 args.clone().iter().map(|arg| arg.clone().into()).collect(),
893 ));
894 Ok((method_name, args))
895 }
896
897 fn eval_element_access_ref<'b>(
898 &mut self,
899 token: Pair<'a>,
900 object: &'b mut Val,
901 ) -> ParserResult<&'b mut Val> {
902 let mut pairs = token.into_inner();
903 let index_token = pairs.next().unwrap();
904 check_rule!(index_token, Rule::expression);
905 let index = self.eval_expression(index_token)?;
906 Ok(object.get_index_ref(index)?)
907 }
908
909 fn eval_element_access(&mut self, token: Pair<'a>, object: &Val) -> ParserResult<Val> {
910 let mut pairs = token.into_inner();
911 let index_token = pairs.next().unwrap();
912 check_rule!(index_token, Rule::expression);
913 let index = self.eval_expression(index_token)?;
914 Ok(object.get_index(index)?)
915 }
916
917 fn variable_access<'b>(
918 &mut self,
919 token: Pair<'a>,
920 object: &'b mut Val,
921 ) -> ParserResult<&'b mut Val> {
922 fn get_member_name(token: Pair<'_>) -> &'_ str {
923 token.into_inner().next().unwrap().as_str()
924 }
925 match token.as_rule() {
926 Rule::static_access => {
927 Err(ParserError::NotImplemented(
929 "modificable static_member".into(),
930 ))
931 }
932 Rule::member_access => Ok(object.member(get_member_name(token))?),
933 Rule::element_access => Ok(self.eval_element_access_ref(token, object)?),
934 _ => unexpected_token!(token),
935 }
936 }
937
938 fn value_access(&mut self, token: Pair<'a>, object: &mut Val) -> ParserResult<Val> {
939 fn get_member_name(token: Pair<'_>) -> &'_ str {
940 token.into_inner().next().unwrap().as_str()
941 }
942 Ok(match token.as_rule() {
943 Rule::static_access => {
944 let Val::RuntimeType(rt) = object else {
945 return Err(RuntimeError::MethodNotFound(
946 "Readonly static members can only be accessed on types".to_string(),
947 )
948 .into());
949 };
950 rt.readonly_static_member(get_member_name(token))?
951 }
952 Rule::member_access => object.readonly_member(get_member_name(token))?.clone(),
953 Rule::method_invocation => {
954 let static_method = self.method_is_static(token.clone());
955 let (function_name, args) = self.eval_method_invocation(token, object)?;
956 let mangled_name = MethodName::from_args(function_name.as_str(), &args);
957
958 if static_method {
959 let Val::RuntimeType(rt) = object else {
960 return Err(RuntimeError::MethodNotFound(
961 "Static method can be called only on type".to_string(),
962 )
963 .into());
964 };
965
966 let mut call = rt.static_method(mangled_name)?;
967 call(args)?
968 } else {
969 let mut call = object.method(mangled_name)?;
970 call(object, args)?
971 }
972 }
973 Rule::element_access => self.eval_element_access(token, object)?,
974 _ => unexpected_token!(token),
975 })
976 }
977
978 fn eval_value_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
979 check_rule!(token, Rule::value_access);
980 let mut pairs = token.into_inner();
981 let token = pairs.next().unwrap();
982
983 let mut object = self.eval_value(token)?;
984 for token in pairs {
985 object = self.value_access(token, &mut object)?;
986 }
987 log::debug!("Success eval_access: {:?}", object);
988 Ok(object)
989 }
990
991 fn parse_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
992 check_rule!(token, Rule::value_access);
993 let mut pairs = token.into_inner();
994 let token = pairs.next().unwrap();
995
996 let mut object = self
997 .eval_value(token.clone())
998 .map(|v| v.cast_to_script())
999 .unwrap_or(token.as_str().to_string());
1000
1001 for token in pairs {
1002 match token.as_rule() {
1003 Rule::static_access => {
1004 object.push_str(token.as_str());
1005 }
1006 Rule::member_access => {
1007 object.push_str(token.as_str());
1008 }
1009 Rule::method_invocation => {
1010 let static_method = self.method_is_static(token.clone());
1011 let (method_name, args) = self
1012 .eval_method_invocation(token.clone(), &Val::ScriptText(object.clone()))?;
1013 log::trace!("Method: {:?} {:?}", &method_name, &args);
1014
1015 let separator = if static_method { "::" } else { "." };
1016 object = format!(
1017 "{}{separator}{}({})",
1018 object,
1019 method_name.to_ascii_lowercase(),
1020 args.iter()
1021 .map(|arg| arg.cast_to_script())
1022 .collect::<Vec<String>>()
1023 .join(", ")
1024 )
1025 }
1026 Rule::element_access => {
1027 let mut pairs = token.into_inner();
1028 let index_token = pairs.next().unwrap();
1029 check_rule!(index_token, Rule::expression);
1030 let index = self.eval_expression(index_token)?;
1031 object = format!("{}[{}]", object, index);
1032 }
1033 _ => unexpected_token!(token),
1034 }
1035 }
1036 Ok(Val::String(object.into()))
1037 }
1038
1039 fn eval_primary_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1040 check_rule!(token, Rule::primary_expression);
1041 let mut pair = token.into_inner();
1042 let token = pair.next().unwrap();
1043 let res = match token.as_rule() {
1044 Rule::value_access => match self.eval_value_access(token.clone()) {
1045 Ok(res) => res,
1046 Err(err) => {
1047 log::info!("eval_access error: {:?}", err);
1048 self.errors.push(err);
1049 self.parse_access(token)?
1050 }
1051 },
1052 Rule::value => self.eval_value(token)?,
1053 Rule::post_inc_expression => {
1054 let variable_token = token.into_inner().next().unwrap();
1055 let var_name = Self::parse_variable(variable_token)?;
1056 let mut var = self.variables.get(&var_name).unwrap_or_default();
1057 let var_to_return = var.clone();
1058
1059 var.inc()?;
1060 self.variables.set(&var_name, var.clone())?;
1061
1062 var_to_return
1064 }
1065 Rule::post_dec_expression => {
1066 let variable_token = token.into_inner().next().unwrap();
1067 let var_name = Self::parse_variable(variable_token)?;
1068 let mut var = self.variables.get(&var_name).unwrap_or_default();
1069 let var_to_return = var.clone();
1070
1071 var.dec()?;
1072 self.variables.set(&var_name, var.clone())?;
1073
1074 var_to_return
1075 }
1076 _ => unexpected_token!(token),
1077 };
1078
1079 Ok(res)
1080 }
1081
1082 fn get_valtype_from_type_literal(&mut self, token: Pair<'a>) -> ParserResult<ValType> {
1083 check_rule!(token, Rule::type_literal);
1084
1085 let token = token.into_inner().next().unwrap();
1086 check_rule!(token, Rule::type_spec);
1087 Ok(ValType::cast(token.as_str())?)
1088 }
1089
1090 fn eval_type_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1091 check_rule!(token, Rule::type_literal);
1092
1093 let token = token.into_inner().next().unwrap();
1094 check_rule!(token, Rule::type_spec);
1095 Ok(ValType::runtime_type_from_str(token.as_str())?)
1096 }
1097
1098 fn parse_script_block(&mut self, token: Pair<'a>) -> ParserResult<ScriptBlock> {
1099 check_rule!(token, Rule::script_block);
1100
1101 let raw_text = token.as_str().to_string();
1102
1103 let mut pairs = token.into_inner();
1104 let Some(token) = pairs.next() else {
1105 return Ok(ScriptBlock::new(vec![], String::new(), raw_text));
1106 };
1107
1108 let params = self.parse_script_param_block(token.clone())?;
1109 let script_body = if let Some(token) = pairs.next() {
1112 check_rule!(token, Rule::script_block_body);
1113 token.as_str().to_string()
1114 } else {
1115 String::new()
1116 };
1117
1118 Ok(ScriptBlock::new(params, script_body, raw_text))
1119
1120 }
1128
1129 fn parse_script_block_expression(&mut self, token: Pair<'a>) -> ParserResult<ScriptBlock> {
1130 check_rule!(token, Rule::script_block_expression);
1131 let mut pairs = token.into_inner();
1132 self.parse_script_block(pairs.next().unwrap())
1133 }
1134
1135 fn eval_hash_key(&mut self, token: Pair<'a>) -> ParserResult<String> {
1136 check_rule!(token, Rule::key_expression);
1137 let mut pairs = token.into_inner();
1138 let key_token = pairs.next().unwrap();
1139
1140 Ok(match key_token.as_rule() {
1141 Rule::simple_name => key_token.as_str().to_ascii_lowercase(),
1142 Rule::unary_exp => self
1143 .eval_unary_exp(key_token)?
1144 .cast_to_string()
1145 .to_ascii_lowercase(),
1146 _ => unexpected_token!(key_token),
1147 })
1148 }
1149
1150 fn eval_hash_entry(&mut self, token: Pair<'a>) -> ParserResult<(String, Val)> {
1151 check_rule!(token, Rule::hash_entry);
1152
1153 let mut pairs = token.into_inner();
1154 let token_key = pairs.next().unwrap();
1155 let token_value = pairs.next().unwrap();
1156 let value = match token_value.as_rule() {
1157 Rule::type_literal => self.eval_type_literal(token_value)?,
1159 _ => self.eval_statement(token_value)?,
1160 };
1161
1162 Ok((self.eval_hash_key(token_key)?, value))
1163 }
1164
1165 fn eval_hash_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1166 check_rule!(token, Rule::hash_literal_expression);
1167 let pairs = token.into_inner();
1168 let mut hash = HashMap::new();
1169 for token in pairs {
1170 let (key, value) = self.eval_hash_entry(token)?;
1171 hash.insert(key, value);
1172 }
1173 Ok(Val::HashTable(hash))
1174 }
1175
1176 fn eval_value(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1177 check_rule!(token, Rule::value);
1178 let mut pair = token.into_inner();
1179 let token = pair.next().unwrap();
1180
1181 let res = match token.as_rule() {
1182 Rule::parenthesized_expression => {
1183 let token = token.into_inner().next().unwrap();
1184 self.safe_eval_pipeline(token)?
1185 }
1186 Rule::sub_expression | Rule::array_expression => {
1187 let statements = self.eval_statements(token)?;
1188 if statements.len() == 1 {
1189 if let Val::Array(_) = statements[0] {
1190 statements[0].clone()
1191 } else {
1192 Val::Array(statements)
1193 }
1194 } else {
1195 Val::Array(statements)
1196 }
1197 }
1198 Rule::script_block_expression => {
1199 Val::ScriptBlock(self.parse_script_block_expression(token)?)
1200 }
1201 Rule::hash_literal_expression => self.eval_hash_literal(token)?,
1202 Rule::string_literal => self.eval_string_literal(token)?,
1203 Rule::number_literal => self.eval_number_literal(token)?,
1204 Rule::type_literal => self.eval_type_literal(token)?,
1205 Rule::variable => self.get_variable(token)?,
1206 _ => unexpected_token!(token),
1207 };
1208 log::debug!("eval_value - res: {:?}", res);
1209 Ok(res)
1210 }
1211
1212 fn eval_number_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1213 check_rule!(token, Rule::number_literal);
1214 let mut negate = false;
1215 let mut pairs = token.into_inner();
1216 let mut token = pairs.next().unwrap();
1217
1218 if token.as_rule() == Rule::minus {
1220 negate = true;
1221 token = pairs.next().unwrap();
1222 } else if token.as_rule() == Rule::plus {
1223 token = pairs.next().unwrap();
1224 }
1225
1226 let mut val = self.eval_number(token)?;
1227
1228 if negate {
1229 val.neg()?;
1230 }
1231
1232 if let Some(unit) = pairs.next() {
1233 let unit = unit.as_str().to_ascii_lowercase();
1234 let unit_int = match unit.as_str() {
1235 "k" => 1024,
1236 "m" => 1024 * 1024,
1237 "g" => 1024 * 1024 * 1024,
1238 "t" => 1024 * 1024 * 1024 * 1024,
1239 "p" => 1024 * 1024 * 1024 * 1024 * 1024,
1240 _ => 1,
1241 };
1242 val.mul(Val::Int(unit_int))?;
1243 }
1244 Ok(val)
1245 }
1246
1247 fn eval_number(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1248 check_rule!(token, Rule::number);
1249 let mut pairs = token.into_inner();
1250 let token = pairs.next().unwrap();
1251 let v = match token.as_rule() {
1252 Rule::decimal_integer => {
1253 let int_val = token.into_inner().next().unwrap();
1254 Val::Int(int_val.as_str().parse::<i64>().unwrap())
1255 }
1256 Rule::hex_integer => {
1257 let int_val = token.into_inner().next().unwrap();
1258 Val::Int(i64::from_str_radix(int_val.as_str(), 16).unwrap())
1259 }
1260 Rule::float => {
1261 let float_str = token.as_str().trim();
1262 Val::Float(float_str.parse::<f64>()?)
1263 }
1265 _ => unexpected_token!(token),
1266 };
1267 Ok(v)
1268 }
1269
1270 fn eval_unary_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1271 check_rule!(token, Rule::unary_exp);
1272 let token = token.into_inner().next().unwrap();
1273 match token.as_rule() {
1274 Rule::expression_with_unary_operator => self.eval_expression_with_unary_operator(token),
1275 Rule::primary_expression => self.eval_primary_expression(token),
1276 _ => unexpected_token!(token),
1277 }
1278 }
1279
1280 fn eval_array_literal_exp_special_case(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1281 check_rule!(token, Rule::array_literal_exp_special_case);
1282 let mut pairs = token.into_inner();
1283 let token = pairs.next().unwrap();
1284
1285 let val = self.eval_array_literal_exp(token)?;
1286 Ok(Val::Array(vec![val]))
1287 }
1288
1289 fn safe_parse_arg(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1290 Ok(if self.skip_error > 0 {
1291 match self.eval_unary_exp(token.clone()) {
1292 Ok(val) => val,
1293 Err(err) => {
1294 self.errors.push(err);
1295 Val::ScriptText(token.as_str().to_string())
1296 }
1297 }
1298 } else {
1299 self.eval_unary_exp(token.clone())?
1300 })
1301 }
1302
1303 fn eval_array_literal_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1304 check_rule!(token, Rule::array_literal_exp);
1305 let mut arr = Vec::new();
1306 let mut pairs = token.into_inner();
1307 let token = pairs.next().unwrap();
1308
1309 if let Rule::array_literal_exp_special_case = token.as_rule() {
1311 return self.eval_array_literal_exp_special_case(token);
1312 }
1313
1314 arr.push(self.safe_parse_arg(token)?);
1315 for token in pairs {
1316 arr.push(self.safe_parse_arg(token)?);
1317 }
1318
1319 Ok(if arr.len() == 1 {
1320 arr[0].clone()
1321 } else {
1322 Val::Array(arr)
1323 })
1324 }
1325
1326 fn eval_range_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1327 fn range(mut left: i64, right: i64) -> Vec<Val> {
1328 let mut v = Vec::new();
1329 if left <= right {
1330 loop {
1331 v.push(left);
1332 if left == right {
1333 break;
1334 }
1335 left += 1;
1336 }
1337 } else {
1338 loop {
1339 v.push(left);
1340 if left == right {
1341 break;
1342 }
1343 left -= 1;
1344 }
1345 }
1346 v.into_iter().map(Val::Int).collect()
1347 }
1348 check_rule!(token, Rule::range_exp);
1349 let mut pairs = token.into_inner();
1350 let token = pairs.next().unwrap();
1351 let res = match token.as_rule() {
1352 Rule::decimal_integer => {
1353 let int_val = token.into_inner().next().unwrap();
1354 let left = int_val.as_str().parse::<i64>().unwrap();
1355 let token = pairs.next().unwrap();
1356 let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
1357 Val::Array(range(left, right))
1358 }
1359 Rule::array_literal_exp => {
1360 let res = self.eval_array_literal_exp(token)?;
1361 if let Some(token) = pairs.next() {
1362 let left = res.cast_to_int()?;
1363 let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
1364 Val::Array(range(left, right))
1365 } else {
1366 res
1367 }
1368 }
1369 _ => unexpected_token!(token),
1370 };
1371
1372 Ok(res)
1373 }
1374
1375 fn eval_format_impl(&mut self, format: Val, mut pairs: Pairs<'a>) -> ParserResult<Val> {
1376 fn format_with_vec(fmt: &str, args: Vec<Val>) -> ParserResult<String> {
1377 fn strange_special_case(fmt: &str, n: i64) -> String {
1378 fn split_digits(n: i64) -> Vec<u8> {
1379 n.abs() .to_string()
1381 .chars()
1382 .filter_map(|c| c.to_digit(10).map(|opt| opt as u8))
1383 .collect()
1384 }
1385
1386 let mut digits = split_digits(n);
1388 digits.reverse();
1389 let mut fmt_vec = fmt.as_bytes().to_vec();
1390 fmt_vec.reverse();
1391
1392 let mut i = 0;
1393 for digit in digits {
1394 while i < fmt_vec.len() {
1395 if fmt_vec[i] != b'0' {
1396 i += 1
1397 } else {
1398 fmt_vec[i] = digit + b'0';
1399 break;
1400 }
1401 }
1402 }
1403 fmt_vec.reverse();
1404 String::from_utf8(fmt_vec).unwrap_or_default()
1405 }
1406
1407 let mut output = String::new();
1408 let mut i = 0;
1409
1410 while i < fmt.len() {
1411 if fmt[i..].starts_with('{') {
1412 if let Some(end) = fmt[i..].find('}') {
1413 let token = &fmt[i + 1..i + end];
1414 let formatted = if token.contains(':') {
1415 let mut parts = token.split(':');
1416 let index: usize = if let Some(p) = parts.next() {
1417 p.parse().unwrap_or(0)
1418 } else {
1419 0
1420 };
1421
1422 let spec = parts.next();
1423 match args.get(index) {
1424 Some(val) => match spec {
1425 Some(s) if s.starts_with('N') => {
1426 let precision = s[1..].parse::<usize>().unwrap_or(2);
1427 if let Ok(f) = val.cast_to_float() {
1428 format!("{:.1$}", f, precision)
1429 } else {
1430 val.cast_to_string().to_string()
1431 }
1432 }
1433 Some(s) => strange_special_case(s, val.cast_to_int()?),
1434 None => val.cast_to_string().to_string(),
1435 },
1436 None => format!("{{{}}}", token), }
1439 } else if token.contains(',') {
1440 let mut parts = token.split(',');
1441 let index: usize = parts.next().unwrap().parse().unwrap_or(0);
1442 let spec = parts.next();
1443 match args.get(index) {
1444 Some(val) => match spec {
1445 Some(s) => {
1446 let spaces = s.parse::<usize>().unwrap_or(0);
1447 let spaces_str = " ".repeat(spaces);
1448 format!("{spaces_str}{}", val.cast_to_string())
1449 }
1450 _ => val.cast_to_string().to_string(),
1451 },
1452 None => format!("{{{}}}", token), }
1455 } else {
1456 let index: usize =
1457 Val::String(token.to_string().into()).cast_to_int()? as usize;
1458 match args.get(index) {
1459 Some(val) => val.cast_to_string().to_string(),
1460 None => format!("{{{}}}", token), }
1463 };
1464
1465 output.push_str(&formatted);
1466 i += end + 1;
1467 } else {
1468 output.push('{');
1469 i += 1;
1470 }
1471 } else {
1472 output.push(fmt[i..].chars().next().unwrap());
1473 i += 1;
1474 }
1475 }
1476
1477 Ok(output)
1478 }
1479
1480 Ok(if let Some(token) = pairs.next() {
1481 let first_fmt = format.cast_to_string();
1482
1483 let second_fmt = self.eval_range_exp(token)?;
1484 let res = self.eval_format_impl(second_fmt, pairs)?;
1485 Val::String(format_with_vec(first_fmt.as_str(), res.cast_to_array())?.into())
1486 } else {
1487 format
1488 })
1489 }
1490
1491 fn eval_format_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1492 check_rule!(token, Rule::format_exp);
1493 let mut pairs = token.into_inner();
1494 let format = self.eval_range_exp(pairs.next().unwrap())?;
1495 self.eval_format_impl(format, pairs)
1496 }
1497
1498 fn eval_mult(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1499 check_rule!(token, Rule::multiplicative_exp);
1500 let mut pairs = token.into_inner();
1501 let mut res = self.eval_format_exp(pairs.next().unwrap())?;
1502 while let Some(op) = pairs.next() {
1503 let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1504 log::error!("No arithmetic function for operator: {}", op.as_str());
1505 return Err(ParserError::NotImplemented(format!(
1506 "No arithmetic function for operator: {}",
1507 op.as_str()
1508 )));
1509 };
1510
1511 let postfix = pairs.next().unwrap();
1512 let right_op = self.eval_format_exp(postfix)?;
1513 res = fun(res, right_op)?;
1514 }
1515
1516 Ok(res)
1517 }
1518
1519 fn eval_additive(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1520 check_rule!(token, Rule::additive_exp);
1521
1522 let mut pairs = token.into_inner();
1523 let mut res = self.eval_mult(pairs.next().unwrap())?;
1524 while let Some(op) = pairs.next() {
1525 let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1527 log::error!("No arithmetic function for operator: {}", op.as_str());
1528 return Err(ParserError::NotImplemented(format!(
1529 "No arithmetic function for operator: {}",
1530 op.as_str()
1531 )));
1532 };
1533
1534 let mult = pairs.next().unwrap();
1535 let right_op = self.eval_mult(mult)?;
1536 res = fun(res, right_op)?;
1537 }
1538
1539 Ok(res)
1540 }
1541
1542 fn eval_split_special_case(
1543 &mut self,
1544 script_block: ScriptBlock,
1545 input: Val,
1546 ) -> ParserResult<Vec<String>> {
1547 let mut res_vec = vec![];
1548 let mut parts = String::new();
1549 let input_str = input.cast_to_string();
1550 let characters = input_str.chars();
1551
1552 for ch in characters {
1554 let b = match script_block.run(vec![], self, Some(Val::String(ch.to_string().into()))) {
1555 Err(er) => {
1556 self.errors.push(er);
1557 false
1558 }
1559 Ok(res) => res.val.cast_to_bool(),
1560 };
1561
1562 if b {
1563 res_vec.push(parts);
1564 parts = String::new();
1565 } else {
1566 parts.push(ch);
1567 }
1568 }
1569 self.variables.reset_ps_item();
1570 Ok(res_vec)
1571 }
1572
1573 fn eval_comparison_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1574 check_rule!(token, Rule::comparison_exp);
1575 let mut pairs = token.into_inner();
1576 let token = pairs.next().unwrap();
1577
1578 let mut res = if token.as_rule() == Rule::additive_exp {
1581 self.eval_additive(token)?
1582 } else {
1583 Val::Null
1584 };
1585
1586 while let Some(op) = pairs.next() {
1587 let Some(fun) = StringPred::get(op.as_str()) else {
1588 log::error!("No string predicate for operator: {}", op.as_str());
1589 return Err(ParserError::NotImplemented(format!(
1590 "No string predicate for operator: {}",
1591 op.as_str()
1592 )));
1593 };
1594
1595 let token = pairs.next().unwrap();
1596 let right_op = match token.as_rule() {
1597 Rule::script_block_expression => {
1598 let script_block = self.parse_script_block_expression(token)?;
1599
1600 return Ok(Val::Array(
1601 self.eval_split_special_case(script_block, res)?
1602 .into_iter()
1603 .map(|s| Val::String(s.into()))
1604 .collect::<Vec<_>>(),
1605 ));
1606 }
1607 Rule::additive_exp => self.eval_additive(token)?,
1608 _ => unexpected_token!(token),
1610 };
1611 log::trace!("res: {:?}, right_op: {:?}", &res, &right_op);
1612 res = fun(res, right_op)?;
1613 log::trace!("res: {:?}", &res);
1614 }
1615
1616 Ok(res)
1617 }
1618
1619 fn parse_script_param_block(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1620 check_rule!(token, Rule::script_param_block);
1621 let mut pairs = token.into_inner();
1622 let Some(param_block_token) = pairs.next() else {
1623 return Ok(vec![]);
1624 };
1625 self.parse_param_block(param_block_token)
1626 }
1627
1628 fn parse_param_block(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1629 check_rule!(token, Rule::param_block);
1630 let mut pairs = token.into_inner();
1631
1632 let Some(token) = pairs.next() else {
1633 return Ok(vec![]);
1634 };
1635
1636 let option_param_token = match token.as_rule() {
1637 Rule::attribute_list => {
1638 pairs.next()
1640 }
1641 Rule::parameter_list => Some(token),
1642 _ => unexpected_token!(token),
1643 };
1644
1645 let Some(param_token) = option_param_token else {
1646 return Ok(vec![]);
1647 };
1648 self.parse_parameter_list(param_token)
1649 }
1650
1651 fn parse_parameter_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1652 check_rule!(token, Rule::parameter_list);
1653 let mut params = vec![];
1654 let param_list_pairs = token.into_inner();
1655 for script_parameter_token in param_list_pairs {
1656 check_rule!(script_parameter_token, Rule::script_parameter);
1657 params.push(self.parse_script_parameter(script_parameter_token)?);
1658 }
1659 Ok(params)
1660 }
1661
1662 fn parse_attribute_list(&mut self, token: Pair<'a>) -> ParserResult<Option<ValType>> {
1663 check_rule!(token, Rule::attribute_list);
1664 let attribute_list_pairs = token.into_inner();
1665 for attribute_token in attribute_list_pairs {
1666 check_rule!(attribute_token, Rule::attribute);
1667 let attribute_type_token = attribute_token.into_inner().next().unwrap();
1668 match attribute_type_token.as_rule() {
1669 Rule::attribute_info => {
1670 continue;
1672 }
1673 Rule::type_literal => {
1674 return Ok(Some(
1675 self.get_valtype_from_type_literal(attribute_type_token)?,
1676 ));
1677 }
1678 _ => unexpected_token!(attribute_type_token),
1679 }
1680 }
1681 Ok(None)
1682 }
1683 fn parse_script_parameter(&mut self, token: Pair<'a>) -> ParserResult<Param> {
1684 check_rule!(token, Rule::script_parameter);
1685 let mut pairs = token.into_inner();
1686 let mut token = pairs.next().unwrap();
1687
1688 let type_literal = if token.as_rule() == Rule::attribute_list {
1689 let type_literal = self.parse_attribute_list(token)?;
1690 token = pairs.next().unwrap();
1691 type_literal
1692 } else {
1693 None
1694 };
1695
1696 check_rule!(token, Rule::variable);
1697 let var_name = Self::parse_variable(token)?;
1698
1699 let default_value = if let Some(default_value_token) = pairs.next() {
1700 check_rule!(default_value_token, Rule::script_parameter_default);
1701 let default_value_expr = default_value_token.into_inner().next().unwrap();
1702 let default_value = self.eval_value(default_value_expr)?;
1703 Some(default_value)
1704 } else {
1705 None
1706 };
1707 Ok(Param::new(type_literal, var_name.name, default_value))
1708 }
1709
1710 fn eval_bitwise_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1711 check_rule!(token, Rule::bitwise_exp);
1712
1713 let mut pairs = token.into_inner();
1714 let mut res = self.eval_as_exp(pairs.next().unwrap())?;
1715 while let Some(op) = pairs.next() {
1716 check_rule!(op, Rule::bitwise_operator);
1717 let Some(fun) = BitwisePred::get(op.as_str()) else {
1718 log::error!("No bitwise predicate for operator: {}", op.as_str());
1719 return Err(ParserError::NotImplemented(format!(
1720 "No bitwise predicate for operator: {}",
1721 op.as_str()
1722 )));
1723 };
1724
1725 let mult = pairs.next().unwrap();
1726 let right_op = self.eval_as_exp(mult)?;
1727 res = fun(res, right_op)?;
1728 }
1729
1730 Ok(res)
1731 }
1732
1733 fn eval_as_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1734 check_rule!(token, Rule::as_expression);
1735
1736 let mut pairs = token.into_inner();
1737 let mut res = self.eval_comparison_exp(pairs.next().unwrap())?;
1738 for token in pairs {
1739 let runtime_object = match token.as_rule() {
1740 Rule::type_literal => self.eval_type_literal(token)?,
1741 Rule::comparison_exp => self.eval_comparison_exp(token)?,
1742 _ => unexpected_token!(token),
1743 };
1744
1745 res = res.cast(&runtime_object).unwrap_or_default();
1746 }
1747
1748 Ok(res)
1749 }
1750
1751 fn parse_cmdlet_command_name(&mut self, token: Pair<'a>) -> ParserResult<Command> {
1752 check_rule!(token, Rule::cmdlet_command);
1753
1754 let mut pairs = token.into_inner();
1755 let token = pairs.next().unwrap();
1756 let command_name = match token.as_rule() {
1757 Rule::command_name => token.as_str(),
1758 Rule::where_command_name => "where-object",
1759 Rule::foreach_command_name => "foreach-object",
1760 Rule::powershell_command_name => "powershell",
1761 _ => unexpected_token!(token),
1762 };
1763
1764 let mut command = Command::cmdlet(command_name);
1765 if Rule::command_name == token.as_rule() {
1766 command.set_session_scope(SessionScope::New);
1767 }
1768 Ok(command)
1769 }
1770
1771 fn parse_command_args(&mut self, pairs: Pairs<'a>) -> ParserResult<Vec<CommandElem>> {
1772 let mut args = vec![];
1773 for command_element_token in pairs {
1774 let token_string = command_element_token.as_str().to_string();
1775 match command_element_token.as_rule() {
1776 Rule::command_argument => {
1777 let arg_token = command_element_token.into_inner().next().unwrap();
1778 let arg = match arg_token.as_rule() {
1779 Rule::array_literal_exp => self.eval_array_literal_exp(arg_token)?,
1780 Rule::script_block_expression => {
1781 Val::ScriptBlock(self.parse_script_block_expression(arg_token)?)
1782 }
1783 Rule::parenthesized_expression => {
1784 let token = arg_token.into_inner().next().unwrap();
1785 self.eval_pipeline(token)?
1786 }
1787 _ => Val::ScriptText(arg_token.as_str().to_string()),
1788 };
1789 args.push(CommandElem::Argument(arg));
1790 }
1791 Rule::command_parameter => {
1792 args.push(CommandElem::Parameter(token_string.to_ascii_lowercase()))
1793 }
1794 Rule::argument_list => args.push(CommandElem::ArgList(token_string)),
1795 Rule::splatten_arg => {
1796 let var_name = Self::parse_scoped_variable(command_element_token)?;
1797 let var = self.variables.get(&var_name).unwrap_or_default();
1798 if let Val::HashTable(h) = var {
1799 for (k, v) in h {
1800 args.push(CommandElem::Parameter(format!("-{}", k)));
1801 args.push(CommandElem::Argument(v));
1802 }
1803 }
1804 }
1805 Rule::redirection => { }
1807 Rule::stop_parsing => { }
1809 _ => unexpected_token!(command_element_token),
1810 }
1811 }
1812 Ok(args)
1813 }
1814
1815 fn eval_command(&mut self, token: Pair<'a>, piped_arg: Option<Val>) -> ParserResult<Val> {
1816 check_rule!(token, Rule::command);
1817 let command_str = token.as_str().to_string();
1818
1819 let mut pairs = token.into_inner();
1820 let command_token = pairs.next().unwrap();
1821 let mut command = match command_token.as_rule() {
1822 Rule::cmdlet_command => self.parse_cmdlet_command_name(command_token)?,
1823 Rule::invocation_command => self.parse_invocation_command(command_token)?,
1824 _ => unexpected_token!(command_token),
1825 };
1826
1827 let mut args = self.parse_command_args(pairs)?;
1828 if let Some(arg) = piped_arg {
1829 args.insert(0, CommandElem::Argument(arg));
1830 }
1831
1832 command.with_args(args);
1833 self.tokens
1834 .push(Token::command(command_str, command.name(), command.args()));
1835
1836 match command.execute(self) {
1837 Ok(CommandOutput {
1838 val,
1839 deobfuscated: _deobfuscated,
1840 }) => Ok(val),
1841 Err(e) => {
1842 self.errors.push(e);
1843 Ok(Val::ScriptText(command.to_string()))
1844 }
1845 }
1846
1847 }
1851
1852 fn add_deobfuscated_statement(&mut self, msg: String) {
1853 if let Some(last) = self.results.last_mut() {
1854 last.deobfuscated.push(msg);
1855 }
1856 }
1857
1858 fn add_output_statement(&mut self, msg: StreamMessage) {
1859 if let Some(last) = self.results.last_mut() {
1860 last.output.push(msg);
1861 }
1862 }
1863
1864 fn parse_invocation_command(&mut self, token: Pair<'a>) -> ParserResult<Command> {
1865 check_rule!(token, Rule::invocation_command);
1866
1867 let invocation_command_token = token.into_inner().next().unwrap();
1868
1869 let mut session_scope = match invocation_command_token.as_rule() {
1870 Rule::current_scope_invocation_command => SessionScope::Current,
1871 Rule::new_scope_invocation_command => SessionScope::New,
1872 _ => unexpected_token!(invocation_command_token),
1873 };
1874
1875 let token_inner = invocation_command_token.into_inner().next().unwrap();
1876
1877 let mut command = match token_inner.as_rule() {
1878 Rule::cmdlet_command => {
1879 session_scope = SessionScope::New;
1880 self.parse_cmdlet_command_name(token_inner)?
1881 }
1882 Rule::primary_expression => {
1883 let primary = self.eval_primary_expression(token_inner)?;
1884 if let Val::ScriptBlock(script_block) = primary {
1885 Command::script_block(script_block)
1886 } else {
1887 Command::cmdlet(&primary.cast_to_script())
1888 }
1889 }
1890 Rule::path_command_name => Command::path(token_inner.as_str()),
1891 _ => unexpected_token!(token_inner),
1892 };
1893
1894 command.set_session_scope(session_scope);
1895 Ok(command)
1896 }
1897
1898 fn eval_redirected_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1899 check_rule!(token, Rule::redirected_expression);
1900
1901 let expression_token = token.into_inner().next().unwrap();
1902 self.eval_expression(expression_token)
1905 }
1906
1907 fn eval_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1908 check_rule!(token, Rule::expression);
1909 let token_string = token.as_str().trim().to_string();
1910
1911 let mut pairs = token.into_inner();
1912 let mut res = self.eval_bitwise_exp(pairs.next().unwrap())?;
1913 while let Some(op) = pairs.next() {
1914 check_rule!(op, Rule::logical_operator);
1915 let Some(fun) = LogicalPred::get(op.as_str()) else {
1916 log::error!("No logical predicate for operator: {}", op.as_str());
1917 return Err(ParserError::NotImplemented(format!(
1918 "No logical predicate for operator: {}",
1919 op.as_str()
1920 )));
1921 };
1922
1923 let mult = pairs.next().unwrap();
1924 let right_op = self.eval_bitwise_exp(mult)?;
1925 res = Val::Bool(fun(res, right_op));
1926 }
1927 self.tokens
1928 .push(Token::expression(token_string, res.clone().into()));
1929
1930 if let Val::String(value::PsString(s)) = &res {
1931 self.tokens.push(Token::String(s.clone()));
1932 }
1933
1934 Ok(res)
1935 }
1936
1937 fn eval_pipeline_tail(&mut self, token: Pair<'a>, mut piped_arg: Val) -> ParserResult<Val> {
1938 check_rule!(token, Rule::pipeline_tail);
1939 let pairs = token.into_inner();
1940
1941 for token in pairs {
1942 piped_arg = self.eval_command(token, Some(piped_arg))?;
1944 }
1945
1946 Ok(piped_arg)
1947 }
1948
1949 fn eval_pipeline_with_tail(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1950 check_rule!(token, Rule::pipeline_with_tail);
1951 let mut pairs = token.into_inner();
1952 let token = pairs.next().unwrap();
1953
1954 let result: Val = match token.as_rule() {
1955 Rule::redirected_expression => self.eval_redirected_expression(token)?,
1956 Rule::command => self.eval_command(token, None)?,
1957 _ => unexpected_token!(token),
1958 };
1959
1960 if let Some(token) = pairs.next() {
1961 match token.as_rule() {
1962 Rule::pipeline_tail => Ok(self.eval_pipeline_tail(token, result)?),
1963 _ => unexpected_token!(token),
1964 }
1965 } else {
1966 Ok(result)
1967 }
1968 }
1969
1970 fn eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1971 check_rule!(token, Rule::pipeline);
1972 let mut pairs = token.into_inner();
1973 let token = pairs.next().unwrap();
1974
1975 match token.as_rule() {
1976 Rule::assignment_exp => self.eval_assigment_exp(token),
1977 Rule::pipeline_with_tail => self.eval_pipeline_with_tail(token),
1978 _ => unexpected_token!(token),
1979 }
1980 }
1981
1982 fn safe_eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1983 let res = self.eval_pipeline(token.clone());
1984
1985 let v = match res {
1986 Ok(val) => val,
1987 Err(err) => {
1988 self.errors.push(err);
1989 Val::ScriptText(token.as_str().to_string())
1990 }
1991 };
1992
1993 Ok(v)
1994 }
1995
1996 fn eval_cast_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1997 check_rule!(token, Rule::cast_expression);
1998
1999 let mut pairs = token.into_inner();
2000 let type_token = pairs.next().unwrap();
2001 check_rule!(type_token, Rule::type_literal);
2002 let val_type = self.eval_type_literal(type_token)?;
2003 let token = pairs.next().unwrap();
2004 let res = match token.as_rule() {
2005 Rule::parenthesized_expression => {
2006 let token = token.into_inner().next().unwrap();
2007 self.safe_eval_pipeline(token)?
2008 }
2009 Rule::unary_exp => self.eval_unary_exp(token)?,
2010 _ => unexpected_token!(token),
2011 };
2012 Ok(res.cast(&val_type)?)
2013 }
2014
2015 fn eval_assigment_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
2016 check_rule!(token, Rule::assignment_exp);
2017
2018 let mut specified_type = None;
2019
2020 let mut pairs = token.into_inner();
2021 let mut token = pairs.next().unwrap();
2022 if token.as_rule() == Rule::type_literal {
2023 specified_type = Some(self.eval_type_literal(token)?);
2024 token = pairs.next().unwrap();
2025 }
2026 let (var_name, access) = self.parse_assignable_variable(token)?;
2027 let mut variable = self.variables.get(&var_name).unwrap_or_default();
2028 let mut accessed_elem = &mut variable;
2029
2030 if let Some(access) = access {
2033 for token in access {
2034 accessed_elem = self.variable_access(token, accessed_elem)?;
2035 }
2036 }
2037 let assignement_op = pairs.next().unwrap();
2038
2039 let op = assignement_op.into_inner().next().unwrap();
2041 let pred = ArithmeticPred::get(op.as_str());
2042
2043 let right_token = pairs.next().unwrap();
2044 let right_op = self.eval_statement(right_token.clone())?;
2045
2046 let Some(pred) = pred else {
2047 log::error!("No arithmetic function for operator: {}", op.as_str());
2048 return Err(ParserError::NotImplemented(format!(
2049 "No arithmetic function for operator: {}",
2050 op.as_str()
2051 )));
2052 };
2053
2054 *accessed_elem = pred(accessed_elem.clone(), right_op)?;
2055 if let Some(runtime_type) = specified_type {
2056 *accessed_elem = accessed_elem.cast(&runtime_type)?;
2057 }
2058 self.variables.set(&var_name, variable.clone())?;
2059 self.add_deobfuscated_statement(format!("{} = {}", var_name, variable.cast_to_script()));
2061
2062 Ok(Val::NonDisplayed(Box::new(variable)))
2063 }
2064
2065 fn push_scope_session(&mut self) {
2066 self.variables.push_scope_session();
2067 }
2068
2069 fn pop_scope_session(&mut self) {
2070 self.variables.pop_scope_session();
2071 }
2072}
2073
2074#[cfg(test)]
2075mod tests {
2076 use pest::Parser;
2077
2078 use super::*;
2079
2080 #[test]
2081 fn comment_and_semicolon() {
2082 let input = r#"
2083# This is a single line comment
2084$a = 1; $b = 2; Write-Output $a
2085
2086Write-Output "Hello" # Another comment
2087
2088<#
2089 This is a
2090 multi-line block comment
2091#>
2092"#;
2093
2094 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2095 }
2096
2097 #[test]
2098 fn while_loop() {
2099 let input = r#"
2100while ($true) {
2101 if ($someCondition) {
2102 break
2103 }
2104 # other code
2105}
2106"#;
2107
2108 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2109 }
2110
2111 #[test]
2112 fn foreach_loop() {
2113 let input = r#"
2114foreach ($n in $numbers) {
2115 Write-Output $n
2116}
2117"#;
2118
2119 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2120 }
2121
2122 #[test]
2123 fn for_loop() {
2124 let input = r#"
2125# Comma separated assignment expressions enclosed in parentheses.
2126for (($i = 0), ($j = 0); $i -lt 10; $i++)
2127{
2128 "`$i:$i"
2129 "`$j:$j"
2130}
2131"#;
2132
2133 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2134 }
2135
2136 #[test]
2137 fn switch() {
2138 let input = r#"
2139switch ($var) {
2140 "a" { Write-Output "A" }
2141 1 { Write-Output "One" }
2142 default { Write-Output "Other" }
2143}
2144"#;
2145
2146 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2147 }
2148
2149 #[test]
2150 fn functions() {
2151 let input = r#"
2152function Get-Square {
2153 param($x)
2154 return $x * $x
2155}
2156
2157function Say-Hello {
2158 Write-Output "Hello"
2159}
2160"#;
2161
2162 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2163 }
2164
2165 #[test]
2166 fn if_expression() {
2167 let input = r#"
2168$x="hello"
2169 Write-Host $x
2170 $y = 42
2171 Start-Process "notepad.exe"
2172
2173 $x = 42
2174if ($x -eq 1) {
2175 Write-Output "One"
2176} elseif ($x -eq 2) {
2177 Write-Output "Two"
2178} else {
2179 Write-Output "Other"
2180}
2181"#;
2182
2183 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2184 }
2185
2186 #[test]
2187 fn command() {
2188 let input = r#"
2189Get-Process | Where-Object { $_.CPU -gt 100 }
2190"#;
2191
2192 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2193 }
2194
2195 #[test]
2196 fn range() {
2197 let input = r#"
2198$numbers = 1..5
2199"#;
2200
2201 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2202 }
2203
2204 #[test]
2205 fn literals() {
2206 let input = r#"
2207$hex = 0xFF
2208
2209$name = "Alice"
2210$msg = "Hello, $name. Today is $day."
2211$escaped = "She said: `"Hi`""
2212$literal = 'Hello, $name'
2213"#;
2214
2215 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2216 }
2217
2218 #[test]
2219 fn floats() {
2220 let input = r#"
2221 $pi = 3.1415
2222$half = .5
2223"#;
2224
2225 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2226 }
2227
2228 #[test]
2229 fn arrays() {
2230 let input = r#"
2231$a = 1, 2, 3
2232$b = @("one", "two", "three")
2233$c = @(1, 2, @(3, 4))
2234"#;
2235
2236 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2237 }
2238
2239 #[test]
2240 fn static_method_call() {
2241 let input = r#"
2242[Threading.Thread]::Sleep(399)
2243"#;
2244
2245 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2246 }
2247
2248 #[test]
2249 fn neg_pipeline() {
2250 let input = r#"
2251-not $input | Where-Object { $_ -gt 5 }
2252"#;
2253
2254 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2255 }
2256
2257 #[test]
2258 fn amsi_fail() {
2259 let input = r#"
2260#Matt Graebers second Reflection method
2261$VMRviwsbtehQfPtxbt=$null;
2262$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))"
2263
2264"#;
2265
2266 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
2267 }
2268}