1 // RUN: clang-cc -fsyntax-only -verify -Wformat-nonliteral %s 2 3 // Define this to get vasprintf on Linux 4 #define _GNU_SOURCE 5 6 #include <stdio.h> 7 #include <stdarg.h> 8 9 char * global_fmt; 10 11 #if defined(_WIN32) || defined(_WIN64) 12 extern int snprintf(char*, size_t, const char*, ...); 13 #endif 14 15 void check_string_literal( FILE* fp, const char* s, char *buf, ... ) { 16 17 char * b; 18 va_list ap; 19 va_start(ap,buf); 20 21 printf(s); // expected-warning {{format string is not a string literal}} 22 vprintf(s,ap); // // no-warning 23 fprintf(fp,s); // expected-warning {{format string is not a string literal}} 24 vfprintf(fp,s,ap); // no-warning 25 asprintf(&b,s); // expected-warning {{format string is not a string lit}} 26 vasprintf(&b,s,ap); // no-warning 27 sprintf(buf,s); // expected-warning {{format string is not a string literal}} 28 snprintf(buf,2,s); // expected-warning {{format string is not a string lit}} 29 __builtin___sprintf_chk(buf,0,-1,s); // expected-warning {{format string is not a string literal}} 30 __builtin___snprintf_chk(buf,2,0,-1,s); // expected-warning {{format string is not a string lit}} 31 vsprintf(buf,s,ap); // no-warning 32 vsnprintf(buf,2,s,ap); // no-warning 33 vsnprintf(buf,2,global_fmt,ap); // expected-warning {{format string is not a string literal}} 34 __builtin___vsnprintf_chk(buf,2,0,-1,s,ap); // no-warning 35 __builtin___vsnprintf_chk(buf,2,0,-1,global_fmt,ap); // expected-warning {{format string is not a string literal}} 36 37 // rdar://6079877 38 printf("abc" 39 "%*d", (unsigned) 1, 1); // expected-warning {{field width should have type 'int'}} 40 printf("abc\ 41 def" 42 "%*d", (unsigned) 1, 1); // expected-warning {{field width should have type 'int'}} 43 44 } 45 46 void check_conditional_literal(const char* s, int i) { 47 printf(i == 1 ? "yes" : "no"); // no-warning 48 printf(i == 0 ? (i == 1 ? "yes" : "no") : "dont know"); // no-warning 49 printf(i == 0 ? (i == 1 ? s : "no") : "dont know"); // expected-warning{{format string is not a string literal}} 50 } 51 52 void check_writeback_specifier() 53 { 54 int x; 55 char *b; 56 57 printf("%n",&x); // expected-warning {{'%n' in format string discouraged}} 58 sprintf(b,"%d%%%n",1, &x); // expected-warning {{'%n' in format string dis}} 59 } 60 61 void check_invalid_specifier(FILE* fp, char *buf) 62 { 63 printf("%s%lb%d","unix",10,20); // expected-warning {{lid conversion '%lb'}} 64 fprintf(fp,"%%%l"); // expected-warning {{lid conversion '%l'}} 65 sprintf(buf,"%%%%%ld%d%d", 1, 2, 3); // no-warning 66 snprintf(buf, 2, "%%%%%ld%;%d", 1, 2, 3); // expected-warning {{sion '%;'}} 67 } 68 69 void check_null_char_string(char* b) 70 { 71 printf("\0this is bogus%d",1); // expected-warning {{string contains '\0'}} 72 snprintf(b,10,"%%%%%d\0%d",1,2); // expected-warning {{string contains '\0'}} 73 printf("%\0d",1); // expected-warning {{string contains '\0'}} 74 } 75 76 void check_empty_format_string(char* buf, ...) 77 { 78 va_list ap; 79 va_start(ap,buf); 80 vprintf("",ap); // expected-warning {{format string is empty}} 81 sprintf(buf,""); // expected-warning {{format string is empty}} 82 } 83 84 void check_wide_string(char* b, ...) 85 { 86 va_list ap; 87 va_start(ap,b); 88 89 printf(L"foo %d",2); // expected-warning {{incompatible pointer types}}, expected-warning {{should not be a wide string}} 90 vsprintf(b,L"bar %d",ap); // expected-warning {{incompatible pointer types}}, expected-warning {{should not be a wide string}} 91 } 92 93 void check_asterisk_precision_width(int x) { 94 printf("%*d"); // expected-warning {{'*' specified field width is missing a matching 'int' argument}} 95 printf("%.*d"); // expected-warning {{'.*' specified field precision is missing a matching 'int' argument}} 96 printf("%*d",12,x); // no-warning 97 printf("%*d","foo",x); // expected-warning {{field width should have type 'int', but argument has type 'char *'}} 98 printf("%.*d","foo",x); // expected-warning {{field precision should have type 'int', but argument has type 'char *'}} 99 } 100 101 void __attribute__((format(printf,1,3))) myprintf(const char*, int blah, ...); 102 103 void test_myprintf() { 104 myprintf("%d", 17, 18); // okay 105 } 106 107 void test_constant_bindings(void) { 108 const char * const s1 = "hello"; 109 const char s2[] = "hello"; 110 const char *s3 = "hello"; 111 char * const s4 = "hello"; 112 extern const char s5[]; 113 114 printf(s1); // no-warning 115 printf(s2); // no-warning 116 printf(s3); // expected-warning{{not a string literal}} 117 printf(s4); // expected-warning{{not a string literal}} 118 printf(s5); // expected-warning{{not a string literal}} 119 } 120 121 122 // Test what happens when -Wformat-security only. 123 #pragma GCC diagnostic ignored "-Wformat-nonliteral" 124 #pragma GCC diagnostic warning "-Wformat-security" 125 126 void test9(char *P) { 127 int x; 128 printf(P); // expected-warning {{format string is not a string literal (potentially insecure)}} 129 printf(P, 42); 130 printf("%n", &x); // expected-warning {{use of '%n' in format string discouraged }} 131 } 132 133 void torture(va_list v8) { 134 vprintf ("%*.*d", v8); // no-warning 135 } 136 137