發生了什麼是我正在讀取加密數據包,並且我遇到了一個損壞的數據包,它給出了一個長度非常大的隨機數。vector.resize函數在尺寸太大時破壞內存
size_t nLengthRemaining = packet.nLength - (packet.m_pSource->GetPosition() - packet.nDataOffset);
seckey.SecretValues.m_data.resize(nLengthRemaining);
在此代碼中,m_data是std::vector<unsigned char>
。由於數據包損壞,nLengthRemaining過大,因此調整大小功能。問題不是調整大小拋出(我們處理異常),但調整大小已經損壞了內存,這導致更多的例外。
我想要做的是知道在調用調整大小之前長度是否過大,如果沒有問題,只調用調整大小。我試圖把這個代碼的調用之前調整:
std::vector<unsigned char>::size_type nMaxSize = seckey.SecretValues.m_data.max_size();
if(seckey.SecretValues.m_data.size() + nLengthRemaining >= nMaxSize) {
throw IHPGP::PgpException("corrupted packet: length too big.");
}
seckey.SecretValues.m_data.resize(nLengthRemaining);
該代碼使用的std ::向量MAX_SIZE成員函數測試是否nLengthRemaining較大。儘管如此,nLengthRemaining仍然小於nMaxSize,但顯然仍然足以導致調整大小以產生問題(nMaxSize爲4xxxxxxxxx,nLengthRemaining爲3xxxxxxxxx),但這一定不可靠。
此外,我還沒有確定調整大小拋出什麼異常。它不是一個std :: length_error,它不是一個std :: bad_alloc。它拋出的異常對我來說並不重要,但我很想知道。
順便說一句,只是你知道,這段代碼在正常情況下確實能正常工作。這種數據包被破壞的情況是唯一一個瘋狂的地方。請幫忙!謝謝。
更新:
@Michael。現在,如果數據包大於5 MB,我會忽略它。我將與其他團隊成員討論可能驗證數據包(它可能已經在那裏,我只是不知道它)。我開始認爲它確實是我們STL版本中的一個bug,它拋出的異常甚至不是std :: exception,這讓我感到驚奇。我會試着從我的主管那裏瞭解我們正在運行的STL版本(我將如何檢查?)。
其他更新: 我只是證明它是我在Visual Studio 6開發機器上使用的STL版本中的一個錯誤。我寫了這個示例應用程序:
// VectorMaxSize.cpp:定義控制檯應用程序的入口點。 //
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <math.h>
#include <typeinfo>
typedef std::vector<unsigned char> vector_unsigned_char;
void fill(vector_unsigned_char& v) {
for (int i=0; i<100; i++) v.push_back(i);
}
void oput(vector_unsigned_char& v) {
std::cout << "size: " << v.size() << std::endl;
std::cout << "capacity: " << v.capacity() << std::endl;
std::cout << "max_size: " << v.max_size() << std::endl << std::endl;
}
void main(int argc, char* argv[]) {
{
vector_unsigned_char v;
fill(v);
try{
v.resize(static_cast<size_t>(3555555555));
}catch(std::bad_alloc&) {
std::cout << "caught bad alloc exception" << std::endl;
}catch(const std::exception& x) {
std::cerr << typeid(x).name() << std::endl;
}catch(...) {
std::cerr << "unknown exception" << std::endl;
}
oput(v);
v.reserve(500);
oput(v);
v.resize(500);
oput(v);
}
std::cout << "done" << std::endl;
}
在我VS6 dev的機器它具有相同的行爲具有加密項目,它會導致各種混亂的。當我在Visual Studio 2008機器上構建並運行它時,調整大小會拋出std :: bad_alloc異常,並且矢量不會被破壞,就像我們預期的那樣!時間爲一些EA體育NCAA橄欖球呵呵!
你在哪個平臺上? – sbi 2009-10-23 20:51:23
我很好奇你使用的是什麼編譯器/ stl版本。如果分配失敗,我有權訪問的實現不會損壞矢量對象。 – jmucchiello 2009-10-23 21:34:57
@cchampion:「在我的VS6開發機器上......」如果你早些時候說過,我們不會浪費這麼多時間。這是超過10年的技術!當然,它是越野車。看到我的答案。 – sbi 2009-10-25 12:15:09