【问题标题】:Coverity issue: Copy of overlapping memory (OVERLAPPING_COPY) on sprintf statement覆盖问题:sprintf 语句上的重叠内存副本 (OVERLAPPING_COPY)
【发布时间】:2020-01-24 08:41:59
【问题描述】:
char arr[512];
...
sprintf(arr, "%s %30s", arr, "Some Text");

我收到以下关于 sprintf 语句的消息: 在调用函数 sprintf 时,参数 arr 和 arr 可能指向同一个对象。

还有其他方法可以实现这种格式吗?

【问题讨论】:

  • 你检查this
  • 是的,但不太清楚。我认为这可能是未定义的行为。那么我该如何解决呢?
  • 你想用这段代码实现什么?没有上下文,它看起来有问题。
  • cppreference:“如果调用 sprintf 或 snprintf 导致在重叠的对象之间发生复制,则行为未定义”。你也错过了一个论点。
  • 您收到的警告提醒您放弃sprintf 并使用C++ iostreams 或fmtBoost.Format 之类的库。

标签: c++ memory-management printf coverity memory-corruption


【解决方案1】:

此代码包含两个不相关的错误。至于 PVS-Studio 分析器,它会发出以下两个警告:

  • V576 格式不正确。调用“sprintf”函数时需要不同数量的实际参数。预期:4. 现在:3. test.cpp 54
  • V541 将“arr”字符串打印到自身是很危险的。 test.cpp 54

第一个暗示该函数传递的实际参数数量不足。实际上,格式字符串表明字符串和整数应作为参数。但是只传递了一个字符串。没有数字参数,导致使用具有随机值的内存量,从而导致未定义的行为。

第二个警告告诉我们,如果将一个缓冲区用作输入和输出缓冲区,则无法保证 sprintf 函数正常工作。这样的代码可能会正常工作,也可能不会。这一切都取决于sprintf 函数的实现。无论如何,没有理由以这种方式编写代码。

因此,Coverity 在针对此代码发出警告时是绝对正确的。代码肯定不正确。

附:它让我想起了另一个与“fake sprintf”的使用有关的有趣案例:)。

【讨论】:

    【解决方案2】:

    重叠警告与您将arr 复制到自身,从而覆盖其内容有关。

    进一步在代码中:

    sprintf(arr, "%s %0x", arr);
                      ^^^
    

    %s 采用 arr 字符串,但 %0x 没有采用应有的无符号十六进制整数变量,因此您可能缺少参数。

    类似的东西:

    char arr[512];
    char arr2[1024];
    unsigned int x = 15;
    sprintf(arr2, "%s %0x", arr, x);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      相关资源
      最近更新 更多