Skip to content

Commit

Permalink
[cxx-string-captured] Report if a string pointer which is the interna…
Browse files Browse the repository at this point in the history
…l pointer of a cxx string is captured

Summary:
Before we were reporting when a local variable of type `std::string` was captured, but this was wrong in many cases as the variable was copied before being captured. What we actually wanted to catch is examples like this

```
example
{
std::string cstring("abc");
const char* ptr = cstring.c_str();
   /// access the ptr in a block that goes out of scope.
   // fine to capture it in a non escaping block

/// we expect the cstring to be destroyed here and ptr to point to dangling address.(use after free)
}
```

So now we adapted the checker to catch this case instead. We add a new context_info for captured variables for when a variable is the internal pointer of a local variable of a certain type. Then we do a preanalysis to compute this, and in the actual checker we check if the variable is an internal pointer and report accordingly.

Reviewed By: skcho

Differential Revision: D64836637

fbshipit-source-id: 967eefb645c1d7f3d412a616e64b327e77384fb0
  • Loading branch information
dulmarod authored and facebook-github-bot committed Oct 25, 2024
1 parent 365995c commit 52b4325
Show file tree
Hide file tree
Showing 6 changed files with 317 additions and 157 deletions.
9 changes: 6 additions & 3 deletions infer/src/IR/CapturedVar.ml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ let is_captured_by_ref captured_mode =
type captured_info = {loc: Location.t; is_formal: Procname.t option}
[@@deriving compare, equal, sexp, hash, normalize]

type context_info = {is_checked_for_null: bool} [@@deriving compare, equal, sexp, hash, normalize]
type context_info = {is_checked_for_null: bool; is_internal_pointer_of: Typ.t option}
[@@deriving compare, equal, sexp, hash, normalize]

type t =
{ pvar: Pvar.t
Expand All @@ -34,8 +35,10 @@ let pp_captured_info fmt {loc; is_formal} =
F.fprintf fmt "(%a, %a)" (Pp.option Procname.pp) is_formal Location.pp loc


let pp_context_info fmt {is_checked_for_null} =
F.fprintf fmt "is_checked_for_null=%b" is_checked_for_null
let pp_context_info fmt {is_checked_for_null; is_internal_pointer_of} =
F.fprintf fmt "is_checked_for_null=%b, is_internal_pointer=%a" is_checked_for_null
(Pp.option (Typ.pp Pp.text))
is_internal_pointer_of


let pp fmt {pvar; typ; capture_mode; captured_from; context_info} =
Expand Down
3 changes: 2 additions & 1 deletion infer/src/IR/CapturedVar.mli
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ val is_captured_by_ref : capture_mode -> bool
type captured_info = {loc: Location.t; is_formal: Procname.t option}
[@@deriving compare, equal, sexp, hash, normalize]

type context_info = {is_checked_for_null: bool} [@@deriving compare, equal, sexp, hash, normalize]
type context_info = {is_checked_for_null: bool; is_internal_pointer_of: Typ.t option}
[@@deriving compare, equal, sexp, hash, normalize]

(** captured_from and context_info only set for captured variables in Objective-C blocks *)
type t =
Expand Down
Loading

0 comments on commit 52b4325

Please sign in to comment.