c++ - _vsnprintf 和 _vsnprintf_s 格式字符串中的自由百分比字符

标签 c++ visual-studio-2012 printf

在格式字符串中使用自由“%”的行为非常令人惊讶。

#include <iostream>
#include <stdarg.h>
#include <stdio.h>

void foo(const char *format, ...) {
  const size_t buffSize = 1024;
  char msg[buffSize];
  {
    va_list args;
    va_start(args, format);
    _vsnprintf(msg, buffSize, format, args);
    va_end(args);
    std::cout << msg << std::endl; // here you get a,b,,c,d,e
  }
  {
    va_list args;
    va_start(args, format);
    _vsnprintf_s(msg, buffSize, format, args); // and here you crash and burn
    va_end(args);
    std::cout << msg << std::endl;
  }
}

int _tmain(int argc, _TCHAR *argv[]) {
  foo("%s,b,%,c,d,%s", "a", "e");
  return 0;
}

这不是您期望得到的,尤其是当出现以下 is stated by Microsoft

If a percent sign is followed by a character that has no meaning as a format field, the character is copied to the output unchanged.

那么我们在这里看到了什么?一个错误?从何时起? msvc12/13 是否已修复?

编辑01: 好吧,我误读了该声明,让我们关注崩溃

#include <iostream>
#include <stdarg.h>
#include <stdio.h>

void foo(const char *format, ...) {
  const size_t buffSize = 1024;
  char msg[buffSize];
  va_list args;
  va_start(args, format);
  _vsnprintf_s(msg, buffSize, format, args);
  va_end(args);
  std::cout << msg << std::endl;
}

int main(int argc, char *argv[]) {
  foo("b,%,c,d"); // crash here
  foo("%s,b,%,c,d,%s", "a", "e"); // there and everywhere
  return 0;
}

EDIT02:
从 Microsoft Connect 得到答案

Thanks for contacting Microsoft about this issue. We've found that we left out important information about how the secure functions behave from the Format Specification Syntax page. The secure functions do additional validation of the format string, and invoke the invalid parameter handler if an unexpected character follows the initial % character. By default, this terminates the program with a Dr. Watson report. In Debug mode, it causes an assert first. More information is available in the Parameter Validation topic at https://msdn.microsoft.com/en-us/library/ksazx244.aspx . The Format Specification Syntax page is being updated with this information. Expect to see the updated page for Visual Studio 2013 in the next week or so.

最佳答案

这实际上是一个文档错误。 Format Specification Syntax 中应该很快就会出现更正(一两天)。话题。缺少的信息是格式化函数的安全版本(带有尾随 _s 的函数)会对格式化字符串进行额外的验证,并且它们会拒绝百分比字符后跟意外字符。然后,在这种情况下,他们会调用无效参数处理程序,而非安全版本则不会。默认情况下,这将终止程序并调用 Dr. Watson 报告机制。

如果您尝试处理任意格式字符串问题,您可以通过调用 _set_invalid_parameter_handler 自行设置无效参数处理程序捕获此类情况并防止崩溃。在 DEBUG 版本中,此格式字符串应导致无效的参数断言。 Parameter Validation下的主题 Security Features in the CRT有更多信息。

关于c++ - _vsnprintf 和 _vsnprintf_s 格式字符串中的自由百分比字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29781151/

相关文章:

c++ - "invalid use of member"尝试使用我的功能时

visual-studio-2012 - 使用 Chrome 调试时,VS2012 中的 Typescript 断点无法命中

c# - Windows 窗体不会在 Debug模式下显示

c++ - 右值引用匹配(完美转发示例)

c++ - 为什么删除移动构造函数会导致 vector 停止工作

c++ - src/Window.d :1: *** multiple target patterns. 停止

entity-framework - VS2012 中针对 .NET 4.0 的 System.Data.SQLite 设计时组件

php - PHP 中的 printf 有什么用?

c - 如何将格式化数据存储到 C 中的数组?

无法将字符串复制到 C 中的字符串数组