diff options
Diffstat (limited to 'clang/lib/Analysis/PrintfFormatString.cpp')
-rw-r--r-- | clang/lib/Analysis/PrintfFormatString.cpp | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/clang/lib/Analysis/PrintfFormatString.cpp b/clang/lib/Analysis/PrintfFormatString.cpp index c6453b66549..146635b8870 100644 --- a/clang/lib/Analysis/PrintfFormatString.cpp +++ b/clang/lib/Analysis/PrintfFormatString.cpp @@ -54,7 +54,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, const char *E, unsigned &argIndex, const LangOptions &LO, - const TargetInfo &Target) { + const TargetInfo &Target, + bool Warn) { using namespace clang::analyze_format_string; using namespace clang::analyze_printf; @@ -83,7 +84,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, if (I == E) { // No more characters left? - H.HandleIncompleteSpecifier(Start, E - Start); + if (Warn) + H.HandleIncompleteSpecifier(Start, E - Start); return true; } @@ -93,7 +95,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, if (I == E) { // No more characters left? - H.HandleIncompleteSpecifier(Start, E - Start); + if (Warn) + H.HandleIncompleteSpecifier(Start, E - Start); return true; } @@ -118,7 +121,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, if (I == E) { // No more characters left? - H.HandleIncompleteSpecifier(Start, E - Start); + if (Warn) + H.HandleIncompleteSpecifier(Start, E - Start); return true; } @@ -129,7 +133,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, if (I == E) { // No more characters left? - H.HandleIncompleteSpecifier(Start, E - Start); + if (Warn) + H.HandleIncompleteSpecifier(Start, E - Start); return true; } @@ -137,7 +142,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, if (*I == '.') { ++I; if (I == E) { - H.HandleIncompleteSpecifier(Start, E - Start); + if (Warn) + H.HandleIncompleteSpecifier(Start, E - Start); return true; } @@ -147,7 +153,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, if (I == E) { // No more characters left? - H.HandleIncompleteSpecifier(Start, E - Start); + if (Warn) + H.HandleIncompleteSpecifier(Start, E - Start); return true; } } @@ -155,7 +162,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, // Look for the length modifier. if (ParseLengthModifier(FS, I, E, LO) && I == E) { // No more characters left? - H.HandleIncompleteSpecifier(Start, E - Start); + if (Warn) + H.HandleIncompleteSpecifier(Start, E - Start); return true; } @@ -239,7 +247,7 @@ bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, // Keep looking for a format specifier until we have exhausted the string. while (I != E) { const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, - LO, Target); + LO, Target, true); // Did a fail-stop error of any kind occur when parsing the specifier? // If so, don't do any more processing. if (FSR.shouldStop()) @@ -257,6 +265,34 @@ bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, return false; } +bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I, + const char *E, + const LangOptions &LO, + const TargetInfo &Target) { + + unsigned argIndex = 0; + + // Keep looking for a %s format specifier until we have exhausted the string. + FormatStringHandler H; + while (I != E) { + const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, + LO, Target, false); + // Did a fail-stop error of any kind occur when parsing the specifier? + // If so, don't do any more processing. + if (FSR.shouldStop()) + return false; + // Did we exhaust the string or encounter an error that + // we can recover from? + if (!FSR.hasValue()) + continue; + const analyze_printf::PrintfSpecifier &FS = FSR.getValue(); + // Return true if this a %s format specifier. + if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg) + return true; + } + return false; +} + //===----------------------------------------------------------------------===// // Methods on PrintfSpecifier. //===----------------------------------------------------------------------===// |