diff options
author | Ted Kremenek <kremenek@apple.com> | 2007-08-14 17:39:48 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2007-08-14 17:39:48 +0000 |
commit | 71895b9aa3ad71957359497e136b50fcb6136bdf (patch) | |
tree | c1fe5cee0b621cff12a5e0623a6b84f375b1e7be /test/Sema/format-strings.c | |
parent | e6a82b2c29ad05534841e5f8fd033fb17b6f61e2 (diff) |
Added support for additional format string checking for the printf
family of functions. Previous functionality only included checking to
see if the format string was a string literal. Now we check parse the
format string (if it is a literal) and perform the following checks:
(1) Warn if: number conversions (e.g. "%d") != number data arguments.
(2) Warn about missing format strings (e.g., "printf()").
(3) Warn if the format string is not a string literal.
(4) Warn about the use se of '%n' conversion. This conversion is
discouraged for security reasons.
(5) Warn about malformed conversions. For example '%;', '%v'; these
are not valid.
(6) Warn about empty format strings; e.g. printf(""). Although these
can be optimized away by the compiler, they can be indicative of
broken programmer logic. We may need to add additional support to
see when such cases occur within macro expansion to avoid false
positives.
(7) Warn if the string literal is wide; e.g. L"%d".
(8) Warn if we detect a '\0' character WITHIN the format string.
Test cases are included.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41076 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Sema/format-strings.c')
-rw-r--r-- | test/Sema/format-strings.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c index f71cd58645..403da07b0f 100644 --- a/test/Sema/format-strings.c +++ b/test/Sema/format-strings.c @@ -21,3 +21,44 @@ void check_string_literal( FILE* fp, const char* s, char *buf, ... ) { vsnprintf(buf,2,s,ap); // expected-warning {{mat string is not a string lit}} } +void check_writeback_specifier() +{ + int x; + char *b; + + printf("%n",&x); // expected-warning {{'%n' in format string discouraged}} + sprintf(b,"%d%%%n",1, &x); // expected-warning {{'%n' in format string dis}} +} + +void check_invalid_specifier(FILE* fp, char *buf) +{ + printf("%s%lb%d","unix",10,20); // expected-warning {{lid conversion '%lb'}} + fprintf(fp,"%%%l"); // expected-warning {{lid conversion '%l'}} + sprintf(buf,"%%%%%ld%d%d", 1, 2, 3); // no-warning + snprintf(buf, 2, "%%%%%ld%;%d", 1, 2, 3); // expected-warning {{sion '%;'}} +} + +void check_null_char_string(char* b) +{ + printf("\0this is bogus%d",1); // expected-warning {{string contains '\0'}} + snprintf(b,10,"%%%%%d\0%d",1,2); // expected-warning {{string contains '\0'}} + printf("%\0d",1); // expected-warning {{string contains '\0'}} +} + +void check_empty_format_string(char* buf) +{ + va_list ap; + va_start(ap,buf); + vprintf("",ap); // expected-warning {{format string is empty}} + sprintf(buf,""); // expected-warning {{format string is empty}} +} + +void check_wide_string() +{ + char *b; + va_list ap; + va_start(ap,b); + + printf(L"foo %d",2); // expected-warning {{should not be a wide string}} + vasprintf(&b,L"bar %d",2); // expected-warning {{should not be a wide string}} +} |