Sfoglia il codice sorgente

Merge branch 'bugfix/nvs_no_throw' into 'release/v4.0'

NVS: Changed all new to new (nothrow) (backport v4.0)

See merge request espressif/esp-idf!7847
Ivan Grokhotkov 5 anni fa
parent
commit
c8a05bae78

+ 11 - 2
components/nvs_flash/src/nvs_api.cpp

@@ -105,7 +105,10 @@ extern "C" esp_err_t nvs_flash_init_custom(const char *partName, uint32_t baseSe
     nvs::Storage* new_storage = NULL;
     nvs::Storage* storage = lookup_storage_from_name(partName);
     if (storage == NULL) {
-        new_storage = new nvs::Storage((const char *)partName);
+        new_storage = new (std::nothrow) nvs::Storage((const char *)partName);
+
+        if (!new_storage) return ESP_ERR_NO_MEM;
+
         storage = new_storage;
     }
 
@@ -127,6 +130,9 @@ extern "C" esp_err_t nvs_flash_secure_init_custom(const char *partName, uint32_t
 
     if(cfg) {
         auto encrMgr = EncrMgr::getInstance();
+
+        if (!encrMgr) return ESP_ERR_NO_MEM;
+
         auto err = encrMgr->setSecurityContext(baseSector, sectorCount, cfg);
         if(err != ESP_OK) {
             return err;
@@ -282,7 +288,10 @@ extern "C" esp_err_t nvs_open_from_partition(const char *part_name, const char*
         return err;
     }
 
-    HandleEntry *handle_entry = new HandleEntry(open_mode==NVS_READONLY, nsIndex, sHandle);
+    HandleEntry *handle_entry = new (std::nothrow) HandleEntry(open_mode==NVS_READONLY, nsIndex, sHandle);
+
+    if (!handle_entry) return ESP_ERR_NO_MEM;
+
     s_nvs_handles.push_back(handle_entry);
 
     *out_handle = handle_entry->mHandle;

+ 7 - 3
components/nvs_flash/src/nvs_encr.cpp

@@ -27,8 +27,10 @@ namespace nvs
     {
         if(!isActive)
         {
-            instance = new EncrMgr();
-            isActive = true;
+            instance = new (std::nothrow) EncrMgr();
+            if (instance) {
+                isActive = true;
+            }
         }
         return instance;
     }
@@ -62,7 +64,9 @@ namespace nvs
 
         uint8_t* eky = reinterpret_cast<uint8_t*>(cfg);
 
-        auto ctxt = new XtsCtxt();
+        auto ctxt = new (std::nothrow) XtsCtxt();
+
+        if (!ctxt) return ESP_ERR_NO_MEM;
 
         ctxt->baseSector = baseSector;
         ctxt->sectorCount = sectorCount;

+ 10 - 5
components/nvs_flash/src/nvs_item_hash_list.cpp

@@ -20,7 +20,7 @@ namespace nvs
 HashList::HashList()
 {
 }
-    
+
 void HashList::clear()
 {
     for (auto it = mBlockList.begin(); it != mBlockList.end();) {
@@ -30,7 +30,7 @@ void HashList::clear()
         delete static_cast<HashListBlock*>(tmp);
     }
 }
-    
+
 HashList::~HashList()
 {
     clear();
@@ -42,7 +42,7 @@ HashList::HashListBlock::HashListBlock()
                   "cache block size calculation incorrect");
 }
 
-void HashList::insert(const Item& item, size_t index)
+esp_err_t HashList::insert(const Item& item, size_t index)
 {
     const uint32_t hash_24 = item.calculateCrc32WithoutValue() & 0xffffff;
     // add entry to the end of last block if possible
@@ -50,14 +50,19 @@ void HashList::insert(const Item& item, size_t index)
         auto& block = mBlockList.back();
         if (block.mCount < HashListBlock::ENTRY_COUNT) {
             block.mNodes[block.mCount++] = HashListNode(hash_24, index);
-            return;
+            return ESP_OK;
         }
     }
     // if the above failed, create a new block and add entry to it
-    HashListBlock* newBlock = new HashListBlock;
+    HashListBlock* newBlock = new (std::nothrow) HashListBlock;
+
+    if (!newBlock) return ESP_ERR_NO_MEM;
+
     mBlockList.push_back(newBlock);
     newBlock->mNodes[0] = HashListNode(hash_24, index);
     newBlock->mCount++;
+
+    return ESP_OK;
 }
 
 void HashList::erase(size_t index, bool itemShouldExist)

+ 4 - 4
components/nvs_flash/src/nvs_item_hash_list.hpp

@@ -27,16 +27,16 @@ class HashList
 public:
     HashList();
     ~HashList();
-    
-    void insert(const Item& item, size_t index);
+
+    esp_err_t insert(const Item& item, size_t index);
     void erase(const size_t index, bool itemShouldExist=true);
     size_t find(size_t start, const Item& item);
     void clear();
-    
+
 private:
     HashList(const HashList& other);
     const HashList& operator= (const HashList& rhs);
-    
+
 protected:
 
     struct HashListNode {

+ 7 - 1
components/nvs_flash/src/nvs_ops.cpp

@@ -26,6 +26,9 @@ esp_err_t nvs_flash_write(size_t destAddr, const void *srcAddr, size_t size) {
 
     if(EncrMgr::isEncrActive()) {
         auto encrMgr = EncrMgr::getInstance();
+
+        if (!encrMgr) return ESP_ERR_NO_MEM;
+
         auto xtsCtxt = encrMgr->findXtsCtxtFromAddr(destAddr);
 
         if(xtsCtxt) {
@@ -44,7 +47,7 @@ esp_err_t nvs_flash_write(size_t destAddr, const void *srcAddr, size_t size) {
 }
 
 esp_err_t nvs_flash_read(size_t srcAddr, void *destAddr, size_t size) {
-    
+
     auto err = spi_flash_read(srcAddr, destAddr, size);
 
     if(err != ESP_OK) {
@@ -53,6 +56,9 @@ esp_err_t nvs_flash_read(size_t srcAddr, void *destAddr, size_t size) {
 
     if(EncrMgr::isEncrActive()) {
         auto encrMgr = EncrMgr::getInstance();
+
+        if (!encrMgr) return ESP_ERR_NO_MEM;
+
         auto xtsCtxt = encrMgr->findXtsCtxtFromAddr(srcAddr);
         if(xtsCtxt) {
             return encrMgr->decryptNvsData(static_cast<uint8_t*>(destAddr),

+ 24 - 5
components/nvs_flash/src/nvs_page.cpp

@@ -49,7 +49,10 @@ esp_err_t Page::load(uint32_t sectorNumber)
         // check if the whole page is really empty
         // reading the whole page takes ~40 times less than erasing it
         const int BLOCK_SIZE = 128;
-        uint32_t* block = new uint32_t[BLOCK_SIZE];
+        uint32_t* block = new (std::nothrow) uint32_t[BLOCK_SIZE];
+
+        if (!block) return ESP_ERR_NO_MEM;
+
         for (uint32_t i = 0; i < SPI_FLASH_SEC_SIZE; i += 4 * BLOCK_SIZE) {
             rc = spi_flash_read(mBaseAddress + i, block, 4 * BLOCK_SIZE);
             if (rc != ESP_OK) {
@@ -215,7 +218,11 @@ esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, c
     // write first item
     size_t span = (totalSize + ENTRY_SIZE - 1) / ENTRY_SIZE;
     item = Item(nsIndex, datatype, span, key, chunkIdx);
-    mHashList.insert(item, mNextFreeEntry);
+    err = mHashList.insert(item, mNextFreeEntry);
+
+    if (err != ESP_OK) {
+        return err;
+    }
 
     if (!isVariableLengthType(datatype)) {
         memcpy(item.data, data, dataSize);
@@ -478,7 +485,11 @@ esp_err_t Page::copyItems(Page& other)
             return err;
         }
 
-        other.mHashList.insert(entry, other.mNextFreeEntry);
+        err = other.mHashList.insert(entry, other.mNextFreeEntry);
+        if (err != ESP_OK) {
+            return err;
+        }
+
         err = other.writeEntry(entry);
         if (err != ESP_OK) {
             return err;
@@ -601,7 +612,11 @@ esp_err_t Page::mLoadEntryTable()
                 continue;
             }
 
-            mHashList.insert(item, i);
+            err = mHashList.insert(item, i);
+            if (err != ESP_OK) {
+                mState = PageState::INVALID;
+                return err;
+            }
 
             // search for potential duplicate item
             size_t duplicateIndex = mHashList.find(0, item);
@@ -671,7 +686,11 @@ esp_err_t Page::mLoadEntryTable()
 
             assert(item.span > 0);
 
-            mHashList.insert(item, i);
+            err = mHashList.insert(item, i);
+            if (err != ESP_OK) {
+                mState = PageState::INVALID;
+                return err;
+            }
 
             size_t span = item.span;
 

+ 4 - 2
components/nvs_flash/src/nvs_pagemanager.cpp

@@ -21,7 +21,9 @@ esp_err_t PageManager::load(uint32_t baseSector, uint32_t sectorCount)
     mPageCount = sectorCount;
     mPageList.clear();
     mFreePageList.clear();
-    mPages.reset(new Page[sectorCount]);
+    mPages.reset(new (std::nothrow) Page[sectorCount]);
+
+    if (!mPages) return ESP_ERR_NO_MEM;
 
     for (uint32_t i = 0; i < sectorCount; ++i) {
         auto err = mPages[i].load(baseSector + i);
@@ -85,7 +87,7 @@ esp_err_t PageManager::load(uint32_t baseSector, uint32_t sectorCount)
                     break;
                 }
             }
-        } 
+        }
     }
 
     // check if power went out while page was being freed

+ 33 - 11
components/nvs_flash/src/nvs_storage.cpp

@@ -31,7 +31,7 @@ void Storage::clearNamespaces()
     mNamespaces.clearAndFreeNodes();
 }
 
-void Storage::populateBlobIndices(TBlobIndexList& blobIdxList)
+esp_err_t Storage::populateBlobIndices(TBlobIndexList& blobIdxList)
 {
     for (auto it = mPageManager.begin(); it != mPageManager.end(); ++it) {
         Page& p = *it;
@@ -43,7 +43,9 @@ void Storage::populateBlobIndices(TBlobIndexList& blobIdxList)
          * duplicate index at this point */
 
         while (p.findItem(Page::NS_ANY, ItemType::BLOB_IDX, nullptr, itemIndex, item) == ESP_OK) {
-            BlobIndexNode* entry = new BlobIndexNode;
+            BlobIndexNode* entry = new (std::nothrow) BlobIndexNode;
+
+            if (!entry) return ESP_ERR_NO_MEM;
 
             item.getKey(entry->key, sizeof(entry->key) - 1);
             entry->nsIndex = item.nsIndex;
@@ -54,6 +56,8 @@ void Storage::populateBlobIndices(TBlobIndexList& blobIdxList)
             itemIndex += item.span;
         }
     }
+
+    return ESP_OK;
 }
 
 void Storage::eraseOrphanDataBlobs(TBlobIndexList& blobIdxList)
@@ -100,7 +104,13 @@ esp_err_t Storage::init(uint32_t baseSector, uint32_t sectorCount)
         size_t itemIndex = 0;
         Item item;
         while (p.findItem(Page::NS_INDEX, ItemType::U8, nullptr, itemIndex, item) == ESP_OK) {
-            NamespaceEntry* entry = new NamespaceEntry;
+            NamespaceEntry* entry = new (std::nothrow) NamespaceEntry;
+
+            if (!entry) {
+                mState = StorageState::INVALID;
+                return ESP_ERR_NO_MEM;
+            }
+
             item.getKey(entry->mName, sizeof(entry->mName) - 1);
             item.getValue(entry->mIndex);
             mNamespaces.push_back(entry);
@@ -114,7 +124,11 @@ esp_err_t Storage::init(uint32_t baseSector, uint32_t sectorCount)
 
     // Populate list of multi-page index entries.
     TBlobIndexList blobIdxList;
-    populateBlobIndices(blobIdxList);
+    err = populateBlobIndices(blobIdxList);
+    if (err != ESP_OK) {
+        mState = StorageState::INVALID;
+        return ESP_ERR_NO_MEM;
+    }
 
     // Remove the entries for which there is no parent multi-page index.
     eraseOrphanDataBlobs(blobIdxList);
@@ -182,7 +196,7 @@ esp_err_t Storage::writeMultiPageBlob(uint8_t nsIndex, const char* key, const vo
                 return err;
             } else if(getCurrentPage().getVarDataTailroom() == tailroom) {
                 /* We got the same page or we are not improving.*/
-                return ESP_ERR_NVS_NOT_ENOUGH_SPACE; 
+                return ESP_ERR_NVS_NOT_ENOUGH_SPACE;
             } else {
                 continue;
             }
@@ -203,7 +217,11 @@ esp_err_t Storage::writeMultiPageBlob(uint8_t nsIndex, const char* key, const vo
         if (err != ESP_OK) {
             break;
         } else {
-            UsedPageNode* node = new UsedPageNode();
+            UsedPageNode* node = new (std::nothrow) UsedPageNode();
+            if (!node) {
+                err = ESP_ERR_NO_MEM;
+                break;
+            }
             node->mPage = &page;
             usedPages.push_back(node);
             if (remainingSize || (tailroom - chunkSize) < Page::ENTRY_SIZE) {
@@ -308,9 +326,9 @@ esp_err_t Storage::writeItem(uint8_t nsIndex, ItemType datatype, const char* key
             if (err != ESP_OK) {
                 return err;
             }
-            
+
             findPage = nullptr;
-        } else { 
+        } else {
             /* Support for earlier versions where BLOBS were stored without index */
             err = findItem(nsIndex, datatype, key, findPage, item);
             if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) {
@@ -395,6 +413,11 @@ esp_err_t Storage::createOrOpenNamespace(const char* nsName, bool canCreate, uin
             return ESP_ERR_NVS_NOT_ENOUGH_SPACE;
         }
 
+        NamespaceEntry* entry = new (std::nothrow) NamespaceEntry;
+        if (!entry) {
+            return ESP_ERR_NO_MEM;
+        }
+
         auto err = writeItem(Page::NS_INDEX, ItemType::U8, nsName, &ns, sizeof(ns));
         if (err != ESP_OK) {
             return err;
@@ -402,7 +425,6 @@ esp_err_t Storage::createOrOpenNamespace(const char* nsName, bool canCreate, uin
         mNamespaceUsage.set(ns, true);
         nsIndex = ns;
 
-        NamespaceEntry* entry = new NamespaceEntry;
         entry->mIndex = ns;
         strncpy(entry->mName, nsName, sizeof(entry->mName) - 1);
         entry->mName[sizeof(entry->mName) - 1] = 0;
@@ -512,14 +534,14 @@ esp_err_t Storage::readItem(uint8_t nsIndex, ItemType datatype, const char* key,
         if (err != ESP_ERR_NVS_NOT_FOUND) {
             return err;
         } // else check if the blob is stored with earlier version format without index
-    } 
+    }
 
     auto err = findItem(nsIndex, datatype, key, findPage, item);
     if (err != ESP_OK) {
         return err;
     }
     return findPage->readItem(nsIndex, datatype, key, data, dataSize);
-    
+
 }
 
 esp_err_t Storage::eraseMultiPageBlob(uint8_t nsIndex, const char* key, VerOffset chunkStart)

+ 1 - 1
components/nvs_flash/src/nvs_storage.hpp

@@ -134,7 +134,7 @@ protected:
 
     void clearNamespaces();
 
-    void populateBlobIndices(TBlobIndexList&);
+    esp_err_t populateBlobIndices(TBlobIndexList&);
 
     void eraseOrphanDataBlobs(TBlobIndexList&);