повысить сериализацию: посмотреть, хорош ли поток - PullRequest
1 голос
/ 31 октября 2011

В настоящее время я разрабатываю серверное приложение, которое должно получать сериализованные данные от клиентов, десериализовывать их и, наконец, обрабатывать. Сериализованные данные отправляются в виде массива символов. Моя проблема в том, что мое приложение может быть легко взломано путем отправки ему неверных данных. Поэтому я хотел спросить, можно ли проверить строку (-поток) и посмотреть, подходит ли она для (де) сериализации (например, имеет ли она действительную подпись), прежде чем пытаться получить из нее данные.

Кстати: как уже сказано в заголовке, мое приложение использует boost.serialization.

Заранее большое спасибо:)

1 Ответ

0 голосов
/ 31 октября 2011

Я предполагаю, что вы хотите выполнить облегченную проверку, не требуя чтения всех данных (в этом случае обработка исключений настолько эффективна, насколько это возможно).

Я только что проверил успех с помощью этой простой функции:

bool can_deserialize(std::istream& is)
{
    bool ok = false;
    is.seekg(0, std::ios_base::beg);

    try
    {
        boost::archive::binary_iarchive ia(is);
        unsigned test = ia.get_library_version();
        ok = true;
    } catch (...) { }

    is.seekg(0, std::ios_base::beg);
    is.clear();
    return ok;
}

Вот простой тестовый комплект, который я использовал (манипулируя данными в data.bin перед десериализацией для проверки «плохих потоков»):

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <fstream>
#include <iostream>

bool can_deserialize(std::istream& is)
{
    bool ok = false;
    is.seekg(0, std::ios_base::beg);

    try
    {
        boost::archive::binary_iarchive ia(is);
        unsigned test = ia.get_library_version();
        ok = true;
    } catch (...) { }

    is.seekg(0, std::ios_base::beg);
    is.clear();
    return ok;
}

int main()
{
    std::vector<int> data = { 19415, -2611, 12092, -3942, -2535, 12105, 21079, 4660, 3,
        27131, 13647, 24428, 15159, 9029, 24827, -979, 17194, 25102, -3631,
        20914, -3223, 25801, 6652, 26208, -77, 15606, 8764, 1896, 7430, 24323,
        -152, 23805, -4259, 11243, 13367, 23559, 19293, 18581, 1639, 15671,
        7929, 18386, 5168, 13816, 465, 15801, 16750, -3340, -202, 10412, 11068,
        13458, 24304, 14814, 6530, 1178, -974, 12882, 757, 583, 4897, 24541,
        12490, -119, 2240, -4833, 569, 24700, 24522, 8708, 9760, 26837, 26060,
        20914, -3223, 25801, 6652, 26208, -77, 15606, 8764, 1896, 7430, 24323,
        3377, 6972, 25689, 2334, 1567, 21670, 23233, 14711, 4650, -4703, 25057,
        16057, 19488, 14575, 18936, 13346, 2779, 5644, 17165, 4526, 4390,
        9616, 2413, 14459, -1070, -4079, 22126, 9063, 4362, 8182, 24439, 23625,
        7929, 18386, 5168, 13816, 465, 15801, 16750, -3340, -202, 10412, 11068,
        4184, 25930, 24767, 2785, 17361, 18033, 12366, 20548, -3831, -4101,
        16841, -193, 23217, 6351, 19077, 23565, 10482, 4100, 27488, 15956,
        -2577, 7161, 20943, 25708, -2877, 7900, -4564, -3647, 12008, 1648,
        10533 };

    {
        std::ofstream ofs("data.bin", std::ios::out | std::ios::binary);
        boost::archive::binary_oarchive oa(ofs);

        oa & data;
        ofs.flush();
        ofs.close();
    }

    {
        std::ifstream ifs("data.bin", std::ios::in | std::ios::binary);
        if (can_deserialize(ifs))
        {
            std::cout << "OK! going to read..." << std::endl;

            boost::archive::binary_iarchive ia(ifs);
            std::vector<int> cloned;
            ia & cloned;

            std::cout << "Read " << cloned.size() << " records" << std::endl;
        }
        else
            std::cout << "not OK! -- skipping data read" << std::endl;
    }

}
...