mago_analyzer/plugin/libraries/stdlib/session/
session_set_cookie_params.rs1use mago_reporting::Annotation;
2use mago_reporting::Issue;
3use mago_span::HasSpan;
4use mago_syntax::cst::Argument;
5use mago_syntax::cst::Expression;
6use mago_syntax::cst::FunctionCall;
7
8use crate::code::IssueCode;
9use crate::plugin::context::HookContext;
10use crate::plugin::hook::FunctionCallHook;
11use crate::plugin::hook::HookResult;
12use crate::plugin::provider::Provider;
13use crate::plugin::provider::ProviderMeta;
14
15#[derive(Default)]
24pub struct SessionSetCookieParamsHook;
25
26impl Provider for SessionSetCookieParamsHook {
27 fn meta() -> &'static ProviderMeta {
28 static META: ProviderMeta = ProviderMeta::new(
29 "php::session::session_set_cookie_params",
30 "session_set_cookie_params",
31 "Validates session_set_cookie_params argument combinations.",
32 );
33
34 &META
35 }
36}
37
38impl FunctionCallHook for SessionSetCookieParamsHook {
39 fn after_function_call(&self, call: &FunctionCall<'_>, context: &mut HookContext<'_, '_>) -> HookResult<()> {
40 let Expression::Identifier(identifier) = call.function else {
41 return Ok(());
42 };
43
44 if !identifier.value().eq_ignore_ascii_case(b"session_set_cookie_params") {
45 return Ok(());
46 }
47
48 let arguments = &call.argument_list.arguments;
49 if arguments.len() <= 1 {
50 return Ok(());
51 }
52
53 let Some(first_arg) = arguments.get(0) else {
54 return Ok(());
55 };
56
57 let first_arg_expr = match first_arg {
58 Argument::Positional(arg) => arg.value,
59 Argument::Named(arg) => arg.value,
60 };
61
62 let Some(first_arg_type) = context.get_expression_type(first_arg_expr) else {
63 return Ok(());
64 };
65
66 if !first_arg_type.has_array() {
67 return Ok(());
68 }
69
70 let Some(second_arg) = arguments.get(1) else {
72 return Ok(());
73 };
74
75 let span = match second_arg {
76 Argument::Positional(arg) => arg.value.span(),
77 Argument::Named(arg) => arg.span(),
78 };
79
80 context.report(
81 IssueCode::TooManyArguments,
82 Issue::error("Too many arguments provided for function `session_set_cookie_params`.")
83 .with_annotation(Annotation::primary(span).with_message("Unexpected argument provided here"))
84 .with_annotation(
85 Annotation::secondary(call.function.span()).with_message("For this function call"),
86 )
87 .with_note(format!(
88 "When the first argument is an array, `session_set_cookie_params()` expects exactly 1 argument, but received {}.",
89 arguments.len()
90 ))
91 .with_help("Remove the extra arguments and pass options in the array instead."),
92 );
93
94 Ok(())
95 }
96}