Skip to content

Commit

Permalink
[transitive-access] add a final_class_only field to JSON config file
Browse files Browse the repository at this point in the history
Summary:
We can now specify that some transitive-access entry point are only for final classes

facebook This is needed for Falco scenario. The fiels is optionnal so we don't fear a sync problem with the .json config we have in prod.

Reviewed By: geralt-encore

Differential Revision:
D52566069

Privacy Context Container: L1208441

fbshipit-source-id: b30fe8034ed8ecdf21047ab4f5af252a51d49101
  • Loading branch information
davidpichardie authored and facebook-github-bot committed Jan 9, 2024
1 parent 83e6a95 commit 2727539
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 6 deletions.
11 changes: 9 additions & 2 deletions infer/src/pulse/PulseTransitiveAccessChecker.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module Config : sig
type context =
{ initial_caller_class_extends: string list
; initial_caller_class_does_not_extend: string list
; final_class_only: bool
; description: string
; tag: string }

Expand Down Expand Up @@ -47,6 +48,7 @@ end = struct
type context =
{ initial_caller_class_extends: string list
; initial_caller_class_does_not_extend: string list
; final_class_only: bool [@yojson.default false]
; description: string
; tag: string }
[@@deriving of_yojson]
Expand Down Expand Up @@ -103,14 +105,19 @@ end = struct


let is_matching_context tenv procname
{initial_caller_class_extends; initial_caller_class_does_not_extend} =
{initial_caller_class_extends; initial_caller_class_does_not_extend; final_class_only} =
match Procname.get_class_type_name procname with
| Some type_name ->
let is_final =
Tenv.lookup tenv type_name
|> Option.exists ~f:(fun {Struct.annots} -> Annot.Item.is_final annots)
in
let parents =
Tenv.fold_supers tenv type_name ~init:String.Set.empty ~f:(fun parent _ acc ->
String.Set.add acc (Typ.Name.to_string parent) )
in
List.exists initial_caller_class_extends ~f:(String.Set.mem parents)
((not final_class_only) || is_final)
&& List.exists initial_caller_class_extends ~f:(String.Set.mem parents)
&& List.for_all initial_caller_class_does_not_extend ~f:(fun type_str ->
not (String.Set.mem parents type_str) )
| None ->
Expand Down
8 changes: 4 additions & 4 deletions infer/tests/codetoanalyze/hack/pulse/global_access.hack
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Parent1 extends Parent2 {}

class ExtendsVeryUnsafe extends VeryUnsafe {}

class GlobalAccess extends Parent1 {
final class GlobalAccess extends Parent1 {

public function basic_is_entry_bad(A $a): int {
return $a->GlobalVARIABLES;
Expand Down Expand Up @@ -59,7 +59,7 @@ class GlobalAccess extends Parent1 {
}

class EventNotHandler {}
class DoesNotInheritEvenHandler extends EventNotHandler {
final class DoesNotInheritEvenHandler extends EventNotHandler {
public function indirect_other_is_not_entry_ok(A $a): int {
return $a->get();
}
Expand All @@ -68,7 +68,7 @@ class DoesNotInheritEvenHandler extends EventNotHandler {
interface Unsafe {}
interface I extends Unsafe {}

class ImplementUnsafe extends Parent1 implements Unsafe {
final class ImplementUnsafe extends Parent1 implements Unsafe {
public function indirect_other_is_not_entry_ok(A $a): int {
return $a->get();
}
Expand Down Expand Up @@ -109,7 +109,7 @@ class Helper {
}
}

class TooMuchDisjuncts extends EventHandler {
final class TooMuchDisjuncts extends EventHandler {

public function bad(
Helper $o,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
{
"initial_caller_class_extends": ["hack GlobalAccess::EventHandler"],
"initial_caller_class_does_not_extend": ["hack GlobalAccess::Unsafe"],
"final_class_only": true,
"tag": "Unsafe Globals",
"description": "The value is accessed in an unsafe context"
},
Expand Down

0 comments on commit 2727539

Please sign in to comment.