[devel] [PATCH for apt v2 13/21] Cacheiterators: sanitize increment operators and end() function

Aleksei Nikiforov darktemplar на altlinux.org
Чт Дек 12 12:57:22 MSK 2019


Make sure that these functions work properly even for default-constructed objects.
Found via clang-static-analyzer during investigation of:
API: Argument with 'nonnull' attribute passed null:
Null pointer passed as an argument to a 'nonnull' parameter
---
 apt/apt-pkg/cacheiterators.h | 22 +++++++++++-----------
 apt/apt-pkg/pkgcache.cc      |  3 +++
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/apt/apt-pkg/cacheiterators.h b/apt/apt-pkg/cacheiterators.h
index bad1e11..a4bf670 100644
--- a/apt/apt-pkg/cacheiterators.h
+++ b/apt/apt-pkg/cacheiterators.h
@@ -60,7 +60,7 @@ class pkgCache::PkgIterator
    // Iteration
    void operator ++(int);
    inline void operator ++() {operator ++(0);};
-   inline bool end() const {return Owner == 0 || Pkg == Owner->PkgP?true:false;};
+   inline bool end() const {return (Owner == 0 || Pkg == 0 || Pkg == Owner->PkgP);};
 
    // Comparison
    inline bool operator ==(const PkgIterator &B) const {return Pkg == B.Pkg;};
@@ -113,9 +113,9 @@ class pkgCache::VerIterator
    public:
 
    // Iteration
-   void operator ++(int) {if (Ver != Owner->VerP) Ver = Owner->VerP + Ver->NextVer;};
+   void operator ++(int) {if ((Owner != NULL) && (Ver != NULL) && (Ver != Owner->VerP)) Ver = Owner->VerP + Ver->NextVer;};
    inline void operator ++() {operator ++(0);};
-   inline bool end() const {return Ver == Owner->VerP?true:false;};
+   inline bool end() const {return (Owner == NULL || Ver == NULL || Ver == Owner->VerP);};
    inline void operator =(const VerIterator &B) {Ver = B.Ver; Owner = B.Owner;};
    
    // Comparison
@@ -175,10 +175,10 @@ class pkgCache::DepIterator
    public:
 
    // Iteration
-   void operator ++(int) {if (Dep != Owner->DepP) Dep = Owner->DepP +
+   void operator ++(int) {if ((Owner != NULL) && (Dep != NULL) && (Dep != Owner->DepP)) Dep = Owner->DepP +
 	(Type == DepVer?Dep->NextDepends:Dep->NextRevDepends);};
    inline void operator ++() {operator ++(0);};
-   inline bool end() const {return Owner == 0 || Dep == Owner->DepP?true:false;};
+   inline bool end() const {return (Owner == 0 || Dep == 0 || Dep == Owner->DepP);};
    
    // Comparison
    inline bool operator ==(const DepIterator &B) const {return Dep == B.Dep;};
@@ -254,10 +254,10 @@ class pkgCache::PrvIterator
    public:
 
    // Iteration
-   void operator ++(int) {if (Prv != Owner->ProvideP) Prv = Owner->ProvideP +
+   void operator ++(int) {if ((Owner != NULL) && (Prv != NULL) && (Prv != Owner->ProvideP)) Prv = Owner->ProvideP +
 	(Type == PrvVer?Prv->NextPkgProv:Prv->NextProvides);};
    inline void operator ++() {operator ++(0);};
-   inline bool end() const {return Prv == Owner->ProvideP?true:false;};
+   inline bool end() const {return (Owner == NULL || Prv == NULL || Prv == Owner->ProvideP);};
    
    // Comparison
    inline bool operator ==(const PrvIterator &B) const {return Prv == B.Prv;};
@@ -311,9 +311,9 @@ class pkgCache::PkgFileIterator
    public:
 
    // Iteration
-   void operator ++(int) {if (File!= Owner->PkgFileP) File = Owner->PkgFileP + File->NextFile;};
+   void operator ++(int) {if ((Owner != NULL) && (File != NULL) && (File!= Owner->PkgFileP)) File = Owner->PkgFileP + File->NextFile;};
    inline void operator ++() {operator ++(0);};
-   inline bool end() const {return File == Owner->PkgFileP?true:false;};
+   inline bool end() const {return (Owner == NULL || File == NULL || File == Owner->PkgFileP);};
 
    // Comparison
    inline bool operator ==(const PkgFileIterator &B) const {return File == B.File;};
@@ -364,9 +364,9 @@ class pkgCache::VerFileIterator
    public:
 
    // Iteration
-   void operator ++(int) {if (FileP != Owner->VerFileP) FileP = Owner->VerFileP + FileP->NextFile;};
+   void operator ++(int) {if ((Owner != NULL) && (FileP != NULL) && (FileP != Owner->VerFileP)) FileP = Owner->VerFileP + FileP->NextFile;};
    inline void operator ++() {operator ++(0);};
-   inline bool end() const {return FileP == Owner->VerFileP?true:false;};
+   inline bool end() const {return (Owner == NULL || FileP == NULL || FileP == Owner->VerFileP);};
 
    // Comparison
    inline bool operator ==(const VerFileIterator &B) const {return FileP == B.FileP;};
diff --git a/apt/apt-pkg/pkgcache.cc b/apt/apt-pkg/pkgcache.cc
index afefe3b..9965532 100644
--- a/apt/apt-pkg/pkgcache.cc
+++ b/apt/apt-pkg/pkgcache.cc
@@ -275,6 +275,9 @@ void pkgCache::PrvIterator::_dummy() {}
 /* This will advance to the next logical package in the hash table. */
 void pkgCache::PkgIterator::operator ++(int) 
 {
+   if ((Owner == NULL) || (Pkg == NULL))
+      return;
+
    // Follow the current links
    if (Pkg != Owner->PkgP)
       Pkg = Owner->PkgP + Pkg->NextPackage;
-- 
2.24.1



Подробная информация о списке рассылки Devel