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