Что происходит, я читаю пакеты шифрования, и я сталкиваюсь с поврежденным пакетом, который возвращает очень большое случайное число для длины.Функция 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 слишком велика из-за поврежденного пакета данных, поэтому функция изменения размера выбрасывает. Проблема заключается не в том, что resize throws (мы обрабатываем исключения), но этот размер имеет поврежденную память уже, и это приводит к большим исключениям позже.
Что я хочу сделать, это знать, если длина слишком велика до того, как я выберу изменение размера, тогда вызывается только изменение размера, если это нормально. Я попытался поставить этот код перед вызовом, чтобы изменить размер:
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);
Этот код использует зЬй :: функции члена вектор max_size, чтобы проверить, если nLengthRemaining больше. Это не должно быть надежным, потому что nLengthRemaining все еще меньше nMaxSize, но, по-видимому, все еще достаточно большой, чтобы вызвать изменение размера (nMaxSize было 4xxxxxxxxx, а nLengthRemaining - 3xxxxxxxxx).
Кроме того, я не определяю, что выбрасывает изменение размера. Это не std :: length_error, и это не std :: bad_alloc. Какое исключение это бросание действительно не слишком важно для меня, но мне любопытно узнать.
Кстати, именно так вы знаете, этот код действительно работает правильно в обычных случаях. Этот случай поврежденного пакета данных является единственным местом, где он сходит с ума. Пожалуйста помоги! Благодарю.
ОБНОВЛЕНИЕ:
@Michael. Пока я просто проигнорирую пакет, если он больше 5 МБ. Я буду обсуждать с другими членами команды вопрос о возможности проверки пакетов (возможно, он уже существует, и я просто этого не знаю). Я начинаю думать, что это действительно ошибка в нашей версии STL, исключение, которое она бросает, - это даже не исключение std :: exception, которое меня удивило. Я попытаюсь выяснить у моего руководителя, какую версию STL мы запускаем (как бы проверить?).
ДРУГОЕ ОБНОВЛЕНИЕ: Я просто докажу, что это ошибка в версии STL, которую я использую на моей машине разработки Visual Studio 6. Я написал это примерное приложение:
// 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 Sport NCAA футбол хе-хе!
На какой платформе вы работаете? – sbi
Мне любопытно, какую версию компилятора/stl вы используете. Реализации, к которым у меня есть доступ, не приведут к повреждению векторного объекта, если сбой распределения. – jmucchiello
@cchampion: «На моей машине VS6 dev ...» Если бы вы сказали это раньше, мы бы не потратили столько времени на это. Это более чем 10-летняя технология! Конечно, это багги. См. Мой ответ. – sbi