C++ 为什么此代码在Visual Studio 2012的代码分析中发出缓冲区溢出警告(C6385/C6386)?

C++ 为什么此代码在Visual Studio 2012的代码分析中发出缓冲区溢出警告(C6385/C6386)?,c++,visual-studio,visual-studio-2012,code-analysis,buffer-overflow,C++,Visual Studio,Visual Studio 2012,Code Analysis,Buffer Overflow,我正在尝试使用Visual Studio 2012的代码分析功能。我只是在我现有的项目中运行了它们,在包含我自己的Knuth减法PRNG(又名RAN3)实现的部分中发现了一些缓冲区溢出警告(/)。然而,我无法理解为什么会发生这种情况,因为它看起来很好(我看不到任何越界读/写)。因此,我做了一个简短的等效部分(如下),但仍然得到相同的警告,无法找出原因 int main() { unsigned int k = 1U, seed = 12345U, randomNumbers[55];

我正在尝试使用Visual Studio 2012的代码分析功能。我只是在我现有的项目中运行了它们,在包含我自己的Knuth减法PRNG(又名RAN3)实现的部分中发现了一些缓冲区溢出警告(/)。然而,我无法理解为什么会发生这种情况,因为它看起来很好(我看不到任何越界读/写)。因此,我做了一个简短的等效部分(如下),但仍然得到相同的警告,无法找出原因

int main() {
  unsigned int k = 1U, seed = 12345U, randomNumbers[55];

  randomNumbers[54] = seed;
  for(unsigned int i = 1U; i <= 54U; ++i) {
    unsigned int ii = ((21U * i) % 55U) - 1U;
    randomNumbers[ii] = k;
    k = seed - k;
    seed = randomNumbers[ii];
  }

  return 0;
}
intmain(){
无符号整数k=1U,种子=12345U,随机数[55];
随机数[54]=种子;

对于(unsigned int i=1U;i打印ii的值,查看其是否超过54 按此线计算
unsigned int ii=((21U*i)%55U)-1U;

std::array
及其方法进行边界检查,以及

#include <array>

int main() {
  unsigned int k = 1U, seed = 12345U;
  std::array<int,55> randomNumbers;

  randomNumbers.at(54) = seed;

  for(unsigned int i = 1U; i <= 54U; ++i) {
    unsigned int ii = ((21U * i) % 55U) - 1U;
    randomNumbers.at(ii) = k;
    k = seed - k;
    seed = randomNumbers.at(ii);
  }

  return 0;
}

不应该有任何越界错误,特别是因为您不会使用无符号整数“到达”-1。)

首先,请理解静态分析的目的,它将执行代码库分析,以仔细检查并确保代码符合行业标准。这是软件质量控制的第一步,并始终与动态分析相配合,以发现静态分析可能导致的微妙问题和漏洞无法找到。模糊化用于通过动态分析确保软件的安全性和质量

静态代码分析也会导致误报,代码审核员应该忽略这一点。这里报告的案例是误报

#pragma warning(suppress:6385)
现在让我们深入了解一下您的场景,静态分析发现您的指令((21U*i)%55U)的计算结果可能最终为零,这可能导致ii=-1;这可能进一步导致软件中潜在的崩溃甚至安全漏洞(缓冲区溢出攻击)。静态分析不会执行所有循环迭代(与动态分析不同)断言代码的每个分支都执行良好

现在让我们来谈谈你的代码,我有一些建议和改进。请介绍一些常量或#define来保持数组的大小

#define _SIZE 55U
现在,不再使用硬编码的数字“55”和“54”,而是开始在代码中使用_SIZE。您可以引入实用函数来获取数组的安全边界

int SafeBoundsInt32(int min, int max, int value)
{
    if (value < 0)
        return 0;
    if (value >= max)
        return max - 1;
    //Valid value
    return value;
}
int-SafeBoundsInt32(int-min,int-max,int-value)
{
如果(值<0)
返回0;
如果(值>=最大值)
返回最大值-1;
//有效值
返回值;
}
我将根据引入的函数更改您的代码

int main()
{
    unsigned int k = 1U, seed = 12345U, randomNumbers[_SIZE];

    randomNumbers[_SIZE - 1] = seed;
    for (unsigned int i = 1U; i <= _SIZE - 1; ++i)
    {
        unsigned int ii = ((21U * i) % _SIZE) - 1U;
        randomNumbers[SafeBoundsInt32(0, _SIZE, ii)] = k;
        k = seed - k;
        seed = randomNumbers[SafeBoundsInt32(0, _SIZE, ii)];
    }

    return 0;
}
intmain()
{
无符号整数k=1U,种子=12345U,随机数[_SIZE];
随机数[_SIZE-1]=种子;

对于(无符号整数i=1U;i,当((21U*i)%55U)=0时,ii将为-1=overflow@AnandRathi这是我最初的想法,但是循环从
1
开始。我尝试用
int
s替换
unsigned int
s:但是发出了相同的警告。嗯,它们是误报吗?
int main()
{
    unsigned int k = 1U, seed = 12345U, randomNumbers[_SIZE];

    randomNumbers[_SIZE - 1] = seed;
    for (unsigned int i = 1U; i <= _SIZE - 1; ++i)
    {
        unsigned int ii = ((21U * i) % _SIZE) - 1U;
        randomNumbers[SafeBoundsInt32(0, _SIZE, ii)] = k;
        k = seed - k;
        seed = randomNumbers[SafeBoundsInt32(0, _SIZE, ii)];
    }

    return 0;
}