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