You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.2 KiB
69 lines
2.2 KiB
(*
|
|
* Copyright (c) 2014 - present Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*)
|
|
|
|
module L = Logging
|
|
|
|
|
|
(** Find SQL statements in string concatenations *)
|
|
let callback_sql { Callbacks.proc_desc; proc_name; tenv } =
|
|
let verbose = false in
|
|
|
|
(* Case insensitive SQL statement patterns *)
|
|
let sql_start =
|
|
let _sql_start = [
|
|
"select.*from.*";
|
|
"insert into.*";
|
|
"update .* set.*";
|
|
"delete .* from.*";
|
|
] in
|
|
IList.map Str.regexp_case_fold _sql_start in
|
|
|
|
(* Check for SQL string concatenations *)
|
|
let do_instr const_map node instr =
|
|
let do_call pn_java i1 i2 l =
|
|
if Procname.java_get_class_name pn_java = "java.lang.StringBuilder"
|
|
&& Procname.java_get_method pn_java = "append"
|
|
then
|
|
begin
|
|
let rvar1 = Sil.Var i1 in
|
|
let rvar2 = Sil.Var i2 in
|
|
begin
|
|
let matches s r = Str.string_match r s 0 in
|
|
match const_map node rvar1, const_map node rvar2 with
|
|
| Some (Sil.Cstr ""), Some (Sil.Cstr s2) ->
|
|
if IList.exists (matches s2) sql_start then
|
|
begin
|
|
L.stdout
|
|
"%s%s@."
|
|
"Possible SQL query using string concatenation. "
|
|
"Please consider using a prepared statement instead.";
|
|
let linereader = Printer.LineReader.create () in
|
|
L.stdout "%a@." (Checkers.PP.pp_loc_range linereader 2 2) l
|
|
end
|
|
| _ -> ()
|
|
end
|
|
end in
|
|
|
|
match instr with
|
|
| Sil.Call (_, Sil.Const (Sil.Cfun pn), (Sil.Var i1, _):: (Sil.Var i2, _):: [], l, _) ->
|
|
begin
|
|
match pn with
|
|
| Procname.Java pn_java ->
|
|
do_call pn_java i1 i2 l
|
|
| _ ->
|
|
()
|
|
end
|
|
| _ -> () in
|
|
|
|
try
|
|
let const_map = ConstantPropagation.build_const_map tenv proc_desc in
|
|
if verbose then L.stdout "Analyzing %a...\n@." Procname.pp proc_name;
|
|
Cfg.Procdesc.iter_instrs (do_instr const_map) proc_desc
|
|
with _ -> ()
|