diff options
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp | 36 | ||||
-rw-r--r-- | test/Analysis/keychainAPI.m | 12 |
2 files changed, 30 insertions, 18 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp index 0b369d795a..8470dc6272 100644 --- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp @@ -230,23 +230,25 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE, const Expr *ArgExpr = CE->getArg(FunctionsToTrack[idx].Param); if (SymbolRef V = getAsPointeeSymbol(ArgExpr, C)) if (const AllocationState *AS = State->get<AllocatedData>(V)) { - // Remove the value from the state. The new symbol will be added for - // tracking when the second allocator is processed in checkPostStmt(). - State = State->remove<AllocatedData>(V); - ExplodedNode *N = C.generateNode(State); - if (!N) - return; - initBugType(); - llvm::SmallString<128> sbuf; - llvm::raw_svector_ostream os(sbuf); - unsigned int DIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx; - os << "Allocated data should be released before another call to " - << "the allocator: missing a call to '" - << FunctionsToTrack[DIdx].Name - << "'."; - RangedBugReport *Report = new RangedBugReport(*BT, os.str(), N); - Report->addRange(ArgExpr->getSourceRange()); - C.EmitReport(Report); + if (!definitelyReturnedError(AS->RetValue, State, C.getSValBuilder())) { + // Remove the value from the state. The new symbol will be added for + // tracking when the second allocator is processed in checkPostStmt(). + State = State->remove<AllocatedData>(V); + ExplodedNode *N = C.generateNode(State); + if (!N) + return; + initBugType(); + llvm::SmallString<128> sbuf; + llvm::raw_svector_ostream os(sbuf); + unsigned int DIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx; + os << "Allocated data should be released before another call to " + << "the allocator: missing a call to '" + << FunctionsToTrack[DIdx].Name + << "'."; + RangedBugReport *Report = new RangedBugReport(*BT, os.str(), N); + Report->addRange(ArgExpr->getSourceRange()); + C.EmitReport(Report); + } } return; } diff --git a/test/Analysis/keychainAPI.m b/test/Analysis/keychainAPI.m index 7a7fcf0cce..fa8135fbad 100644 --- a/test/Analysis/keychainAPI.m +++ b/test/Analysis/keychainAPI.m @@ -143,12 +143,22 @@ OSStatus getPasswordAndItem(void** password, UInt32* passwordLength) { } // no-warning // Make sure we do not report an error if we call free only if password != 0. -OSStatus testSecKeychainFindGenericPassword(UInt32* passwordLength) { +// Also, do not report double allocation if first allocation returned an error. +OSStatus testSecKeychainFindGenericPassword(UInt32* passwordLength, + CFTypeRef keychainOrArray, SecProtocolType protocol, + SecAuthenticationType authenticationType) { OSStatus err; SecKeychainItemRef item; void *password; err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx", passwordLength, &password, &item); + if( err == GenericError ) { + err = SecKeychainFindInternetPassword(keychainOrArray, + 16, "server", 16, "domain", 16, "account", + 16, "path", 222, protocol, authenticationType, + passwordLength, &(password), 0); + } + if (err == noErr && password) { SecKeychainItemFreeContent(0, password); } |