Skip to content

Commit 6bd9488

Browse files
vfscanf does not model escaping of parameters
1 parent 26423cb commit 6bd9488

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,10 +1050,13 @@ void StreamChecker::evalFscanf(const FnDescription *Desc, const CallEvent &Call,
10501050
if (!StateNotFailed)
10511051
return;
10521052

1053-
SmallVector<unsigned int> EscArgs;
1054-
for (auto EscArg : llvm::seq(2u, Call.getNumArgs()))
1055-
EscArgs.push_back(EscArg);
1056-
StateNotFailed = escapeArgs(StateNotFailed, C, Call, EscArgs);
1053+
if (auto const *Callee = Call.getCalleeIdentifier();
1054+
!Callee || !Callee->getName().equals("vfscanf")) {
1055+
SmallVector<unsigned int> EscArgs;
1056+
for (auto EscArg : llvm::seq(2u, Call.getNumArgs()))
1057+
EscArgs.push_back(EscArg);
1058+
StateNotFailed = escapeArgs(StateNotFailed, C, Call, EscArgs);
1059+
}
10571060

10581061
if (StateNotFailed)
10591062
C.addTransition(StateNotFailed);

clang/test/Analysis/stream.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,3 +473,28 @@ void test_fprintf() {
473473

474474
fclose(F1);
475475
}
476+
477+
478+
int test_vscanf_inner(const char *fmt, ...) {
479+
FILE *F1 = tmpfile();
480+
if (!F1)
481+
return EOF;
482+
483+
va_list ap;
484+
va_start(ap, fmt);
485+
486+
int r = vfscanf(F1, fmt, ap);
487+
488+
fclose(F1);
489+
va_end(ap);
490+
return r;
491+
}
492+
493+
void test_vscanf() {
494+
int i = 42;
495+
int r = test_vscanf_inner("%d", &i);
496+
if (r != EOF) {
497+
clang_analyzer_dump_int(i); // expected-warning {{conj_$}}
498+
// FIXME va_list "hides" the pointer to i
499+
}
500+
}

0 commit comments

Comments
 (0)