zoukankan      html  css  js  c++  java
  • Visual Studio /analyze不好之处---漏报(四)

    分析是一种强大的VisualC++特性,可以帮助发现bug。然而,它有时忽略了关键问题。在这篇简短的文章中,我描述了一个有趣的危险模式,它无法识别,并解释了一个真正的解决方法。

    这些测试都是用Visual Studio 2010 SP1,C/C++优化编译器版本16.00 .40219.01为80×86。

    你想复制一个字符串吗?

    我想我们都同意strcpy是危险的。在一些情况下,它可以安全使用,但这是一个坏习惯。所以考虑一下这个代码:

        void StringCopyTests( const char* pEvil )
        {
            char buffer[100];
    
            // warning C4996: ‘strcpy’: This function or variable may be unsafe.
            // Consider using strcpy_s instead.
            // warning C6204: Possible buffer overrun in call to ‘strcpy’: use
            // of unchecked parameter ‘pEvil’
            strcpy(buffer, pEvil);
    
            // No warning
            strcpy_s(buffer, strlen(pEvil) + 1, pEvil);
        }

    VC++警告说strcpy是危险的,strcpy是一个更好的选择。With/analyze VC++还警告说,这是strcpy的一种特别危险的用法。也可以。然而,它没有评论strcpy_s在语义上相同的用法。
    我希望每个人都会因为在这件事上使用strcpy_s而感到震惊。这样的代码表明作者根本没有清楚地考虑它们的缓冲区。不是我写的代码。
    以任何方式使用源缓冲区属性的目标缓冲区大小计算都将中断。我需要/analyze来告诉我这个模式是否存在于我们的代码库中,而现在它让我失望了。

    安全的拷贝字符串

    VC++弃用警告在理论上是个好主意,但在现实世界中,它们常常失败。从strcpy/strncpy转换为strcpy/strncpy_s/strncpy_s有好有坏的方法,经验告诉我,虽然大多数转换没有这一个糟糕,但可悲的事实是,大多数开发人员没有有效地转换到更安全的CRT。在这种情况下,有两种合理的方法来修改代码:
        void StringCopyFix( const char* pEvil )
        {
            char buffer[100];
    
            // Terminate if source is too big
            strcpy_s(buffer, pEvil);
    
            // Truncate if source is too big
            strncpy_s(buffer, pEvil, _TRUNCATE);
        }

    在strcpy_s和strncpy_s与_TRUNCATE之间进行选择是一个策略决定–如果字符串不适合,您是要继续还是要中止?没有讨论的是尺寸参数。它必须被正确地指定,而且,事实证明,最好的方法就是省略它。更安全的CRT函数都有模板重载,如果你给它们一个机会,它们将推断数组的大小。这些版本应该是首选的,因为人类有六种不同的方法可以搞乱目标缓冲区的大小*,而编译器总是能正确地处理。如果编译器不能推断出正确的大小,它将拒绝编译代码。

    我发现缓冲区大小指定不正确的一些方式包括:

    • 使用strcpy计算缓冲区大小
    • 使用与缓冲区大小不匹配的硬编码数字
    • 使用与缓冲区大小不匹配的命名常量
    • 调用_countof时使用sizeof
    • 使用错误数组的大小
    • 在打算使用sizeof(buffer)-1时使用sizeof(buffer-1)
  • 相关阅读:
    1833: [ZJOI2010]count 数字计数——数位dp
    【模板】BZOJ 3685: 普通van Emde Boas树——Treap
    【模板】解决二分图匹配的强力算法——Hopcroft-Karp算法
    BZOJ 4516: [Sdoi2016]生成魔咒——后缀数组、并查集
    【模板】二分图匹配/一般图匹配——匈牙利算法/随机匈牙利算法
    【模板】BZOJ 1692:队列变换—后缀数组 Suffix Array
    BZOJ 4241: 历史研究——莫队 二叉堆
    【模板】BZOJ 3781: 小B的询问 莫队算法
    BZOJ 3656: 异或 (组合数取模 CRT)
    【模板】SPOJ FACT0 大数分解 miller-rabin & pollard-rho
  • 原文地址:https://www.cnblogs.com/yilang/p/13376555.html
Copyright © 2011-2022 走看看