================
@@ -682,38 +687,86 @@ void WalkAST::checkCall_mkstemp(const CallExpr *CE, const 
FunctionDecl *FD) {
 // the Bounds of a Memory Buffer
 
//===----------------------------------------------------------------------===//
 
+
+void WalkAST::emitUnboundedStringDiagnostic(const CallExpr *CE, StringRef Name,
+                                            StringRef NarrowReplacement,
+                                            bool IsWide) {
+  // Construct the warning title and description.
+  SmallString<128> Buf1;
+  SmallString<512> Buf2;
+  llvm::raw_svector_ostream Out1(Buf1);
+  llvm::raw_svector_ostream Out2(Buf2);
+
+  Out1 << "Potential insecure memory buffer bounds restriction in call '"
+       << Name << "'";
+
+  Out2 << "Call to function '" << Name
+       << "' is insecure as it does not "
+          "provide bounding of the memory buffer. Replace "
+          "unbounded copy functions with analogous functions that "
+          "support length arguments";
+
+  if (IsWide)
+    Out2 << " for wide-character strings";
+  else
+    Out2 << " such as '" << NarrowReplacement << "'";
+
+  Out2 << ". CWE-119.";
+
+  // Issue a warning.
+  PathDiagnosticLocation CELoc =
+      PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
+
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy, Out1.str(),
+                     "Security", Out2.str(), CELoc,
+                     CE->getCallee()->getSourceRange());
+}
+
+
 void WalkAST::checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD) {
   if (!filter.check_strcpy)
     return;
 
-  if (!checkCall_strCommon(CE, FD))
+  // Get the function name and normalize fortified variants.
+  StringRef Name = FD->getIdentifier()->getName();
+  Name.consume_front("__builtin_");
+
+  if (Name == "__strcpy_chk")
+    Name = "strcpy";
+
+  bool IsWide = Name == "wcscpy" || Name == "lstrcpyW";
+
+  if (!checkCall_strCommon(CE, FD, IsWide))
     return;
 
-  const auto *Target = CE->getArg(0)->IgnoreImpCasts(),
-             *Source = CE->getArg(1)->IgnoreImpCasts();
+  const auto *Target = CE->getArg(0)->IgnoreImpCasts();
+  const auto *Source = CE->getArg(1)->IgnoreImpCasts();
 
+  // Check whether a string literal fits into the destination array.
   if (const auto *Array = dyn_cast<ConstantArrayType>(Target->getType())) {
-    uint64_t ArraySize = BR.getContext().getTypeSize(Array) / 8;
+    uint64_t ArraySize = Array->getSize().getZExtValue();
+
     if (const auto *String = dyn_cast<StringLiteral>(Source)) {
-      if (ArraySize >= String->getLength() + 1)
+      ASTContext &Ctx = BR.getContext();
+
+      QualType DestElementType =
+          Ctx.getCanonicalType(Array->getElementType()).getUnqualifiedType();
+
+      QualType SrcElementType =
+          Ctx.getCanonicalType(
+                 String->getType()->getAsArrayTypeUnsafe()->getElementType())
+              .getUnqualifiedType();
+
+      if (DestElementType == SrcElementType &&
+          ArraySize >= String->getLength() + 1)
         return;
     }
   }
 
-  // Issue a warning.
-  PathDiagnosticLocation CELoc =
-    PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy,
-                     "Potential insecure memory buffer bounds restriction in "
-                     "call 'strcpy'",
-                     "Security",
-                     "Call to function 'strcpy' is insecure as it does not "
-                     "provide bounding of the memory buffer. Replace "
-                     "unbounded copy functions with analogous functions that "
-                     "support length arguments such as 'strlcpy'. CWE-119.",
-                     CELoc, CE->getCallee()->getSourceRange());
+  emitUnboundedStringDiagnostic(CE, Name, "strlcpy", IsWide);
 }
 
+
----------------
benedekaibas wrote:

```suggestion
```

nit: At _most_ places in this checker there are only one spaces between the 
functions and the comments, but at a few places like this one there are two 
spaces. I'd advise removing this, but no hard preference.

https://github.com/llvm/llvm-project/pull/234582
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to