提升序列化:查看流是否“好”

时间:2011-10-30 22:17:55

标签: c++ boost boost-serialization

我目前正在开发一个服务器应用程序,它必须从客户端接收序列化数据,对其进行反序列化并最终处理它。序列化数据以字符数组的形式发送。我的问题是,通过向其发送无效数据可以轻松破解我的应用程序。所以我想问一下,在尝试从中获取数据之前,是否可以检查一个字符串(-stream)并查看它是否适合(反)序列化(例如它是否有一个有效的签名)。

顺便说一句:正如标题所说,我的应用程序使用boost.serialization。

非常感谢提前:)

1 个答案:

答案 0 :(得分:0)

我假设您要执行轻量级检查,而无需读取所有数据(在这种情况下,处理异常的效率与获取的效率相同)。

我刚用这个简单的函数测试了成功:

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

}