正在发生的是我正在读取加密数据包,遇到一个损坏的数据包,长度返回了一个非常大的随机数。
size_t nLengthRemaining = packet.nLength - (packet.m_pSource->GetPosition() - packet.nDataOffset);
seckey.SecretValues.m_data.resize(nLengthRemaining);
在这段代码中,m_data是一个
std::vector<unsigned char>
。由于数据包已损坏,nLengthRemaining过大,因此resize函数会抛出异常。问题不在于resize函数会抛出异常(我们处理了异常),而是resize函数已经破坏了内存,这会导致后面出现更多的异常。我想要做的是,在调用resize之前知道长度是否过大,只有当它是可行的时候才调用resize。我尝试在调用resize之前放置以下代码:
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::vector的max_size成员函数来测试nLengthRemaining是否更大。但这可能不可靠,因为nLengthRemaining仍然小于nMaxSize,但显然足够大以导致resize出现问题(nMaxSize为4xxxxxxxxx,nLengthRemaining为3xxxxxxxxx)。
此外,我还没有确定resize抛出的异常。它既不是std::length_error也不是std::bad_alloc。它抛出的异常对我来说并不太重要,但我很好奇。
顺便说一下,你需要知道,这段代码在正常情况下可以正确工作。只有在数据包损坏的情况下才会出现问题。请帮帮我!谢谢。
更新:
@Michael。现在,如果数据包大于5 MB,我将忽略它。我将与其他团队成员讨论可能验证数据包的方法(可能已经存在,而我只是不知道)。我开始认为这确实是我们版本的STL中的一个错误,它抛出的异常甚至不是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开发机上,它的行为和加密项目一样,会引起各种混乱。当我在Visual Studio 2008机器上构建和运行它时,调整大小会抛出std::bad_alloc异常,而向量不会被破坏,正如我们所期望的那样!是时候玩一些EA Sport NCAA足球了,哈哈!
<xmemory>
头文件中(但不是Dunkumware VC错误页面上讨论的那个)。 - Michael Burr