【问题标题】:Microsoft's secure replacement for std::reverse_copy?微软对 std::reverse_copy 的安全替代?
【发布时间】:2016-01-25 01:48:06
【问题描述】:

我有以下代码:

Integer::Integer(const byte *encodedInteger, size_t byteCount, Signedness s, ByteOrder o)
{
    if(o == LITTLE_ENDIAN_ORDER)
    {
        SecByteBlock block(byteCount);
        std::reverse_copy(encodedInteger, encodedInteger+byteCount, block.begin());

        Decode(block.begin(), block.size(), s);
        return;
    }
    ...
}

我在std::reverse_copy 上发现了C4996 warning

1>c:\Program Files\...\VC\include\algorithm(2184): warning C4996: 'std::_Reverse_copy': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
1>          c:\...\VC\include\algorithm(2168) : see declaration of 'std::_Reverse_copy'
1>          integer.cpp(2898) : see reference to function template instantiation '_OutIt std::reverse_copy<const byte*,unsigned char*>(_BidIt,_BidIt,_OutIt)' being compiled
1>          with
1>          [
1>              _OutIt=unsigned char *,
1>              _BidIt=const byte *
1>          ]

我很高兴提供目标缓冲区大小或最后一个目标元素以符合 Microsoft 平台上的最佳实践。

byteCount 是一个参数(不是一个编译时间常数),所以我不能调用目标缓冲区大小的重载(count 模板参数如下):

std::reverse_copy<byte*, byte*, count>(...);

我也天真地尝试添加目标缓冲区大小和最后一个元素,但它们导致编译错误“expects 3 arguments - 4 provided”

std::reverse_copy(encodedInteger, encodedInteger+byteCount, block.begin(), block.begin()+block.size());

什么是 Microsoft 对 std::reverse_copy 的安全替代,它允许我指定目标缓冲区大小?


以下是 Microsoft 从 &lt;algorithm&gt; 提供的重载:

template<class _BidIt,
    class _OutIt> inline
_SCL_INSECURE_DEPRECATE
    _OutIt _Reverse_copy(_BidIt _First, _BidIt _Last,
        _OutIt _Dest,
        _STD tr1::false_type)
    {   // copy reversing elements in [_First, _Last), unchecked dest
    return (_Reverse_copy(_First, _Last,
        _Dest, _Iter_cat(_First), _Iter_cat(_Dest)));
    }

template<class _BidIt,
    class _OutIt> inline
    _OutIt reverse_copy(_BidIt _First, _BidIt _Last,
        _OutIt _Dest)
    {   // copy reversing elements in [_First, _Last)
    _DEBUG_RANGE(_First, _Last);
    _DEBUG_POINTER(_Dest);
    return (_Reverse_copy(_Unchecked(_First), _Unchecked(_Last),
        _Dest, _Is_checked(_Dest)));
    }

template<class _BidIt,
    class _OutTy,
    size_t _OutSize> inline
    _OutTy *reverse_copy(_BidIt _First, _BidIt _Last,
        _OutTy (&_Dest)[_OutSize])
    {   // copy reversing elements in [_First, _Last), array dest
    return (_Unchecked(
        _STD reverse_copy(_First, _Last,
            _Array_iterator<_OutTy, _OutSize>(_Dest))));
    }

【问题讨论】:

    标签: c++ visual-c++ stl


    【解决方案1】:

    问题不在于功能。编译器只是(有帮助地)通知您代码不安全,因为在调试模式下无法检查指针,因此任何溢出都会导致未定义的行为。

    VC++ 专门为此目的提供了一个名为stdext::make_checked_array_iterator 的函数。像这样使用它:

    std::reverse_copy(encodedInteger, encodedInteger+byteCount, 
         stdext::make_checked_array_iterator(block.begin(), block.size()));
    

    【讨论】:

    • 谢谢。那是哪个过载?是_Array_iterator&lt;_OutTy, _OutSize&gt; 的那个吗?为了完整起见,我不认为目标缓冲区大小是一个问题。我很高兴 Microsoft 采用更安全的编码实践。
    猜你喜欢
    • 2018-07-23
    • 2013-07-12
    • 2013-04-25
    • 1970-01-01
    • 2014-10-26
    • 1970-01-01
    • 2023-03-12
    • 2011-05-09
    • 1970-01-01
    相关资源
    最近更新 更多