Summary: Topl matches procedure names against whatever Procname.hashable_name returns. For Java, it returns something like "java.util.ArrayList.add(...)", but for Erlang it used to return something like "add/1": no module and no parenthesis after. Now, Erlang returns "lists:add/1"; that is, it includes module name. Also, Topl doesn't insist anymore on having a paranthesis after the name. Differential Revision: D29520365 fbshipit-source-id: d23be1cc8master
parent
0f4394503b
commit
2ecfa422ac
@ -0,0 +1,16 @@
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
TESTS_DIR = ../../..
|
||||
|
||||
# see explanations in cpp/biabduction/Makefile for the custom isystem
|
||||
INFER_OPTIONS = --topl --topl-properties taint.topl --project-root $(TESTS_DIR)
|
||||
INFERPRINT_OPTIONS = --issues-tests
|
||||
|
||||
SOURCES = $(wildcard src/*.erl)
|
||||
|
||||
include $(TESTS_DIR)/erlang.make
|
||||
|
||||
infer-out/report.json: $(MAKEFILE_LIST)
|
@ -0,0 +1,6 @@
|
||||
codetoanalyze/erlang/topl/src/topl_taint.erl, fp_test_f_Bad/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
|
||||
codetoanalyze/erlang/topl/src/topl_taint.erl, fp_test_g_Ok/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
|
||||
codetoanalyze/erlang/topl/src/topl_taint.erl, test_a_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to source/0,call to sink/1]
|
||||
codetoanalyze/erlang/topl/src/topl_taint.erl, test_d_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to source/0,call to call_sink_indirectly/1,call to call_sink/1,call to sink/1]
|
||||
codetoanalyze/erlang/topl/src/topl_taint.erl, test_h_Bad/0, 0, TOPL_ERROR, no_bucket, ERROR, [call to dirty_if_argument_nil/1,call to source/0,call to sink/1]
|
||||
codetoanalyze/erlang/topl/src/topl_taint.erl, test_j_Bad/0, 1, NONEXHAUSTIVE_PATTERN_MATCH, no_bucket, ERROR, [no pattern match here]
|
@ -0,0 +1,11 @@
|
||||
% Copyright (c) Facebook, Inc. and its affiliates.
|
||||
%
|
||||
% This source code is licensed under the MIT license found in the
|
||||
% LICENSE file in the root directory of this source tree.
|
||||
|
||||
{erl_opts, []}.
|
||||
{deps, []}.
|
||||
|
||||
{shell, [
|
||||
{apps, [topl_taint]}
|
||||
]}.
|
@ -0,0 +1,14 @@
|
||||
% Copyright (c) Facebook, Inc. and its affiliates.
|
||||
%
|
||||
% This source code is licensed under the MIT license found in the
|
||||
% LICENSE file in the root directory of this source tree.
|
||||
{application, topl_taint, [
|
||||
{description, "An Erlang app that leaks"},
|
||||
{vsn, "0.1.0"},
|
||||
{registered, []},
|
||||
{applications, [
|
||||
kernel,
|
||||
stdlib
|
||||
]},
|
||||
{modules, []}
|
||||
]}.
|
@ -0,0 +1,84 @@
|
||||
% Copyright (c) Facebook, Inc. and its affiliates.
|
||||
%
|
||||
% This source code is licensed under the MIT license found in the
|
||||
% LICENSE file in the root directory of this source tree.
|
||||
|
||||
-module(topl_taint).
|
||||
|
||||
-export([
|
||||
test_a_Bad/0,
|
||||
test_b_Ok/0,
|
||||
fn_test_c_Bad/0,
|
||||
test_d_Bad/0,
|
||||
test_e_Ok/0,
|
||||
fp_test_f_Bad/0,
|
||||
fp_test_g_Ok/0,
|
||||
test_h_Bad/0,
|
||||
test_i_Ok/0,
|
||||
test_j_Bad/0
|
||||
]).
|
||||
|
||||
test_a_Bad() ->
|
||||
sink(source()).
|
||||
|
||||
test_b_Ok() ->
|
||||
sink(1).
|
||||
|
||||
% FN because match not yet translated
|
||||
fn_test_c_Bad() ->
|
||||
X = source(),
|
||||
sink(X).
|
||||
|
||||
test_d_Bad() ->
|
||||
call_sink_indirectly(tito(source())).
|
||||
|
||||
test_e_Ok() ->
|
||||
call_sink_indirectly(tito(ok)).
|
||||
|
||||
% FP: T94670024 (bad, but wrong warning reported)
|
||||
fp_test_f_Bad() ->
|
||||
case one() + one() - two() =:= 0 of
|
||||
true -> sink(dirty_if_argument_nil([]));
|
||||
false -> sink(dirty_if_argument_nil([1]))
|
||||
end.
|
||||
|
||||
% FP: T94670024
|
||||
fp_test_g_Ok() ->
|
||||
case one() + one() - two() =/= 0 of
|
||||
true -> sink(dirty_if_argument_nil([]));
|
||||
false -> sink(dirty_if_argument_nil([1]))
|
||||
end.
|
||||
|
||||
test_h_Bad() ->
|
||||
case one() + one() of
|
||||
1 -> sink(dirty_if_argument_nil([ok]));
|
||||
2 -> sink(dirty_if_argument_nil([]))
|
||||
end.
|
||||
|
||||
test_i_Ok() ->
|
||||
case two() of
|
||||
1 -> sink(dirty_if_argument_nil(bad));
|
||||
2 -> sink(dirty_if_argument_nil([ok, ok, ok]))
|
||||
end.
|
||||
|
||||
% Bad because no case for 3 (not a topl property)
|
||||
test_j_Bad() ->
|
||||
case two() + two() - one() of
|
||||
1 -> sink(dirty_if_argument_nil(bad));
|
||||
2 -> sink(dirty_if_argument_nil([ok, ok, ok]))
|
||||
end.
|
||||
|
||||
%%
|
||||
|
||||
% tito = Taint-In Taint-Out
|
||||
tito(X) -> X.
|
||||
call_sink_indirectly(X) -> call_sink(X).
|
||||
call_sink(X) -> sink(X).
|
||||
dirty_if_argument_nil([]) -> source();
|
||||
dirty_if_argument_nil([X | _]) -> X.
|
||||
one() -> 1.
|
||||
two() -> 2.
|
||||
|
||||
%%
|
||||
source() -> dirty.
|
||||
sink(_) -> ok.
|
@ -0,0 +1,5 @@
|
||||
property Taint
|
||||
prefix "topl_taint"
|
||||
start -> start: *
|
||||
start -> tracking: "source/0"(Ret) => x := Ret
|
||||
tracking -> error: "sink/1"(Arg, VoidRet) when x == Arg
|
Loading…
Reference in new issue