Skip to content

Commit

Permalink
Support taints for preg_match_with_matches
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Mar 24, 2024
1 parent 1eecfbb commit 7a98677
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 44 deletions.
40 changes: 15 additions & 25 deletions src/analyzer/expr/binop/assignment_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ pub(crate) fn analyze(
assign_var,
assign_value,
assign_value_type,
existing_var_type,
var_id.as_ref().unwrap(),
analysis_data,
context,
Expand Down Expand Up @@ -576,35 +575,26 @@ fn analyze_assignment_to_variable(
statements_analyzer: &StatementsAnalyzer,
var_expr: &aast::Expr<(), ()>,
source_expr: Option<&aast::Expr<(), ()>>,
mut assign_value_type: TUnion,
existing_var_type: Option<Rc<TUnion>>,
assign_value_type: TUnion,
var_id: &String,
analysis_data: &mut FunctionAnalysisData,
context: &mut ScopeContext,
is_inout: bool,
) {
if analysis_data.data_flow_graph.kind == GraphKind::FunctionBody {
if !is_inout {
analysis_data
.data_flow_graph
.add_node(DataFlowNode::get_for_variable_source(
var_id.clone(),
statements_analyzer.get_hpos(var_expr.pos()),
!context.inside_awaitall
&& if let Some(source_expr) = source_expr {
analysis_data.is_pure(source_expr.pos())
} else {
false
},
assign_value_type.has_awaitable_types(),
));
} else if let Some(existing_var_type) = &existing_var_type {
if !existing_var_type.parent_nodes.is_empty() {
assign_value_type
.parent_nodes
.clone_from(&existing_var_type.parent_nodes);
}
}
if analysis_data.data_flow_graph.kind == GraphKind::FunctionBody && !is_inout {
analysis_data
.data_flow_graph
.add_node(DataFlowNode::get_for_variable_source(
var_id.clone(),
statements_analyzer.get_hpos(var_expr.pos()),
!context.inside_awaitall
&& if let Some(source_expr) = source_expr {
analysis_data.is_pure(source_expr.pos())
} else {
false
},
assign_value_type.has_awaitable_types(),
));
}

let assign_value_type = check_variable_or_property_assignment(
Expand Down
55 changes: 37 additions & 18 deletions src/analyzer/expr/call/arguments_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::BTreeMap;
use std::sync::Arc;

use hakana_reflection_info::assertion::Assertion;
use hakana_reflection_info::data_flow::path::PathKind;
use hakana_reflection_info::{GenericParent, EFFECT_WRITE_LOCAL};

use hakana_reflection_info::data_flow::node::DataFlowNode;
Expand Down Expand Up @@ -33,8 +34,7 @@ use hakana_type::template::{
};
use hakana_type::type_expander::{self, StaticClassType, TypeExpansionOptions};
use hakana_type::{
add_optional_union_type, combine_optional_union_types, extend_dataflow_uniquely, get_arraykey,
get_mixed_any, wrap_atomic,
add_optional_union_type, combine_optional_union_types, get_arraykey, get_mixed_any, wrap_atomic,
};
use indexmap::IndexMap;
use oxidized::ast_defs::ParamKind;
Expand Down Expand Up @@ -391,6 +391,7 @@ pub(crate) fn check_arguments_match(
analysis_data,
function_param,
functionlike_id,
args,
argument_offset,
arg_expr,
class_storage,
Expand Down Expand Up @@ -965,6 +966,7 @@ fn handle_possibly_matching_inout_param(
analysis_data: &mut FunctionAnalysisData,
functionlike_param: &FunctionLikeParameter,
functionlike_id: &FunctionLikeIdentifier,
all_args: &[(ast_defs::ParamKind, aast::Expr<(), ()>)],
argument_offset: usize,
expr: &aast::Expr<(), ()>,
classlike_storage: Option<&ClassLikeInfo>,
Expand Down Expand Up @@ -1048,33 +1050,50 @@ fn handle_possibly_matching_inout_param(

let arg_type = arg_type.unwrap_or(get_mixed_any());

let out_node = DataFlowNode::get_for_method_argument_out(
functionlike_id.to_string(statements_analyzer.get_interner()),
argument_offset,
Some(functionlike_param.name_location),
Some(statements_analyzer.get_hpos(function_call_pos)),
);

inout_type.parent_nodes = vec![out_node.clone()];

for arg_node in &arg_type.parent_nodes {
analysis_data.data_flow_graph.add_path(
arg_node,
&out_node,
PathKind::Default,
vec![],
vec![],
);
}

if functionlike_id == &FunctionLikeIdentifier::Function(StrId::PREG_MATCH_WITH_MATCHES)
&& argument_offset == 2
{
let function_call_node = DataFlowNode::get_for_method_return(
let argument_node = DataFlowNode::get_for_method_argument(
functionlike_id.to_string(statements_analyzer.get_interner()),
Some(statements_analyzer.get_hpos(function_call_pos)),
1,
Some(statements_analyzer.get_hpos(all_args[1].1.pos())),
Some(statements_analyzer.get_hpos(function_call_pos)),
);

inout_type.parent_nodes.push(function_call_node);
}
analysis_data
.data_flow_graph
.add_node(argument_node.clone());

if let GraphKind::WholeProgram(_) = &analysis_data.data_flow_graph.kind {
let out_node = DataFlowNode::get_for_method_argument_out(
functionlike_id.to_string(statements_analyzer.get_interner()),
argument_offset,
Some(functionlike_param.name_location),
Some(statements_analyzer.get_hpos(function_call_pos)),
analysis_data.data_flow_graph.add_path(
&argument_node,
&out_node,
PathKind::Default,
vec![],
vec![],
);

inout_type.parent_nodes = vec![out_node.clone()];

analysis_data.data_flow_graph.add_node(out_node);
} else {
extend_dataflow_uniquely(&mut inout_type.parent_nodes, arg_type.parent_nodes.clone());
}

analysis_data.data_flow_graph.add_node(out_node);

assignment_analyzer::analyze_inout_param(
statements_analyzer,
expr,
Expand Down
2 changes: 1 addition & 1 deletion src/analyzer/expr/fetch/class_constant_fetch_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ fn analyse_known_class_constant(
&TypeExpansionOptions {
evaluate_conditional_types: true,
expand_generic: true,
self_class: Some(&classlike_name),
self_class: Some(classlike_name),
static_class_type: StaticClassType::Object(&this_class),
parent_class: None,
file_path: Some(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function generate_diff(string $wanted_re): mixed {
$m = null;
preg_match_with_matches('/^\((.*)\)\{(\d+)\}$/s', $wanted_re, inout $m);
return $m;
}

0 comments on commit 7a98677

Please sign in to comment.