|
@@ -156,14 +156,21 @@ bool WalkAST::containsBadStrlcpyStrlcatPattern(const CallExpr *CE) {
|
|
const Expr *DstArg = CE->getArg(0);
|
|
const Expr *DstArg = CE->getArg(0);
|
|
const Expr *LenArg = CE->getArg(2);
|
|
const Expr *LenArg = CE->getArg(2);
|
|
|
|
|
|
- const auto *DstArgDecl = dyn_cast<DeclRefExpr>(DstArg->IgnoreParenImpCasts());
|
|
|
|
- const auto *LenArgDecl = dyn_cast<DeclRefExpr>(LenArg->IgnoreParenLValueCasts());
|
|
|
|
|
|
+ const auto *DstArgDRE = dyn_cast<DeclRefExpr>(DstArg->IgnoreParenImpCasts());
|
|
|
|
+ const auto *LenArgDRE =
|
|
|
|
+ dyn_cast<DeclRefExpr>(LenArg->IgnoreParenLValueCasts());
|
|
uint64_t DstOff = 0;
|
|
uint64_t DstOff = 0;
|
|
if (isSizeof(LenArg, DstArg))
|
|
if (isSizeof(LenArg, DstArg))
|
|
return false;
|
|
return false;
|
|
|
|
+
|
|
// - size_t dstlen = sizeof(dst)
|
|
// - size_t dstlen = sizeof(dst)
|
|
- if (LenArgDecl) {
|
|
|
|
- const auto *LenArgVal = dyn_cast<VarDecl>(LenArgDecl->getDecl());
|
|
|
|
|
|
+ if (LenArgDRE) {
|
|
|
|
+ const auto *LenArgVal = dyn_cast<VarDecl>(LenArgDRE->getDecl());
|
|
|
|
+ // If it's an EnumConstantDecl instead, then we're missing out on something.
|
|
|
|
+ if (!LenArgVal) {
|
|
|
|
+ assert(isa<EnumConstantDecl>(LenArgDRE->getDecl()));
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
if (LenArgVal->getInit())
|
|
if (LenArgVal->getInit())
|
|
LenArg = LenArgVal->getInit();
|
|
LenArg = LenArgVal->getInit();
|
|
}
|
|
}
|
|
@@ -177,9 +184,10 @@ bool WalkAST::containsBadStrlcpyStrlcatPattern(const CallExpr *CE) {
|
|
// Case when there is pointer arithmetic on the destination buffer
|
|
// Case when there is pointer arithmetic on the destination buffer
|
|
// especially when we offset from the base decreasing the
|
|
// especially when we offset from the base decreasing the
|
|
// buffer length accordingly.
|
|
// buffer length accordingly.
|
|
- if (!DstArgDecl) {
|
|
|
|
- if (const auto *BE = dyn_cast<BinaryOperator>(DstArg->IgnoreParenImpCasts())) {
|
|
|
|
- DstArgDecl = dyn_cast<DeclRefExpr>(BE->getLHS()->IgnoreParenImpCasts());
|
|
|
|
|
|
+ if (!DstArgDRE) {
|
|
|
|
+ if (const auto *BE =
|
|
|
|
+ dyn_cast<BinaryOperator>(DstArg->IgnoreParenImpCasts())) {
|
|
|
|
+ DstArgDRE = dyn_cast<DeclRefExpr>(BE->getLHS()->IgnoreParenImpCasts());
|
|
if (BE->getOpcode() == BO_Add) {
|
|
if (BE->getOpcode() == BO_Add) {
|
|
if ((IL = dyn_cast<IntegerLiteral>(BE->getRHS()->IgnoreParenImpCasts()))) {
|
|
if ((IL = dyn_cast<IntegerLiteral>(BE->getRHS()->IgnoreParenImpCasts()))) {
|
|
DstOff = IL->getValue().getZExtValue();
|
|
DstOff = IL->getValue().getZExtValue();
|
|
@@ -187,8 +195,9 @@ bool WalkAST::containsBadStrlcpyStrlcatPattern(const CallExpr *CE) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (DstArgDecl) {
|
|
|
|
- if (const auto *Buffer = dyn_cast<ConstantArrayType>(DstArgDecl->getType())) {
|
|
|
|
|
|
+ if (DstArgDRE) {
|
|
|
|
+ if (const auto *Buffer =
|
|
|
|
+ dyn_cast<ConstantArrayType>(DstArgDRE->getType())) {
|
|
ASTContext &C = BR.getContext();
|
|
ASTContext &C = BR.getContext();
|
|
uint64_t BufferLen = C.getTypeSize(Buffer) / 8;
|
|
uint64_t BufferLen = C.getTypeSize(Buffer) / 8;
|
|
auto RemainingBufferLen = BufferLen - DstOff;
|
|
auto RemainingBufferLen = BufferLen - DstOff;
|