Skip to content
This repository was archived by the owner on Jun 26, 2026. It is now read-only.

Commit a4df923

Browse files
arthaudfacebook-github-bot
authored andcommitted
Rename BreadcrumbSet into BreadcrumbMayAlwaysSet
Summary: The `BreadcrumbSet` module actually represents an over and under approximation set, or may-always set, i.e two sets. There are cases where we actually want a simple set of breadcrumbs, without the over and under approximation. To make this clear in the codebase, this diff renames `BreadcrumbSet` into `BreadcrumbMayAlwaysSet` (terminology used by Mariana Trench), and introduces a proper `BreadcrumbSet` module. Reviewed By: tianhan0 Differential Revision: D77373734 fbshipit-source-id: da31823d9643f18483dcc99ad80d39087c0b8a75
1 parent fa94b46 commit a4df923

12 files changed

Lines changed: 191 additions & 129 deletions

File tree

source/domains/abstractOverUnderSetDomain.ml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ type 'a approximation = {
1818
module type S = sig
1919
include AbstractSetDomain.S
2020

21+
type set
22+
2123
type _ AbstractDomainCore.part += ElementAndUnder : element approximation AbstractDomainCore.part
2224

2325
val empty : t
@@ -30,6 +32,8 @@ module type S = sig
3032

3133
val of_approximation : element approximation list -> t
3234

35+
val of_set : set -> t
36+
3337
val add_set : t -> to_add:t -> t
3438

3539
val sequence_join : t -> t -> t
@@ -47,11 +51,13 @@ module MakeWithSet (Set : AbstractSetDomain.SET) = struct
4751

4852
module rec Base : (BASE with type t := biset) = MakeBase (Domain)
4953

50-
and Domain : (S with type t = biset and type element = Set.element) = struct
54+
and Domain : (S with type t = biset and type element = Set.element and type set = Set.t) = struct
5155
(* Implicitly under <= over at all times. Note that Bottom is different from ({}, {}) since ({},
5256
{}) is not less or equal to e.g. ({a}, {a}) *)
5357
type t = biset
5458

59+
type set = Set.t
60+
5561
type element = Set.element
5662

5763
type _ part +=
@@ -179,6 +185,8 @@ module MakeWithSet (Set : AbstractSetDomain.SET) = struct
179185

180186
let of_approximation elements = ListLabels.fold_left ~f:add_element ~init:empty elements
181187

188+
let of_set set = BiSet { over = set; under = set }
189+
182190
let over_to_under set =
183191
match set with
184192
| Bottom -> Bottom

source/domains/abstractOverUnderSetDomain.mli

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ type 'a approximation = {
1313
module type S = sig
1414
include AbstractSetDomain.S
1515

16+
type set
17+
1618
type _ AbstractDomainCore.part += ElementAndUnder : element approximation AbstractDomainCore.part
1719

1820
(* Distinct from bottom in that it has no elements present, which will cause joins to
@@ -28,6 +30,8 @@ module type S = sig
2830

2931
val of_approximation : element approximation list -> t
3032

33+
val of_set : set -> t
34+
3135
val add_set : t -> to_add:t -> t
3236

3337
(* Normal join models an either/or outcome, e.g. two distinct paths, where as sequence_join models
@@ -39,6 +43,7 @@ module type S = sig
3943
val over_to_under : t -> t
4044
end
4145

42-
module MakeWithSet (Set : AbstractSetDomain.SET) : S with type element = Set.element
46+
module MakeWithSet (Set : AbstractSetDomain.SET) :
47+
S with type element = Set.element and type set = Set.t
4348

4449
module Make (Element : AbstractSetDomain.ELEMENT) : S with type element = Element.t

source/interprocedural_analyses/taint/backwardAnalysis.ml

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,9 @@ module State (FunctionContext : FUNCTION_CONTEXT) = struct
406406
state
407407
else
408408
let breadcrumbs =
409-
breadcrumbs |> Model.AddBreadcrumbsToState.elements |> Features.BreadcrumbSet.of_list
409+
breadcrumbs
410+
|> Model.AddBreadcrumbsToState.elements
411+
|> Features.BreadcrumbMayAlwaysSet.of_list
410412
in
411413
{
412414
taint =
@@ -468,7 +470,9 @@ module State (FunctionContext : FUNCTION_CONTEXT) = struct
468470
taint_model;
469471
let call_taint =
470472
BackwardState.Tree.add_local_breadcrumbs
471-
(Features.type_breadcrumbs (Option.value_exn return_type))
473+
(Option.value_exn return_type
474+
|> Features.type_breadcrumbs
475+
|> Features.BreadcrumbMayAlwaysSet.of_set)
472476
call_taint
473477
in
474478
let initial_state =
@@ -578,7 +582,7 @@ module State (FunctionContext : FUNCTION_CONTEXT) = struct
578582
BackwardState.Tree.transform_non_tito
579583
Features.LocalKindSpecificBreadcrumbSet.Self
580584
Map
581-
~f:(Features.BreadcrumbSet.add breadcrumb)
585+
~f:(Features.BreadcrumbMayAlwaysSet.add breadcrumb)
582586
taint_to_propagate
583587
in
584588
add_extra_traces_for_tito_transforms
@@ -717,7 +721,7 @@ module State (FunctionContext : FUNCTION_CONTEXT) = struct
717721
BackwardState.Tree.filter_by_kind ~kind:Sinks.AddFeatureToArgument sink_taint
718722
|> BackwardTaint.joined_breadcrumbs
719723
in
720-
if Features.BreadcrumbSet.is_bottom breadcrumbs_to_add then
724+
if Features.BreadcrumbMayAlwaysSet.is_bottom breadcrumbs_to_add then
721725
state
722726
else
723727
let taint =
@@ -1553,7 +1557,10 @@ module State (FunctionContext : FUNCTION_CONTEXT) = struct
15531557
let callees = get_call_callees ~location ~call:{ Call.callee; arguments; origin } in
15541558

15551559
let add_type_breadcrumbs taint =
1556-
let type_breadcrumbs = CallModel.type_breadcrumbs_of_calls callees.call_targets in
1560+
let type_breadcrumbs =
1561+
CallModel.type_breadcrumbs_of_calls callees.call_targets
1562+
|> Features.BreadcrumbMayAlwaysSet.of_set
1563+
in
15571564
BackwardState.Tree.add_local_breadcrumbs type_breadcrumbs taint
15581565
in
15591566

@@ -2045,7 +2052,7 @@ module State (FunctionContext : FUNCTION_CONTEXT) = struct
20452052
~pyre_in_context
20462053
~taint
20472054
~state
2048-
~breadcrumbs:(Features.BreadcrumbSet.singleton (Features.format_string ()))
2055+
~breadcrumbs:(Features.BreadcrumbMayAlwaysSet.singleton (Features.format_string ()))
20492056
{
20502057
CallModel.StringFormatCall.nested_expressions = arguments_formatted_string;
20512058
string_literal = { value; location = value_location };
@@ -2079,7 +2086,8 @@ module State (FunctionContext : FUNCTION_CONTEXT) = struct
20792086
~pyre_in_context
20802087
~taint
20812088
~state
2082-
~breadcrumbs:(Features.BreadcrumbSet.singleton (Features.string_concat_left_hand_side ()))
2089+
~breadcrumbs:
2090+
(Features.BreadcrumbMayAlwaysSet.singleton (Features.string_concat_left_hand_side ()))
20832091
{
20842092
CallModel.StringFormatCall.nested_expressions = [expression];
20852093
string_literal = { value; location = value_location };
@@ -2117,7 +2125,7 @@ module State (FunctionContext : FUNCTION_CONTEXT) = struct
21172125
~taint
21182126
~state
21192127
~breadcrumbs:
2120-
(Features.BreadcrumbSet.singleton (Features.string_concat_right_hand_side ()))
2128+
(Features.BreadcrumbMayAlwaysSet.singleton (Features.string_concat_right_hand_side ()))
21212129
{
21222130
CallModel.StringFormatCall.nested_expressions = [expression];
21232131
string_literal = { value; location = value_location };
@@ -2141,8 +2149,8 @@ module State (FunctionContext : FUNCTION_CONTEXT) = struct
21412149
match function_name with
21422150
| "__mod__"
21432151
| "format" ->
2144-
Features.BreadcrumbSet.singleton (Features.format_string ())
2145-
| _ -> Features.BreadcrumbSet.empty
2152+
Features.BreadcrumbMayAlwaysSet.singleton (Features.format_string ())
2153+
| _ -> Features.BreadcrumbMayAlwaysSet.empty
21462154
in
21472155
let substrings =
21482156
arguments
@@ -2474,7 +2482,7 @@ module State (FunctionContext : FUNCTION_CONTEXT) = struct
24742482
~pyre_in_context
24752483
~taint
24762484
~state
2477-
~breadcrumbs:(Features.BreadcrumbSet.singleton (Features.format_string ()))
2485+
~breadcrumbs:(Features.BreadcrumbMayAlwaysSet.singleton (Features.format_string ()))
24782486
{
24792487
CallModel.StringFormatCall.nested_expressions = substrings;
24802488
string_literal = { value = string_literal; location };
@@ -2839,6 +2847,7 @@ let extract_tito_and_sink_models
28392847
annotation
28402848
>>| PyrePysaEnvironment.ReadOnly.parse_annotation pyre_api
28412849
|> Features.type_breadcrumbs_from_annotation ~pyre_api
2850+
|> Features.BreadcrumbMayAlwaysSet.of_set
28422851
in
28432852
BackwardState.Tree.add_local_breadcrumbs type_breadcrumbs tree
28442853
in

source/interprocedural_analyses/taint/callModel.ml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ let at_callsite
4040
~caller
4141
~callee:call_target
4242
~arguments
43+
|> Features.BreadcrumbMayAlwaysSet.of_set
4344
in
4445
Frame.add_propagated_breadcrumbs breadcrumbs frame
4546
in
@@ -299,8 +300,8 @@ let taint_in_taint_out_mapping_for_argument
299300
let obscure_breadcrumbs =
300301
TaintInTaintOutMap.get_tree mapping ~kind:output_kind
301302
>>| BackwardState.Tree.joined_breadcrumbs
302-
|> Option.value ~default:Features.BreadcrumbSet.empty
303-
|> Features.BreadcrumbSet.add (Features.obscure_model ())
303+
|> Option.value ~default:Features.BreadcrumbMayAlwaysSet.empty
304+
|> Features.BreadcrumbMayAlwaysSet.add (Features.obscure_model ())
304305
in
305306
let mapping = TaintInTaintOutMap.remove mapping ~kind:output_kind in
306307
if SanitizeTransformSet.is_all obscure_sanitize then
@@ -430,11 +431,11 @@ let source_tree_of_argument
430431

431432

432433
let type_breadcrumbs_of_calls targets =
433-
List.fold targets ~init:Features.BreadcrumbSet.bottom ~f:(fun so_far call_target ->
434+
List.fold targets ~init:Features.BreadcrumbSet.empty ~f:(fun so_far call_target ->
434435
match call_target.CallGraph.CallTarget.return_type with
435436
| None -> so_far
436437
| Some return_type ->
437-
return_type |> Features.type_breadcrumbs |> Features.BreadcrumbSet.join so_far)
438+
return_type |> Features.type_breadcrumbs |> Features.BreadcrumbSet.union so_far)
438439

439440

440441
module ExtraTraceForTransforms = struct

source/interprocedural_analyses/taint/classModels.ml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@ module PyrePysaLogic = Analysis.PyrePysaLogic
2424

2525
module FeatureSet = struct
2626
type t = {
27-
breadcrumbs: Features.BreadcrumbSet.t;
27+
breadcrumbs: Features.BreadcrumbMayAlwaysSet.t;
2828
via_features: Features.ViaFeatureSet.t;
2929
}
3030

3131
let empty =
32-
{ breadcrumbs = Features.BreadcrumbSet.bottom; via_features = Features.ViaFeatureSet.bottom }
32+
{
33+
breadcrumbs = Features.BreadcrumbMayAlwaysSet.bottom;
34+
via_features = Features.ViaFeatureSet.bottom;
35+
}
3336

3437

3538
let from_taint taint =
@@ -245,7 +248,7 @@ let infer ~scheduler ~scheduler_policies ~pyre_api ~user_models =
245248
~output_root:(Sinks.ParameterUpdate self)
246249
~output_path:[Abstract.TreeDomain.Label.AnyIndex]
247250
~collapse_depth:0
248-
~breadcrumbs:Features.BreadcrumbSet.bottom
251+
~breadcrumbs:Features.BreadcrumbMayAlwaysSet.bottom
249252
~via_features:Features.ViaFeatureSet.bottom
250253
|> add_tito
251254
~input_root:
@@ -255,15 +258,15 @@ let infer ~scheduler ~scheduler_policies ~pyre_api ~user_models =
255258
~output_root:(Sinks.ParameterUpdate self)
256259
~output_path:[AccessPath.dictionary_keys]
257260
~collapse_depth:Features.CollapseDepth.no_collapse
258-
~breadcrumbs:Features.BreadcrumbSet.bottom
261+
~breadcrumbs:Features.BreadcrumbMayAlwaysSet.bottom
259262
~via_features:Features.ViaFeatureSet.bottom
260263
|> add_tito
261264
~input_root:(AccessPath.Root.StarStarParameter { excluded = fields })
262265
~input_path:[]
263266
~output_root:(Sinks.ParameterUpdate self)
264267
~output_path:[Abstract.TreeDomain.Label.AnyIndex]
265268
~collapse_depth:Features.CollapseDepth.no_collapse
266-
~breadcrumbs:Features.BreadcrumbSet.bottom
269+
~breadcrumbs:Features.BreadcrumbMayAlwaysSet.bottom
267270
~via_features:Features.ViaFeatureSet.bottom
268271
in
269272
let sink_taint =

0 commit comments

Comments
 (0)