Reviewed By: jvillard Differential Revision: D3723819 fbshipit-source-id: 941e1fcmaster
							parent
							
								
									dda4921786
								
							
						
					
					
						commit
						3b12208e1b
					
				| @ -0,0 +1,128 @@ | ||||
| (* | ||||
|  * Copyright (c) 2016 - 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. | ||||
|  *) | ||||
| 
 | ||||
| open! Utils | ||||
| 
 | ||||
| module F = Format | ||||
| 
 | ||||
| module MockTrace = Trace.Make(struct | ||||
|     module MockTraceElem = struct | ||||
|       type kind = unit | ||||
|       type t = CallSite.t | ||||
|       let call_site t = t | ||||
|       let kind _ = () | ||||
|       let make _ site = site | ||||
|       let compare = CallSite.compare | ||||
|       let equal = CallSite.equal | ||||
|       let pp = CallSite.pp | ||||
| 
 | ||||
|       let to_callee t _ = t | ||||
| 
 | ||||
|       module Set = PrettyPrintable.MakePPSet(struct | ||||
|           type nonrec t = t | ||||
|           let compare = compare | ||||
|           let pp_element = pp | ||||
|         end) | ||||
| 
 | ||||
|     end | ||||
| 
 | ||||
|     module Source = struct | ||||
|       include MockTraceElem | ||||
| 
 | ||||
|       let get site = | ||||
|         if string_is_prefix "SOURCE" (Procname.to_string (CallSite.pname site)) | ||||
|         then [(0, site)] | ||||
|         else [] | ||||
| 
 | ||||
|       let is_footprint _ = assert false | ||||
|       let make_footprint _ = assert false | ||||
|       let get_footprint_access_path _ = assert false | ||||
|       let to_return _ _ = assert false | ||||
|     end | ||||
| 
 | ||||
|     module Sink = struct | ||||
|       include MockTraceElem | ||||
| 
 | ||||
|       let get site = | ||||
|         if string_is_prefix "SINK" (Procname.to_string (CallSite.pname site)) | ||||
|         then [(0, site)] | ||||
|         else [] | ||||
|     end | ||||
| 
 | ||||
|     let should_report _ _ = true | ||||
|   end) | ||||
| 
 | ||||
| module MockTaintAnalysis = TaintAnalysis.Make(MockTrace) | ||||
| 
 | ||||
| module TestInterpreter = AnalyzerTester.Make | ||||
|     (ProcCfg.Normal) | ||||
|     (Scheduler.ReversePostorder) | ||||
|     (MockTaintAnalysis.TransferFunctions) | ||||
| 
 | ||||
| let tests = | ||||
|   let open OUnit2 in | ||||
|   let open AnalyzerTester.StructuredSil in | ||||
|   (* less verbose form of pretty-printing to make writing tests easy *) | ||||
|   let pp_sparse fmt astate = | ||||
|     let pp_call_site fmt call_site = | ||||
|       F.fprintf fmt "%a" Procname.pp (CallSite.pname call_site) in | ||||
|     let pp_sources fmt sources = | ||||
|       if MockTrace.Sources.is_empty sources | ||||
|       then F.fprintf fmt "?" | ||||
|       else | ||||
|         MockTrace.Sources.iter | ||||
|           (fun source -> pp_call_site fmt (MockTrace.Source.call_site source)) | ||||
|           sources in | ||||
|     let pp_sinks fmt sinks = | ||||
|       if MockTrace.Sinks.is_empty sinks | ||||
|       then F.fprintf fmt "?" | ||||
|       else | ||||
|         MockTrace.Sinks.iter | ||||
|           (fun sink -> | ||||
|              pp_call_site fmt (MockTrace.Sink.call_site sink)) | ||||
|           sinks in | ||||
|     (* just print source -> sink, no line nums or passthroughs *) | ||||
|     let pp_trace fmt trace = | ||||
|       F.fprintf | ||||
|         fmt | ||||
|         "(%a -> %a)" | ||||
|         pp_sources (MockTrace.sources trace) | ||||
|         pp_sinks (MockTrace.sinks trace) in | ||||
|     let pp_item fmt (ap, trace) = | ||||
|       F.fprintf fmt "%a => %a" AccessPath.pp ap pp_trace trace in | ||||
|     (* flatten access tree into list of access paths with associated traces *) | ||||
|     let trace_assocs = | ||||
|       MockTaintAnalysis.TaintDomain.fold | ||||
|         (fun acc ap t -> | ||||
|            if not (MockTrace.is_empty t) | ||||
|            then (ap, t) :: acc | ||||
|            else acc) | ||||
|         astate.MockTaintAnalysis.Domain.access_tree | ||||
|         [] in | ||||
|     PrettyPrintable.pp_collection ~pp_item fmt (IList.rev trace_assocs) in | ||||
|   let assign_to_source ret_str = | ||||
|     let procname = Procname.from_string_c_fun "SOURCE" in | ||||
|     make_call ~procname [ident_of_str ret_str] [] in | ||||
|   let assign_to_non_source ret_str = | ||||
|     let procname = Procname.from_string_c_fun "NON-SOURCE" in | ||||
|     make_call ~procname [ident_of_str ret_str] [] in | ||||
|   let assert_empty = invariant "{  }" in | ||||
|   let test_list = [ | ||||
|     "source recorded", | ||||
|     [ | ||||
|       assign_to_source "ret_id"; | ||||
|       invariant "{ ret_id$0 => (SOURCE -> ?) }"; | ||||
|     ]; | ||||
|     "non-source not recorded", | ||||
|     [ | ||||
|       assign_to_non_source "ret_id"; | ||||
|       assert_empty; | ||||
|     ]; | ||||
|   ] |> TestInterpreter.create_tests ~pp_opt:pp_sparse [] in | ||||
|   "taint_test_suite">:::test_list | ||||
					Loading…
					
					
				
		Reference in new issue