diff options
-rw-r--r-- | lib/Checker/StreamChecker.cpp | 29 | ||||
-rw-r--r-- | test/Analysis/stream.c | 6 |
2 files changed, 18 insertions, 17 deletions
diff --git a/lib/Checker/StreamChecker.cpp b/lib/Checker/StreamChecker.cpp index 8553875a24..fb1937933d 100644 --- a/lib/Checker/StreamChecker.cpp +++ b/lib/Checker/StreamChecker.cpp @@ -271,29 +271,24 @@ void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) { return; // Check the legality of the 'whence' argument of 'fseek'. SVal Whence = state->getSVal(CE->getArg(2)); - bool WhenceIsLegal = true; const nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Whence); + if (!CI) - WhenceIsLegal = false; + return; int64_t x = CI->getValue().getSExtValue(); - if (!(x == 0 || x == 1 || x == 2)) - WhenceIsLegal = false; - - if (!WhenceIsLegal) { - if (ExplodedNode *N = C.GenerateSink(state)) { - if (!BT_illegalwhence) - BT_illegalwhence = new BuiltinBug("Illegal whence argument", - "The whence argument to fseek() should be " - "SEEK_SET, SEEK_END, or SEEK_CUR."); - BugReport *R = new BugReport(*BT_illegalwhence, - BT_illegalwhence->getDescription(), N); - C.EmitReport(R); - } + if (x >= 0 && x <= 2) return; - } - C.addTransition(state); + if (ExplodedNode *N = C.GenerateNode(state)) { + if (!BT_illegalwhence) + BT_illegalwhence = new BuiltinBug("Illegal whence argument", + "The whence argument to fseek() should be " + "SEEK_SET, SEEK_END, or SEEK_CUR."); + BugReport *R = new BugReport(*BT_illegalwhence, + BT_illegalwhence->getDescription(), N); + C.EmitReport(R); + } } void StreamChecker::Ftell(CheckerContext &C, const CallExpr *CE) { diff --git a/test/Analysis/stream.c b/test/Analysis/stream.c index 73bbc13cfb..0b4960ffd9 100644 --- a/test/Analysis/stream.c +++ b/test/Analysis/stream.c @@ -77,3 +77,9 @@ FILE *f9(void) { void pr7831(FILE *fp) { fclose(fp); // no-warning } + +// PR 8081 - null pointer crash when 'whence' is not an integer constant +void pr8081(FILE *stream, long offset, int whence) { + fseek(stream, offset, whence); +} + |