From 9abe2268ef1237e16fa55393ad4c731a1cfe2944 Mon Sep 17 00:00:00 2001 From: Pavel Kosov Date: Wed, 19 Apr 2023 10:43:41 +0300 Subject: [PATCH 1/2] Revert "[clang] Switch to using CallDescription::matches() instead of isCalled()" This reverts commit 9b29d83f61fc99efa31de71c2710a1cbb17a0630. Issue: https://gitee.com/openharmony/third_party_llvm-project/issues/I6X1AW Signed-off-by: Pavel Kosov --- .../Checkers/OpenHarmony/NapiGetArrBufferDataChecker.cpp | 4 ++-- .../Checkers/OpenHarmony/NapiScopeManagerChecker.cpp | 4 ++-- .../Checkers/OpenHarmony/NapiWrapParamChecker.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiGetArrBufferDataChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiGetArrBufferDataChecker.cpp index cfb384b2fbed..6b2341af9009 100644 --- a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiGetArrBufferDataChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiGetArrBufferDataChecker.cpp @@ -72,7 +72,7 @@ NapiGetArrBufferDataChecker::NapiGetArrBufferDataChecker() // napi_get_arraybuffer_info void NapiGetArrBufferDataChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { - if (!this->NapiGetArrBuffer.matches(Call)) { + if (!Call.isCalled(this->NapiGetArrBuffer)) { return; } ProgramStateRef State = C.getState(); @@ -90,7 +90,7 @@ void NapiGetArrBufferDataChecker::checkPostCall(const CallEvent &Call, // A callback before the function is executed to track free void NapiGetArrBufferDataChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { - if (!this->Free.matches(Call)) { + if (!Call.isCalled(this->Free)) { return; } ProgramStateRef State = C.getState(); diff --git a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiScopeManagerChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiScopeManagerChecker.cpp index 7e5214233956..b4cb795c3138 100644 --- a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiScopeManagerChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiScopeManagerChecker.cpp @@ -206,7 +206,7 @@ void NapiScopeManagerChecker::UvCallbackDetect(CheckerContext &C, // napi_close_handle_scope void NapiScopeManagerChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { - if (!this->CloseHandleScope.matches(Call)) { + if (!Call.isCalled(this->CloseHandleScope)) { return; } ProgramStateRef State = C.getState(); @@ -233,7 +233,7 @@ void NapiScopeManagerChecker::checkPreCall(const CallEvent &Call, // A callback after the function is executed to track the napi_open_handle_scope void NapiScopeManagerChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { - if (!this->OpenHandleScope.matches(Call)) { + if (!Call.isCalled(this->OpenHandleScope)) { return; } ProgramStateRef State = C.getState(); diff --git a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiWrapParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiWrapParamChecker.cpp index 577af93850b0..ed44205e7600 100644 --- a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiWrapParamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiWrapParamChecker.cpp @@ -59,7 +59,7 @@ NapiWrapParamChecker::NapiWrapParamChecker() // A callback before the function is executed to track napi_wrap void NapiWrapParamChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { - if (!this->NapiWrap.matches(Call)) { + if (!Call.isCalled(this->NapiWrap)) { return; } ProgramStateRef State = C.getState(); -- Gitee From b0136baf82d5f26655b52eff6de2f27fb76637a1 Mon Sep 17 00:00:00 2001 From: Pavel Kosov Date: Wed, 19 Apr 2023 10:45:45 +0300 Subject: [PATCH 2/2] Revert "[Clang] add napi static analyzers" This reverts commit a4ed079a69ee9337318e7cdcebaea9cb3537e0a5. Issue: https://gitee.com/openharmony/third_party_llvm-project/issues/I6X1AW Signed-off-by: Pavel Kosov --- .../clang/StaticAnalyzer/Checkers/Checkers.td | 12 - .../StaticAnalyzer/Checkers/CMakeLists.txt | 8 - .../NapiGetArrBufferDataChecker.cpp | 143 ------- .../OpenHarmony/NapiScopeManagerChecker.cpp | 397 ------------------ .../OpenHarmony/NapiWrapParamChecker.cpp | 100 ----- .../napi_get_arraybuffer_info_test.cpp | 29 -- .../test/Analysis/napi_handle_scope_test.cpp | 172 -------- clang/test/Analysis/napi_include.h | 84 ---- clang/test/Analysis/napi_wrap_test.cpp | 16 - 9 files changed, 961 deletions(-) delete mode 100644 clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiGetArrBufferDataChecker.cpp delete mode 100644 clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiScopeManagerChecker.cpp delete mode 100644 clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiWrapParamChecker.cpp delete mode 100644 clang/test/Analysis/napi_get_arraybuffer_info_test.cpp delete mode 100644 clang/test/Analysis/napi_handle_scope_test.cpp delete mode 100644 clang/test/Analysis/napi_include.h delete mode 100644 clang/test/Analysis/napi_wrap_test.cpp diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index e8d6253d160f..df70f03f0939 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1773,18 +1773,6 @@ def SignalHandlerChecker : Checker<"SignalHandler">, Released>, ]>, Documentation; - -def NapiScopeManagerChecker : Checker<"Napi.Scope">, - HelpText<"Check the use of napi_handle_scope">, - Documentation; - -def NapiGetArrBufferDataChecker : Checker<"Napi.GetArrayBuffer">, - HelpText<"Check the use of napi_handle_scope">, - Documentation; - -def NapiWrapParamChecker : Checker<"Napi.Wrap">, - HelpText<"Check the use of napi_handle_scope">, - Documentation; } // OHOS_LOCAL end diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index d4cf9d4a9394..1749bd6233d6 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -135,18 +135,10 @@ add_clang_library(clangStaticAnalyzerCheckers WebKit/UncountedCallArgsChecker.cpp WebKit/UncountedLambdaCapturesChecker.cpp WebKit/UncountedLocalVarsChecker.cpp - - # OHOS_LOCAL begin - OpenHarmony/UnixAPIArgsChecker.cpp OpenHarmony/MemcpyChecker.cpp OpenHarmony/PrintSensitiveInfoChecker.cpp OpenHarmony/SignalHandlerChecker.cpp - OpenHarmony/NapiScopeManagerChecker.cpp - OpenHarmony/NapiGetArrBufferDataChecker.cpp - OpenHarmony/NapiWrapParamChecker.cpp - - # OHOS_LOCAL end LINK_LIBS clangAST diff --git a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiGetArrBufferDataChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiGetArrBufferDataChecker.cpp deleted file mode 100644 index 6b2341af9009..000000000000 --- a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiGetArrBufferDataChecker.cpp +++ /dev/null @@ -1,143 +0,0 @@ -//== NapiGetArrBufferDataChecker.cpp ----------------------------*- C++ -*--==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines NapiGetArrBufferDataChecker, which is a path-sensitive -// check looking for JS data is released by mistake. -// -//===----------------------------------------------------------------------===// - -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" - -using namespace clang; -using namespace ento; -namespace { - -// Checker class -class NapiGetArrBufferDataChecker - : public Checker> { - // Constant definitions - constexpr static int NAPI_GET_ARRAYBUFFER_INFO_AYGS_NUM = 4; - constexpr static int FREE_AYGS_NUM = 1; - constexpr static int NAPI_DATA_POS = 2; - constexpr static int FREE_CONTENT_POS = 0; - - // Function wrapper class definitions - CallDescription NapiGetArrBuffer, Free; - - // BugType definitions - std::unique_ptr DataReleaseBugType; - - // Report warning function - void reportDataRelease(CheckerContext &C, const SymbolRef NapiSym) const; - -public: - NapiGetArrBufferDataChecker(); - - // Checker function - void checkPostCall(const CallEvent &Call, CheckerContext &C) const; - - void checkPreCall(const CallEvent &Call, CheckerContext &C) const; - - void checkPreStmt(const CXXDeleteExpr *DS, CheckerContext &C) const; -}; - -} // end anonymous namespace - -// Register set to save necessary data -REGISTER_SET_WITH_PROGRAMSTATE(DataSet, SymbolRef) - -// Constructor -NapiGetArrBufferDataChecker::NapiGetArrBufferDataChecker() - : NapiGetArrBuffer("napi_get_arraybuffer_info", - NAPI_GET_ARRAYBUFFER_INFO_AYGS_NUM), - Free("free", FREE_AYGS_NUM) { - // Initialize the bug types. - DataReleaseBugType.reset(new BugType( - this, "The third parameter illegal release", "OHOS Napi API Error")); -} - -// A callback after the function is executed to track the -// napi_get_arraybuffer_info -void NapiGetArrBufferDataChecker::checkPostCall(const CallEvent &Call, - CheckerContext &C) const { - if (!Call.isCalled(this->NapiGetArrBuffer)) { - return; - } - ProgramStateRef State = C.getState(); - SVal S = Call.getArgSVal(NAPI_DATA_POS); - Optional X = S.getAs(); - StoreManager &SM = C.getStoreManager(); - SymbolRef DataSym = SM.getBinding(State->getStore(), *X).getAsLocSymbol(); - if (!DataSym) { - return; - } - State = State->add(DataSym); - C.addTransition(State); -} - -// A callback before the function is executed to track free -void NapiGetArrBufferDataChecker::checkPreCall(const CallEvent &Call, - CheckerContext &C) const { - if (!Call.isCalled(this->Free)) { - return; - } - ProgramStateRef State = C.getState(); - SymbolRef PtrSym = Call.getArgSVal(FREE_CONTENT_POS).getAsSymbol(); - if (!PtrSym) { - return; - } - if (State->contains(PtrSym)) { - State = State->remove(PtrSym); - reportDataRelease(C, PtrSym); - } -} - -// A callback before the delete statement is used to capture the delete -// behavior -void NapiGetArrBufferDataChecker::checkPreStmt(const CXXDeleteExpr *DE, - CheckerContext &C) const { - ProgramStateRef State = C.getState(); - SymbolRef ArgSym = C.getSVal(DE->getArgument()).getAsSymbol(); - if (!ArgSym) { - return; - } - if (State->contains(ArgSym)) { - State = State->remove(ArgSym); - reportDataRelease(C, ArgSym); - } -} - -// Report if the data is released -void NapiGetArrBufferDataChecker::reportDataRelease( - CheckerContext &C, const SymbolRef NapiSym) const { - ExplodedNode *ErrNode = C.generateNonFatalErrorNode(C.getState()); - if (!ErrNode) { - return; - } - auto R = std::make_unique( - *DataReleaseBugType, "The variable is not allowed to be released", - ErrNode); - R->markInteresting(NapiSym); - C.emitReport(std::move(R)); -} - -void ento::registerNapiGetArrBufferDataChecker(CheckerManager &mgr) { - mgr.registerChecker(); -} - -bool ento::shouldRegisterNapiGetArrBufferDataChecker( - const CheckerManager &mgr) { - return true; -} \ No newline at end of file diff --git a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiScopeManagerChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiScopeManagerChecker.cpp deleted file mode 100644 index b4cb795c3138..000000000000 --- a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiScopeManagerChecker.cpp +++ /dev/null @@ -1,397 +0,0 @@ -//== NapiScopeManagerChecker.cpp ------------------------------*- C++ -*--==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines NapiScopeManagerChecker, which is a path-sensitive check -// looking for Memory leak issues due to no napi_handle_scope is used. -// -//===----------------------------------------------------------------------===// - -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" -#include "llvm/ADT/StringRef.h" -#include - -using namespace clang; -using namespace ento; -namespace { -using SymbolVector = SmallVector; - -// String packaging class -class StringWarpper { - const std::string Str; - -public: - StringWarpper(const std::string &S) : Str(S) {} - const std::string &get() { return Str; } - void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddString(Str); } - bool operator==(const StringWarpper &rhs) const { return Str == rhs.Str; } - bool operator!=(const StringWarpper &rhs) const { return Str != rhs.Str; } - bool operator<(const StringWarpper &rhs) const { return Str < rhs.Str; } -}; - -// napi_handle_scope state class -struct NapiScopeManagerState { -private: - enum Kind { Opened, Closed } K; - NapiScopeManagerState(Kind InK) : K(InK) {} - -public: - bool isOpened() const { return K == Opened; } - bool isClosed() const { return K == Closed; } - - static NapiScopeManagerState getOpened() { - return NapiScopeManagerState(Opened); - } - static NapiScopeManagerState getClosed() { - return NapiScopeManagerState(Closed); - } - - bool operator==(const NapiScopeManagerState &X) const { return K == X.K; } - void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(K); } -}; - -// uv_queue_work callback state class -struct UvQueueWorkCallBackState { -private: - enum Kind { Safe, Dangerous } K; - UvQueueWorkCallBackState(Kind InK) : K(InK) {} - -public: - bool isSafe() const { return K == Safe; } - bool isDangerous() const { return K == Dangerous; } - - static UvQueueWorkCallBackState getSafe() { - return UvQueueWorkCallBackState(Safe); - } - static UvQueueWorkCallBackState getDangerous() { - return UvQueueWorkCallBackState(Dangerous); - } - - bool operator==(const UvQueueWorkCallBackState &X) const { return K == X.K; } - void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(K); } -}; - -// Checker class -class NapiScopeManagerChecker - : public Checker> { - // Constant definitions - constexpr static int NAPI_SCOPE_AYGS_NUM = 2; - constexpr static int NAPI_SCOPE_HANDLE_POS = 1; - constexpr static int UV_QUEUE_WORK_CALLBACK_AYGS_NUM = 2; - - // Function wrapper class definitions - CallDescription OpenHandleScope, CloseHandleScope; - - // BugType definitions - std::unique_ptr DoubleCloseBugType; - std::unique_ptr LeakBugType; - std::unique_ptr UvLeakBugType; - - // Report warning functions - - void reportDoubleClose(SymbolRef NapiDescSym, const CallEvent &Call, - CheckerContext &C) const; - - void reportLeaks(ArrayRef LeakedStreams, CheckerContext &C, - ExplodedNode *ErrNode) const; - - void reportUvCallBackLeaks(CheckerContext &C, const SourceRange &SR) const; - - // Tool functions - - void UvCallbackDetect(CheckerContext &C, const bool &isBegin) const; - - bool isLeaked(SymbolRef Sym, const NapiScopeManagerState &SS, bool IsSymDead, - ProgramStateRef State) const; - -public: - NapiScopeManagerChecker(); - - // Checker functions - - void checkPostCall(const CallEvent &Call, CheckerContext &C) const; - - void checkPreCall(const CallEvent &Call, CheckerContext &C) const; - - void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; - - void checkBeginFunction(CheckerContext &C) const; - - void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const; - - void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const; -}; - -} // end anonymous namespace - -// Register map to save necessary data -REGISTER_MAP_WITH_PROGRAMSTATE(HandleScopeMap, SymbolRef, NapiScopeManagerState) -REGISTER_MAP_WITH_PROGRAMSTATE(UvQueueWorkMap, StringWarpper, - UvQueueWorkCallBackState) - -// Constructor -NapiScopeManagerChecker::NapiScopeManagerChecker() - : OpenHandleScope("napi_open_handle_scope", NAPI_SCOPE_AYGS_NUM), - CloseHandleScope("napi_close_handle_scope", NAPI_SCOPE_AYGS_NUM) { - // Initialize the bug types. - DoubleCloseBugType.reset(new BugType(this, "Double close 'napi_handle_scope'", - "OHOS Napi API Error")); - - LeakBugType.reset(new BugType(this, "Resource 'napi_handle_scope' Leaked", - "OHOS Napi API Error", - /*SuppressOnSink=*/false)); - - UvLeakBugType.reset(new BugType( - this, "The callback of uv_queue_work no use 'napi_handle_scope'", - "OHOS Napi API Error")); -} - -// Determine whether napi_handle_scope memory leak -bool NapiScopeManagerChecker::isLeaked(SymbolRef Sym, - const NapiScopeManagerState &SS, - bool IsSymDead, - ProgramStateRef State) const { - if (IsSymDead && SS.isOpened()) { - ConstraintManager &CMgr = State->getConstraintManager(); - ConditionTruthVal OpenFailed = CMgr.isNull(State, Sym); - return !OpenFailed.isConstrainedTrue(); - } - return false; -} - -// A callback function that determines whether it is uv_queue_work and stores -// the status in Map -void NapiScopeManagerChecker::UvCallbackDetect(CheckerContext &C, - const bool &isBegin) const { - const FunctionDecl *checkFun = - C.getCurrentAnalysisDeclContext()->getDecl()->getAsFunction(); - if (checkFun->getNumParams() != UV_QUEUE_WORK_CALLBACK_AYGS_NUM) { - return; - } - std::string param1Type = - checkFun->getParamDecl(0)->getOriginalType().getAsString(); - std::string param2Type = - checkFun->getParamDecl(1)->getOriginalType().getAsString(); - if (param1Type != "uv_work_t *") { - return; - } - if ((param2Type != "int32_t" && param2Type != "int")) { - return; - } - - ProgramStateRef State = C.getState(); - StringWarpper FunName = StringWarpper(checkFun->getNameAsString()); - if (isBegin) { - State = State->set( - FunName, UvQueueWorkCallBackState::getDangerous()); - } else { - State = State->remove(FunName); - } - C.addTransition(State); -} - -// A callback before the function is executed to track the -// napi_close_handle_scope -void NapiScopeManagerChecker::checkPreCall(const CallEvent &Call, - CheckerContext &C) const { - if (!Call.isCalled(this->CloseHandleScope)) { - return; - } - ProgramStateRef State = C.getState(); - SymbolRef Napisym = Call.getArgSVal(NAPI_SCOPE_HANDLE_POS).getAsSymbol(); - if (!Napisym) { - return; - } - - const NapiScopeManagerState *NS = State->get(Napisym); - if (!NS) { - return; - } - - if (NS->isClosed()) { - reportDoubleClose(Napisym, Call, C); - return; - } - - State = - State->set(Napisym, NapiScopeManagerState::getClosed()); - C.addTransition(State); -} - -// A callback after the function is executed to track the napi_open_handle_scope -void NapiScopeManagerChecker::checkPostCall(const CallEvent &Call, - CheckerContext &C) const { - if (!Call.isCalled(this->OpenHandleScope)) { - return; - } - ProgramStateRef State = C.getState(); - UvQueueWorkMapTy CBS = State->get(); - if (CBS.isEmpty()) - return; - for (auto cb : CBS) { - if (cb.second.isDangerous()) { - State = State->set(cb.first, - UvQueueWorkCallBackState::getSafe()); - } - } - - SVal ScopeSVal = Call.getArgSVal(NAPI_SCOPE_HANDLE_POS); - Optional X = ScopeSVal.getAs(); - StoreManager &SM = C.getStoreManager(); - SymbolRef NapiSym = SM.getBinding(State->getStore(), *X).getAsLocSymbol(); - if (!NapiSym) { - return; - } - - State = - State->set(NapiSym, NapiScopeManagerState::getOpened()); - - SVal StatusVal = Call.getReturnValue(); - Optional Dval = StatusVal.getAs(); - if (!Dval) { - return; - } - State = State->assume(*Dval, false); - C.addTransition(State); -} - -// A callbacks for symbol death, determine whether the scope has died -void NapiScopeManagerChecker::checkDeadSymbols(SymbolReaper &SymReaper, - CheckerContext &C) const { - ProgramStateRef State = C.getState(); - SymbolVector LeakedStreams; - HandleScopeMapTy TrackedStreams = State->get(); - for (HandleScopeMapTy::iterator I = TrackedStreams.begin(), - E = TrackedStreams.end(); - I != E; ++I) { - SymbolRef Sym = I->first; - - bool IsSymDead = SymReaper.isDead(Sym); - - if (isLeaked(Sym, I->second, IsSymDead, State)) { - LeakedStreams.push_back(Sym); - } - - if (IsSymDead) { - State = State->remove(Sym); - } - } - - ExplodedNode *N = C.generateNonFatalErrorNode(State); - if (!N) { - return; - } - reportLeaks(LeakedStreams, C, N); -} - -// A callback from which the function starts, which tracks the start of the -// callback function of uv_queue_work -void NapiScopeManagerChecker::checkBeginFunction(CheckerContext &C) const { - UvCallbackDetect(C, true); -} - -// A callback from which the function ends, which tracks the end of the callback function of -// uv_queue_work -void NapiScopeManagerChecker::checkEndFunction(const ReturnStmt *RS, - CheckerContext &C) const { - UvCallbackDetect(C, false); -} - -// A callback before the declaration statement is used to capture the JSValue -// declaration -void NapiScopeManagerChecker::checkPreStmt(const DeclStmt *DS, - CheckerContext &C) const { - ProgramStateRef State = C.getState(); - UvQueueWorkMapTy CBS = State->get(); - if (CBS.isEmpty()) { - return; - } - - if (!DS->isSingleDecl()) { - return; - } - - const VarDecl *VD = dyn_cast(DS->getSingleDecl()); - if (!VD) { - return; - } - - const std::string DeclType = VD->getType().getAsString(); - if (DeclType.find("napi_value") == std::string::npos) { - return; - } - - for (auto cb : CBS) { - if (cb.second.isDangerous()) { - - reportUvCallBackLeaks(C, DS->getSourceRange()); - } - } -} - -// Report if the scope is open but not closed -void NapiScopeManagerChecker::reportLeaks(ArrayRef LeakedStreams, - CheckerContext &C, - ExplodedNode *ErrNode) const { - for (SymbolRef LeakedStream : LeakedStreams) { - auto R = std::make_unique( - *LeakBugType, "Opened Napi is never closed; potential resource leak", - ErrNode); - R->markInteresting(LeakedStream); - C.emitReport(std::move(R)); - } -} - -// Report if the scope is double closed -void NapiScopeManagerChecker::reportDoubleClose(SymbolRef NapiSym, - const CallEvent &Call, - CheckerContext &C) const { - ExplodedNode *ErrNode = C.generateErrorNode(C.getState()); - if (!ErrNode) { - return; - } - - auto R = std::make_unique( - *DoubleCloseBugType, "Closing a previously closed napi_handle_scope", - ErrNode); - R->addRange(Call.getSourceRange()); - R->markInteresting(NapiSym); - C.emitReport(std::move(R)); -} - -// Report if the callback of uv_queue_work use JSValue but no use napi_handle_scope -void NapiScopeManagerChecker::reportUvCallBackLeaks( - CheckerContext &C, const SourceRange &SR) const { - ExplodedNode *ErrNode = C.generateNonFatalErrorNode(C.getState()); - if (!ErrNode) { - return; - } - - auto R = std::make_unique( - *UvLeakBugType, - "Illegal access to JSValue, access to JSValue must be within the napi " - "handle scope", - ErrNode); - R->addRange(SR); - C.emitReport(std::move(R)); -} - -void ento::registerNapiScopeManagerChecker(CheckerManager &mgr) { - mgr.registerChecker(); -} - -bool ento::shouldRegisterNapiScopeManagerChecker(const CheckerManager &mgr) { - return true; -} \ No newline at end of file diff --git a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiWrapParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiWrapParamChecker.cpp deleted file mode 100644 index ed44205e7600..000000000000 --- a/clang/lib/StaticAnalyzer/Checkers/OpenHarmony/NapiWrapParamChecker.cpp +++ /dev/null @@ -1,100 +0,0 @@ -//== NapiWrapParamChecker.cpp ------------------------------*- C++ -*--==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines NapiWrapParamChecker, which is a path-sensitive check -// looking for the function return args is not null. -// -//===----------------------------------------------------------------------===// - -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" - -using namespace clang; -using namespace ento; -namespace { - -// Checker class -class NapiWrapParamChecker : public Checker { - // Constant definitions - constexpr static int NAPI_WRAP_AYGS_NUM = 6; - constexpr static int LAST_ARG_POS = 5; - - // Function wrapper class definitions - CallDescription NapiWrap; - - // BugType definitions - std::unique_ptr LastParamNotNullBugType; - - // Report warning function - void reportParamNotNull(const CallEvent &Call, CheckerContext &C, - const SymbolRef NapiSym) const; - -public: - NapiWrapParamChecker(); - - // Checker function - void checkPreCall(const CallEvent &Call, CheckerContext &C) const; -}; - -} // end anonymous namespace - -// Constructor -NapiWrapParamChecker::NapiWrapParamChecker() - : NapiWrap("napi_wrap", NAPI_WRAP_AYGS_NUM) { - // Initialize the bug types. - LastParamNotNullBugType.reset(new BugType( - this, "last parameter of 'napi_wrap' not null", "OHOS Napi API Error")); -} - -// A callback before the function is executed to track napi_wrap -void NapiWrapParamChecker::checkPreCall(const CallEvent &Call, - CheckerContext &C) const { - if (!Call.isCalled(this->NapiWrap)) { - return; - } - ProgramStateRef State = C.getState(); - SVal S = Call.getArgSVal(LAST_ARG_POS); - Optional NapiSVal = S.getAs(); - if (!NapiSVal) { - return; - } - ConditionTruthVal Nullness = State->isNull(*NapiSVal); - if (Nullness.isConstrainedFalse()) { - reportParamNotNull(Call, C, S.getAsSymbol()); - } -} - -// Report if the third args of napi_wrap is not null -void NapiWrapParamChecker::reportParamNotNull(const CallEvent &Call, - CheckerContext &C, - const SymbolRef NapiSym) const { - ExplodedNode *ErrNode = C.generateNonFatalErrorNode(C.getState()); - if (!ErrNode) { - return; - } - - auto R = std::make_unique( - *LastParamNotNullBugType, "The last parameter of napi_wrap is not null", - ErrNode); - R->addRange(Call.getSourceRange()); - R->markInteresting(NapiSym); - C.emitReport(std::move(R)); -} - -void ento::registerNapiWrapParamChecker(CheckerManager &mgr) { - mgr.registerChecker(); -} - -bool ento::shouldRegisterNapiWrapParamChecker(const CheckerManager &mgr) { - return true; -} \ No newline at end of file diff --git a/clang/test/Analysis/napi_get_arraybuffer_info_test.cpp b/clang/test/Analysis/napi_get_arraybuffer_info_test.cpp deleted file mode 100644 index 41a2e7311978..000000000000 --- a/clang/test/Analysis/napi_get_arraybuffer_info_test.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "napi_include.h" -#include -#include - -void test_bad_case_1() { - napi_env env = nullptr; - napi_value Args = nullptr; - void *data = nullptr; - size_t len = 0; - napi_get_arraybuffer_info(env, Args, &data, &len); - delete data; -} - -void test_bad_case_2() { - napi_env env = nullptr; - napi_value Args = nullptr; - void *data = nullptr; - size_t len = 0; - napi_get_arraybuffer_info(env, Args, &data, &len); - free(data); -} - -void test_good_case_1() { - napi_env env = nullptr; - napi_value Args = nullptr; - void *data = nullptr; - size_t len = 0; - napi_get_arraybuffer_info(env, Args, &data, &len); -} diff --git a/clang/test/Analysis/napi_handle_scope_test.cpp b/clang/test/Analysis/napi_handle_scope_test.cpp deleted file mode 100644 index 5492bd71cb92..000000000000 --- a/clang/test/Analysis/napi_handle_scope_test.cpp +++ /dev/null @@ -1,172 +0,0 @@ -#include "napi_include.h" - -void test_bad_case_1() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_value jsCallback = nullptr; - jsCallback = 0; - delete work; - }); -} - -void test_bad_case_2() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_value args[1] = {nullptr}; - args[0] = 0; - delete work; - }); -} - -void test_bad_case_3() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_env env_ = nullptr; - napi_handle_scope scope = nullptr; - napi_open_handle_scope(env_, &scope); - napi_value jsCallback = nullptr; - jsCallback = 0; - delete work; - }); -} - -void test_bad_case_4() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_env env_ = nullptr; - napi_handle_scope scope = nullptr; - napi_open_handle_scope(env_, &scope); - napi_value args[1] = {nullptr}; - args[0] = 0; - delete work; - }); -} - -void test_bad_case_5() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_env env_ = nullptr; - napi_handle_scope scope = nullptr; - napi_open_handle_scope(env_, &scope); - delete work; - }); -} - -void test_bad_case_6() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_env env_ = nullptr; - napi_handle_scope scope = nullptr; - napi_open_handle_scope(env_, &scope); - napi_value jsCallback = nullptr; - jsCallback = 0; - napi_close_handle_scope(env_, scope); - napi_close_handle_scope(env_, scope); - delete work; - }); -} - -void test_bad_case_7() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_env env_ = nullptr; - napi_handle_scope scope = nullptr; - napi_open_handle_scope(env_, &scope); - napi_value args[1] = {nullptr}; - args[0] = 0; - napi_close_handle_scope(env_, scope); - napi_close_handle_scope(env_, scope); - delete work; - }); -} - -void test_good_case_1() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_env env_ = nullptr; - napi_handle_scope scope = nullptr; - napi_open_handle_scope(env_, &scope); - napi_value jsCallback = nullptr; - jsCallback = 0; - napi_close_handle_scope(env_, scope); - delete work; - }); -} - -void test_good_case_2() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_env env_ = nullptr; - napi_handle_scope scope = nullptr; - napi_open_handle_scope(env_, &scope); - napi_value args[1] = {nullptr}; - args[0] = 0; - napi_close_handle_scope(env_, scope); - delete work; - }); -} - -void test_good_case_3() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_env env_ = nullptr; - napi_handle_scope scope = nullptr; - napi_status stat = napi_open_handle_scope(env_, &scope); - if (stat != napi_ok) { - return; - } - napi_value args[1] = {nullptr}; - args[0] = 0; - napi_close_handle_scope(env_, scope); - delete work; - }); -} - -void test_good_case_4() { - uv_loop_s *loop = nullptr; - uv_work_t *work = new uv_work_t; - uv_queue_work( - loop, work, [](uv_work_t *work) {}, - [](uv_work_t *work, int status) { - napi_env env_ = nullptr; - napi_handle_scope scope = nullptr; - napi_open_handle_scope(env_, &scope); - if (scope == nullptr) { - return; - } - napi_value args[1] = {nullptr}; - args[0] = 0; - napi_close_handle_scope(env_, scope); - delete work; - }); -} \ No newline at end of file diff --git a/clang/test/Analysis/napi_include.h b/clang/test/Analysis/napi_include.h deleted file mode 100644 index dcac71463f38..000000000000 --- a/clang/test/Analysis/napi_include.h +++ /dev/null @@ -1,84 +0,0 @@ -#include - -typedef struct napi_env__* napi_env; -typedef struct napi_value__* napi_value; -typedef struct napi_ref__* napi_ref; -typedef struct napi_handle_scope__* napi_handle_scope; - -typedef enum { - napi_ok, - napi_invalid_arg, - napi_object_expected, - napi_string_expected, - napi_name_expected, - napi_function_expected, - napi_number_expected, - napi_boolean_expected, - napi_array_expected, - napi_generic_failure, - napi_pending_exception, - napi_cancelled, - napi_escape_called_twice, - napi_handle_scope_mismatch, - napi_callback_scope_mismatch, - napi_queue_full, - napi_closing, - napi_bigint_expected, - napi_date_expected, - napi_arraybuffer_expected, - napi_detachable_arraybuffer_expected, - napi_would_deadlock // unused -} napi_status; - -typedef void (*napi_finalize)(napi_env env, - void* finalize_data, - void* finalize_hint); - -napi_status napi_wrap(napi_env env, - napi_value js_object, - void* native_object, - napi_finalize finalize_cb, - void* finalize_hint, - napi_ref* result); - -napi_status napi_open_handle_scope(napi_env env, - napi_handle_scope* result); -napi_status napi_close_handle_scope(napi_env env, - napi_handle_scope scope); -napi_status napi_get_arraybuffer_info(napi_env env, - napi_value arraybuffer, - void** data, - size_t* byte_length); - - - - -typedef struct uv_loop_s uv_loop_t; -typedef struct uv_work_s uv_work_t; -typedef void (*uv_work_cb)(uv_work_t* req); -typedef void (*uv_after_work_cb)(uv_work_t* req, int status); -struct uv_work_s { - uv_loop_t* loop; - uv_work_cb work_cb; - uv_after_work_cb after_work_cb; -}; - - int uv_queue_work(uv_loop_t* loop, - uv_work_t* req, - uv_work_cb work_cb, - uv_after_work_cb after_work_cb); -struct uv_loop_s { - /* User data - use this for whatever. */ - void* data; - /* Loop reference counting. */ - unsigned int active_handles; - void* handle_queue[2]; - union { - void* unused; - unsigned int count; - } active_reqs; - /* Internal storage for future extensions. */ - void* internal_fields; - /* Internal flag to signal loop stop. */ - unsigned int stop_flag; -}; diff --git a/clang/test/Analysis/napi_wrap_test.cpp b/clang/test/Analysis/napi_wrap_test.cpp deleted file mode 100644 index 1327684284c2..000000000000 --- a/clang/test/Analysis/napi_wrap_test.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "napi_include.h" - -void test_bad_case_1() { - napi_env env = nullptr; - napi_value thisArg = nullptr; - void* cbInfo = nullptr; - napi_ref* res = new napi_ref[5]; - napi_wrap(env, thisArg, cbInfo, [](napi_env env, void* data, void* hint) {}, nullptr, res); -} - -void test_good_case_1() { - napi_env env = nullptr; - napi_value thisArg = nullptr; - void* cbInfo = nullptr; - napi_wrap(env, thisArg, cbInfo, [](napi_env env, void* data, void* hint) {}, nullptr, nullptr); -} \ No newline at end of file -- Gitee