aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp315
1 files changed, 159 insertions, 156 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
index f0a114801dda..f6e2f59d5697 100644
--- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -30,6 +30,7 @@
#include <limits>
#include <memory>
+#include <optional>
#include <utility>
#define DEBUG_TYPE "taint-checker"
@@ -124,16 +125,17 @@ SVal getPointeeOf(const CheckerContext &C, Loc LValue) {
}
/// Given a pointer/reference argument, return the value it refers to.
-Optional<SVal> getPointeeOf(const CheckerContext &C, SVal Arg) {
+std::optional<SVal> getPointeeOf(const CheckerContext &C, SVal Arg) {
if (auto LValue = Arg.getAs<Loc>())
return getPointeeOf(C, *LValue);
- return None;
+ return std::nullopt;
}
/// Given a pointer, return the SVal of its pointee or if it is tainted,
/// otherwise return the pointer's SVal if tainted.
/// Also considers stdin as a taint source.
-Optional<SVal> getTaintedPointeeOrPointer(const CheckerContext &C, SVal Arg) {
+std::optional<SVal> getTaintedPointeeOrPointer(const CheckerContext &C,
+ SVal Arg) {
const ProgramStateRef State = C.getState();
if (auto Pointee = getPointeeOf(C, Arg))
@@ -147,7 +149,7 @@ Optional<SVal> getTaintedPointeeOrPointer(const CheckerContext &C, SVal Arg) {
if (isStdin(Arg, C.getASTContext()))
return Arg;
- return None;
+ return std::nullopt;
}
bool isTaintedOrPointsToTainted(const Expr *E, const ProgramStateRef &State,
@@ -161,7 +163,8 @@ bool isTaintedOrPointsToTainted(const Expr *E, const ProgramStateRef &State,
class ArgSet {
public:
ArgSet() = default;
- ArgSet(ArgVecTy &&DiscreteArgs, Optional<ArgIdxTy> VariadicIndex = None)
+ ArgSet(ArgVecTy &&DiscreteArgs,
+ std::optional<ArgIdxTy> VariadicIndex = std::nullopt)
: DiscreteArgs(std::move(DiscreteArgs)),
VariadicIndex(std::move(VariadicIndex)) {}
@@ -176,7 +179,7 @@ public:
private:
ArgVecTy DiscreteArgs;
- Optional<ArgIdxTy> VariadicIndex;
+ std::optional<ArgIdxTy> VariadicIndex;
};
/// A struct used to specify taint propagation rules for a function.
@@ -197,12 +200,12 @@ class GenericTaintRule {
ArgSet PropDstArgs;
/// A message that explains why the call is sensitive to taint.
- Optional<StringRef> SinkMsg;
+ std::optional<StringRef> SinkMsg;
GenericTaintRule() = default;
GenericTaintRule(ArgSet &&Sink, ArgSet &&Filter, ArgSet &&Src, ArgSet &&Dst,
- Optional<StringRef> SinkMsg = None)
+ std::optional<StringRef> SinkMsg = std::nullopt)
: SinkArgs(std::move(Sink)), FilterArgs(std::move(Filter)),
PropSrcArgs(std::move(Src)), PropDstArgs(std::move(Dst)),
SinkMsg(SinkMsg) {}
@@ -211,7 +214,7 @@ public:
/// Make a rule that reports a warning if taint reaches any of \p FilterArgs
/// arguments.
static GenericTaintRule Sink(ArgSet &&SinkArgs,
- Optional<StringRef> Msg = None) {
+ std::optional<StringRef> Msg = std::nullopt) {
return {std::move(SinkArgs), {}, {}, {}, Msg};
}
@@ -232,9 +235,9 @@ public:
}
/// Make a rule that taints all PropDstArgs if any of PropSrcArgs is tainted.
- static GenericTaintRule SinkProp(ArgSet &&SinkArgs, ArgSet &&SrcArgs,
- ArgSet &&DstArgs,
- Optional<StringRef> Msg = None) {
+ static GenericTaintRule
+ SinkProp(ArgSet &&SinkArgs, ArgSet &&SrcArgs, ArgSet &&DstArgs,
+ std::optional<StringRef> Msg = std::nullopt) {
return {
std::move(SinkArgs), {}, std::move(SrcArgs), std::move(DstArgs), Msg};
}
@@ -302,7 +305,7 @@ struct GenericTaintRuleParser {
TaintConfiguration &&Config) const;
private:
- using NamePartsTy = llvm::SmallVector<SmallString<32>, 2>;
+ using NamePartsTy = llvm::SmallVector<StringRef, 2>;
/// Validate part of the configuration, which contains a list of argument
/// indexes.
@@ -359,8 +362,8 @@ private:
// TODO: Remove separation to simplify matching logic once CallDescriptions
// are more expressive.
- mutable Optional<RuleLookupTy> StaticTaintRules;
- mutable Optional<RuleLookupTy> DynamicTaintRules;
+ mutable std::optional<RuleLookupTy> StaticTaintRules;
+ mutable std::optional<RuleLookupTy> DynamicTaintRules;
};
} // end of anonymous namespace
@@ -442,10 +445,8 @@ GenericTaintRuleParser::parseNameParts(const Config &C) {
if (!C.Scope.empty()) {
// If the Scope argument contains multiple "::" parts, those are considered
// namespace identifiers.
- llvm::SmallVector<StringRef, 2> NSParts;
- StringRef{C.Scope}.split(NSParts, "::", /*MaxSplit*/ -1,
+ StringRef{C.Scope}.split(NameParts, "::", /*MaxSplit*/ -1,
/*KeepEmpty*/ false);
- NameParts.append(NSParts.begin(), NSParts.end());
}
NameParts.emplace_back(C.Name);
return NameParts;
@@ -456,10 +457,7 @@ void GenericTaintRuleParser::consumeRulesFromConfig(const Config &C,
GenericTaintRule &&Rule,
RulesContTy &Rules) {
NamePartsTy NameParts = parseNameParts(C);
- llvm::SmallVector<const char *, 2> CallDescParts{NameParts.size()};
- llvm::transform(NameParts, CallDescParts.begin(),
- [](SmallString<32> &S) { return S.c_str(); });
- Rules.emplace_back(CallDescription(CallDescParts), std::move(Rule));
+ Rules.emplace_back(CallDescription(NameParts), std::move(Rule));
}
void GenericTaintRuleParser::parseConfig(const std::string &Option,
@@ -485,10 +483,12 @@ void GenericTaintRuleParser::parseConfig(const std::string &Option,
validateArgVector(Option, P.DstArgs);
bool IsSrcVariadic = P.VarType == TaintConfiguration::VariadicType::Src;
bool IsDstVariadic = P.VarType == TaintConfiguration::VariadicType::Dst;
- Optional<ArgIdxTy> JustVarIndex = P.VarIndex;
+ std::optional<ArgIdxTy> JustVarIndex = P.VarIndex;
- ArgSet SrcDesc(std::move(P.SrcArgs), IsSrcVariadic ? JustVarIndex : None);
- ArgSet DstDesc(std::move(P.DstArgs), IsDstVariadic ? JustVarIndex : None);
+ ArgSet SrcDesc(std::move(P.SrcArgs),
+ IsSrcVariadic ? JustVarIndex : std::nullopt);
+ ArgSet DstDesc(std::move(P.DstArgs),
+ IsDstVariadic ? JustVarIndex : std::nullopt);
consumeRulesFromConfig(
P, GenericTaintRule::Prop(std::move(SrcDesc), std::move(DstDesc)), Rules);
@@ -527,128 +527,128 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {
RulesConstructionTy GlobalCRules{
// Sources
- {{"fdopen"}, TR::Source({{ReturnValueIndex}})},
- {{"fopen"}, TR::Source({{ReturnValueIndex}})},
- {{"freopen"}, TR::Source({{ReturnValueIndex}})},
- {{"getch"}, TR::Source({{ReturnValueIndex}})},
- {{"getchar"}, TR::Source({{ReturnValueIndex}})},
- {{"getchar_unlocked"}, TR::Source({{ReturnValueIndex}})},
- {{"gets"}, TR::Source({{0}, ReturnValueIndex})},
- {{"gets_s"}, TR::Source({{0}, ReturnValueIndex})},
- {{"scanf"}, TR::Source({{}, 1})},
- {{"scanf_s"}, TR::Source({{}, {1}})},
- {{"wgetch"}, TR::Source({{}, ReturnValueIndex})},
+ {{{"fdopen"}}, TR::Source({{ReturnValueIndex}})},
+ {{{"fopen"}}, TR::Source({{ReturnValueIndex}})},
+ {{{"freopen"}}, TR::Source({{ReturnValueIndex}})},
+ {{{"getch"}}, TR::Source({{ReturnValueIndex}})},
+ {{{"getchar"}}, TR::Source({{ReturnValueIndex}})},
+ {{{"getchar_unlocked"}}, TR::Source({{ReturnValueIndex}})},
+ {{{"gets"}}, TR::Source({{0}, ReturnValueIndex})},
+ {{{"gets_s"}}, TR::Source({{0}, ReturnValueIndex})},
+ {{{"scanf"}}, TR::Source({{}, 1})},
+ {{{"scanf_s"}}, TR::Source({{}, {1}})},
+ {{{"wgetch"}}, TR::Source({{}, ReturnValueIndex})},
// Sometimes the line between taint sources and propagators is blurry.
// _IO_getc is choosen to be a source, but could also be a propagator.
// This way it is simpler, as modeling it as a propagator would require
// to model the possible sources of _IO_FILE * values, which the _IO_getc
// function takes as parameters.
- {{"_IO_getc"}, TR::Source({{ReturnValueIndex}})},
- {{"getcwd"}, TR::Source({{0, ReturnValueIndex}})},
- {{"getwd"}, TR::Source({{0, ReturnValueIndex}})},
- {{"readlink"}, TR::Source({{1, ReturnValueIndex}})},
- {{"readlinkat"}, TR::Source({{2, ReturnValueIndex}})},
- {{"get_current_dir_name"}, TR::Source({{ReturnValueIndex}})},
- {{"gethostname"}, TR::Source({{0}})},
- {{"getnameinfo"}, TR::Source({{2, 4}})},
- {{"getseuserbyname"}, TR::Source({{1, 2}})},
- {{"getgroups"}, TR::Source({{1, ReturnValueIndex}})},
- {{"getlogin"}, TR::Source({{ReturnValueIndex}})},
- {{"getlogin_r"}, TR::Source({{0}})},
+ {{{"_IO_getc"}}, TR::Source({{ReturnValueIndex}})},
+ {{{"getcwd"}}, TR::Source({{0, ReturnValueIndex}})},
+ {{{"getwd"}}, TR::Source({{0, ReturnValueIndex}})},
+ {{{"readlink"}}, TR::Source({{1, ReturnValueIndex}})},
+ {{{"readlinkat"}}, TR::Source({{2, ReturnValueIndex}})},
+ {{{"get_current_dir_name"}}, TR::Source({{ReturnValueIndex}})},
+ {{{"gethostname"}}, TR::Source({{0}})},
+ {{{"getnameinfo"}}, TR::Source({{2, 4}})},
+ {{{"getseuserbyname"}}, TR::Source({{1, 2}})},
+ {{{"getgroups"}}, TR::Source({{1, ReturnValueIndex}})},
+ {{{"getlogin"}}, TR::Source({{ReturnValueIndex}})},
+ {{{"getlogin_r"}}, TR::Source({{0}})},
// Props
- {{"atoi"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"atol"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"atoll"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"fgetc"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"fgetln"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"fgets"}, TR::Prop({{2}}, {{0, ReturnValueIndex}})},
- {{"fscanf"}, TR::Prop({{0}}, {{}, 2})},
- {{"fscanf_s"}, TR::Prop({{0}}, {{}, {2}})},
- {{"sscanf"}, TR::Prop({{0}}, {{}, 2})},
-
- {{"getc"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"getc_unlocked"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"getdelim"}, TR::Prop({{3}}, {{0}})},
- {{"getline"}, TR::Prop({{2}}, {{0}})},
- {{"getw"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"pread"}, TR::Prop({{0, 1, 2, 3}}, {{1, ReturnValueIndex}})},
- {{"read"}, TR::Prop({{0, 2}}, {{1, ReturnValueIndex}})},
- {{"strchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"strrchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"tolower"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"toupper"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"fread"}, TR::Prop({{3}}, {{0, ReturnValueIndex}})},
- {{"recv"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
- {{"recvfrom"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
-
- {{"ttyname"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"ttyname_r"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
-
- {{"basename"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"dirname"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"fnmatch"}, TR::Prop({{1}}, {{ReturnValueIndex}})},
- {{"memchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"memrchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"rawmemchr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
-
- {{"mbtowc"}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
- {{"wctomb"}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
- {{"wcwidth"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
-
- {{"memcmp"}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},
- {{"memcpy"}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
- {{"memmove"}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
+ {{{"atoi"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"atol"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"atoll"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"fgetc"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"fgetln"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"fgets"}}, TR::Prop({{2}}, {{0, ReturnValueIndex}})},
+ {{{"fscanf"}}, TR::Prop({{0}}, {{}, 2})},
+ {{{"fscanf_s"}}, TR::Prop({{0}}, {{}, {2}})},
+ {{{"sscanf"}}, TR::Prop({{0}}, {{}, 2})},
+
+ {{{"getc"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"getc_unlocked"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"getdelim"}}, TR::Prop({{3}}, {{0}})},
+ {{{"getline"}}, TR::Prop({{2}}, {{0}})},
+ {{{"getw"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"pread"}}, TR::Prop({{0, 1, 2, 3}}, {{1, ReturnValueIndex}})},
+ {{{"read"}}, TR::Prop({{0, 2}}, {{1, ReturnValueIndex}})},
+ {{{"strchr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"strrchr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"tolower"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"toupper"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"fread"}}, TR::Prop({{3}}, {{0, ReturnValueIndex}})},
+ {{{"recv"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
+ {{{"recvfrom"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
+
+ {{{"ttyname"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"ttyname_r"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
+
+ {{{"basename"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"dirname"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"fnmatch"}}, TR::Prop({{1}}, {{ReturnValueIndex}})},
+ {{{"memchr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"memrchr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"rawmemchr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+
+ {{{"mbtowc"}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
+ {{{"wctomb"}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
+ {{{"wcwidth"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+
+ {{{"memcmp"}}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},
+ {{{"memcpy"}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
+ {{{"memmove"}}, TR::Prop({{1}}, {{0, ReturnValueIndex}})},
// If memmem was called with a tainted needle and the search was
// successful, that would mean that the value pointed by the return value
// has the same content as the needle. If we choose to go by the policy of
// content equivalence implies taintedness equivalence, that would mean
// haystack should be considered a propagation source argument.
- {{"memmem"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"memmem"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
// The comment for memmem above also applies to strstr.
- {{"strstr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"strcasestr"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"strstr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"strcasestr"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"strchrnul"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"strchrnul"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"index"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"rindex"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"index"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"rindex"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
// FIXME: In case of arrays, only the first element of the array gets
// tainted.
- {{"qsort"}, TR::Prop({{0}}, {{0}})},
- {{"qsort_r"}, TR::Prop({{0}}, {{0}})},
-
- {{"strcmp"}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},
- {{"strcasecmp"}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},
- {{"strncmp"}, TR::Prop({{0, 1, 2}}, {{ReturnValueIndex}})},
- {{"strncasecmp"}, TR::Prop({{0, 1, 2}}, {{ReturnValueIndex}})},
- {{"strspn"}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},
- {{"strcspn"}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},
- {{"strpbrk"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"strndup"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"strndupa"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"strlen"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"strnlen"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"strtol"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
- {{"strtoll"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
- {{"strtoul"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
- {{"strtoull"}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
-
- {{"isalnum"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"isalpha"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"isascii"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"isblank"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"iscntrl"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"isdigit"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"isgraph"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"islower"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"isprint"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"ispunct"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"isspace"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"isupper"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{"isxdigit"}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"qsort"}}, TR::Prop({{0}}, {{0}})},
+ {{{"qsort_r"}}, TR::Prop({{0}}, {{0}})},
+
+ {{{"strcmp"}}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},
+ {{{"strcasecmp"}}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},
+ {{{"strncmp"}}, TR::Prop({{0, 1, 2}}, {{ReturnValueIndex}})},
+ {{{"strncasecmp"}}, TR::Prop({{0, 1, 2}}, {{ReturnValueIndex}})},
+ {{{"strspn"}}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},
+ {{{"strcspn"}}, TR::Prop({{0, 1}}, {{ReturnValueIndex}})},
+ {{{"strpbrk"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"strndup"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"strndupa"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"strlen"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"strnlen"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"strtol"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
+ {{{"strtoll"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
+ {{{"strtoul"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
+ {{{"strtoull"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
+
+ {{{"isalnum"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"isalpha"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"isascii"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"isblank"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"iscntrl"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"isdigit"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"isgraph"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"islower"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"isprint"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"ispunct"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"isspace"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"isupper"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{{"isxdigit"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
{{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrncat)}},
TR::Prop({{1, 2}}, {{0, ReturnValueIndex}})},
@@ -656,37 +656,40 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {
TR::Prop({{1, 2}}, {{0}})},
{{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrlcat)}},
TR::Prop({{1, 2}}, {{0}})},
- {{CDF_MaybeBuiltin, {"snprintf"}},
+ {{CDF_MaybeBuiltin, {{"snprintf"}}},
TR::Prop({{1}, 3}, {{0, ReturnValueIndex}})},
- {{CDF_MaybeBuiltin, {"sprintf"}},
+ {{CDF_MaybeBuiltin, {{"sprintf"}}},
TR::Prop({{1}, 2}, {{0, ReturnValueIndex}})},
- {{CDF_MaybeBuiltin, {"strcpy"}},
+ {{CDF_MaybeBuiltin, {{"strcpy"}}},
TR::Prop({{1}}, {{0, ReturnValueIndex}})},
- {{CDF_MaybeBuiltin, {"stpcpy"}},
+ {{CDF_MaybeBuiltin, {{"stpcpy"}}},
TR::Prop({{1}}, {{0, ReturnValueIndex}})},
- {{CDF_MaybeBuiltin, {"strcat"}},
+ {{CDF_MaybeBuiltin, {{"strcat"}}},
TR::Prop({{1}}, {{0, ReturnValueIndex}})},
- {{CDF_MaybeBuiltin, {"strdup"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{CDF_MaybeBuiltin, {"strdupa"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
- {{CDF_MaybeBuiltin, {"wcsdup"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{CDF_MaybeBuiltin, {{"strdup"}}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{CDF_MaybeBuiltin, {{"strdupa"}}},
+ TR::Prop({{0}}, {{ReturnValueIndex}})},
+ {{CDF_MaybeBuiltin, {{"wcsdup"}}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
// Sinks
- {{"system"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
- {{"popen"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
- {{"execl"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
- {{"execle"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
- {{"execlp"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
- {{"execvp"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
- {{"execvP"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
- {{"execve"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
- {{"dlopen"}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
- {{CDF_MaybeBuiltin, {"malloc"}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
- {{CDF_MaybeBuiltin, {"calloc"}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
- {{CDF_MaybeBuiltin, {"alloca"}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
- {{CDF_MaybeBuiltin, {"memccpy"}}, TR::Sink({{3}}, MsgTaintedBufferSize)},
- {{CDF_MaybeBuiltin, {"realloc"}}, TR::Sink({{1}}, MsgTaintedBufferSize)},
- {{{"setproctitle"}}, TR::Sink({{0}, 1}, MsgUncontrolledFormatString)},
- {{{"setproctitle_fast"}},
+ {{{"system"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
+ {{{"popen"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
+ {{{"execl"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
+ {{{"execle"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
+ {{{"execlp"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
+ {{{"execvp"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
+ {{{"execvP"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
+ {{{"execve"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
+ {{{"dlopen"}}, TR::Sink({{0}}, MsgSanitizeSystemArgs)},
+ {{CDF_MaybeBuiltin, {{"malloc"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
+ {{CDF_MaybeBuiltin, {{"calloc"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
+ {{CDF_MaybeBuiltin, {{"alloca"}}}, TR::Sink({{0}}, MsgTaintedBufferSize)},
+ {{CDF_MaybeBuiltin, {{"memccpy"}}},
+ TR::Sink({{3}}, MsgTaintedBufferSize)},
+ {{CDF_MaybeBuiltin, {{"realloc"}}},
+ TR::Sink({{1}}, MsgTaintedBufferSize)},
+ {{{{"setproctitle"}}}, TR::Sink({{0}, 1}, MsgUncontrolledFormatString)},
+ {{{{"setproctitle_fast"}}},
TR::Sink({{0}, 1}, MsgUncontrolledFormatString)},
// SinkProps
@@ -702,7 +705,7 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {
{{CDF_MaybeBuiltin, {BI.getName(Builtin::BIstrndup)}},
TR::SinkProp({{1}}, {{0, 1}}, {{ReturnValueIndex}},
MsgTaintedBufferSize)},
- {{CDF_MaybeBuiltin, {"bcopy"}},
+ {{CDF_MaybeBuiltin, {{"bcopy"}}},
TR::SinkProp({{2}}, {{0, 2}}, {{1}}, MsgTaintedBufferSize)}};
// `getenv` returns taint only in untrusted environments.
@@ -710,7 +713,7 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {
// void setproctitle_init(int argc, char *argv[], char *envp[])
GlobalCRules.push_back(
{{{"setproctitle_init"}}, TR::Sink({{1, 2}}, MsgCustomSink)});
- GlobalCRules.push_back({{"getenv"}, TR::Source({{ReturnValueIndex}})});
+ GlobalCRules.push_back({{{"getenv"}}, TR::Source({{ReturnValueIndex}})});
}
StaticTaintRules.emplace(std::make_move_iterator(GlobalCRules.begin()),
@@ -723,7 +726,7 @@ void GenericTaintChecker::initTaintRules(CheckerContext &C) const {
std::string Option{"Config"};
StringRef ConfigFile =
Mgr->getAnalyzerOptions().getCheckerStringOption(this, Option);
- llvm::Optional<TaintConfiguration> Config =
+ std::optional<TaintConfiguration> Config =
getConfiguration<TaintConfiguration>(*Mgr, this, Option, ConfigFile);
if (!Config) {
// We don't have external taint config, no parsing required.
@@ -899,7 +902,7 @@ bool GenericTaintRule::UntrustedEnv(CheckerContext &C) {
bool GenericTaintChecker::generateReportIfTainted(const Expr *E, StringRef Msg,
CheckerContext &C) const {
assert(E);
- Optional<SVal> TaintedSVal{getTaintedPointeeOrPointer(C, C.getSVal(E))};
+ std::optional<SVal> TaintedSVal{getTaintedPointeeOrPointer(C, C.getSVal(E))};
if (!TaintedSVal)
return false;