// If there are no arguments specified, warn with -Wformat-security, otherwise
// warn only with -Wformat-nonliteral.
if (Args.size() == firstDataArg) {
- const SemaDiagnosticBuilder &D =
- Diag(FormatLoc, diag::warn_format_nonliteral_noargs);
+ Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
+ << OrigFormatExpr->getSourceRange();
switch (Type) {
default:
- D << OrigFormatExpr->getSourceRange();
break;
case FST_Kprintf:
case FST_FreeBSDKPrintf:
case FST_Printf:
- D << FixItHint::CreateInsertion(FormatLoc, "\"%s\", ");
+ Diag(FormatLoc, diag::note_format_security_fixit)
+ << FixItHint::CreateInsertion(FormatLoc, "\"%s\", ");
break;
case FST_NSString:
- D << FixItHint::CreateInsertion(FormatLoc, "@\"%@\", ");
+ Diag(FormatLoc, diag::note_format_security_fixit)
+ << FixItHint::CreateInsertion(FormatLoc, "@\"%@\", ");
break;
}
} else {
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __WCHAR_TYPE__ wchar_t;
-extern const char *NonliteralString;
-
void test() {
// Basic types
printf("%s", (int) 123);
printf("%G", (long double) 42);
printf("%a", (long double) 42);
printf("%A", (long double) 42);
-
- // nonliteral format
- printf(NonliteralString);
}
int scanf(char const *, ...);
// CHECK: printf("%LG", (long double) 42);
// CHECK: printf("%La", (long double) 42);
// CHECK: printf("%LA", (long double) 42);
-// CHECK: printf("%s", NonliteralString);
// CHECK: scanf("%99s", str);
// CHECK: scanf("%s", vstr);
va_start(ap,buf);
printf(s); // expected-warning {{format string is not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
vprintf(s,ap); // expected-warning {{format string is not a string literal}}
fprintf(fp,s); // expected-warning {{format string is not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
vfprintf(fp,s,ap); // expected-warning {{format string is not a string literal}}
asprintf(&b,s); // expected-warning {{format string is not a string lit}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
vasprintf(&b,s,ap); // expected-warning {{format string is not a string literal}}
sprintf(buf,s); // expected-warning {{format string is not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
snprintf(buf,2,s); // expected-warning {{format string is not a string lit}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
__builtin___sprintf_chk(buf,0,-1,s); // expected-warning {{format string is not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
__builtin___snprintf_chk(buf,2,0,-1,s); // expected-warning {{format string is not a string lit}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
vsprintf(buf,s,ap); // expected-warning {{format string is not a string lit}}
vsnprintf(buf,2,s,ap); // expected-warning {{format string is not a string lit}}
vsnprintf(buf,2,global_fmt,ap); // expected-warning {{format string is not a string literal}}
va_start(ap,buf);
printf(s); // expected-warning {{format string is not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
vprintf(s,ap); // no-warning
fprintf(fp,s); // expected-warning {{format string is not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
vfprintf(fp,s,ap); // no-warning
asprintf(&b,s); // expected-warning {{format string is not a string lit}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
vasprintf(&b,s,ap); // no-warning
sprintf(buf,s); // expected-warning {{format string is not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
snprintf(buf,2,s); // expected-warning {{format string is not a string lit}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
__builtin___vsnprintf_chk(buf,2,0,-1,s,ap); // no-warning
vscanf(s, ap); // expected-warning {{format string is not a string literal}}
printf(i == 1 ? "yes" : "no"); // no-warning
printf(i == 0 ? (i == 1 ? "yes" : "no") : "dont know"); // no-warning
printf(i == 0 ? (i == 1 ? s : "no") : "dont know"); // expected-warning{{format string is not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
printf("yes" ?: "no %d", 1); // expected-warning{{data argument not used by format string}}
printf(0 ? "yes %s" : "no %d", 1); // no-warning
printf(0 ? "yes %d" : "no %s", 1); // expected-warning{{format specifies type 'char *'}}
printf(s1); // no-warning
printf(s2); // no-warning
printf(s3); // expected-warning{{not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
printf(s4); // expected-warning{{not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
printf(s5); // expected-warning{{not a string literal}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
}
void test9(char *P) {
int x;
printf(P); // expected-warning {{format string is not a string literal (potentially insecure)}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
printf(P, 42);
}
__attribute__((__format__(__printf__, 1, 3)));
void test_format_security_pos(char* string) {
test_format_security_extra_args(string, 5); // expected-warning {{format string is not a string literal (potentially insecure)}}
+ // expected-note@-1{{treat the string as an argument to avoid this}}
}
#pragma GCC diagnostic warning "-Wformat-nonliteral"
+++ /dev/null
-// RUN: cp %s %t
-// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin -Wno-objc-root-class -pedantic -Wall -fixit %t
-// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin -Wno-objc-root-class -fsyntax-only -pedantic -Wall -Werror %t
-// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin -Wno-objc-root-class -E -o - %t | FileCheck %s
-
-typedef signed char BOOL;
-typedef unsigned int NSUInteger;
-typedef struct _NSZone NSZone;
-@class NSCoder, NSString, NSEnumerator;
-@protocol NSObject - (BOOL)isEqual:(id)object; @end
-@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
-@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
-@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
-@interface NSObject <NSObject> {} @end
-@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; @end
-extern void NSLog(NSString *format, ...);
-
-/* This is a test of the various code modification hints that are
- provided as part of warning or extension diagnostics. All of the
- warnings will be fixed by -fixit, and the resulting file should
- compile cleanly with -Werror -pedantic. */
-
-extern NSString *NonliteralString;
-
-void test() {
- // nonliteral format
- NSLog(NonliteralString);
-}
-
-// Validate the fixes.
-// CHECK: NSLog(@"%@", NonliteralString);