boost serialization: see whether a stream is “good”

断了今生、忘了曾经 提交于 2019-12-11 02:06:51

问题


I currently develop a server application which has to receive serialized data from clients, deserialize it and finally process it. The serialized data is sent in form of an array of chars. My problem is that my application can be easily broken by sending invalid data to it. So I wanted to ask whether it's possible to check a string(-stream) and see whether it's good for (de-)serialization (e.g. whether it has a valid signature) before trying to get data from it.

By the way: as the title already says, my application uses boost.serialization.

Many thanks in advance :)


回答1:


I assume you want to do a lightweight check, without requiring to read all data (in which case handling the exceptions is as efficient as it will get).

I just tested success with this simple function:

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;
}

Here is a simple test harness that I used (manipulating the data in data.bin before deserialization to check for 'bad streams'):

#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;
    }

}


来源:https://stackoverflow.com/questions/7948290/boost-serialization-see-whether-a-stream-is-good

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!