应该返回 -1 的 sprintf 编码错误是什么?

Ted*_*elt 6 c error-handling gcc language-lawyer

我知道当“发生编码错误”时,snprintf将返回一个负值

但是,会产生该结果的这种“编码错误”的简单示例是什么?

我正在使用gcc 10.2.0 C 编译器,并且我尝试过格式错误的格式说明符、不合理的大数字字段长度,甚至空格式字符串。

  • 格式错误的格式说明符只是按字面打印
  • 不合理的大数作为长度说明符会产生致命错误
  • 空格式字符串也会产生致命错误

这涉及重复执行以下操作:

length += snprintf(...
Run Code Online (Sandbox Code Playgroud)

建立一个格式化的字符串。

如果确定不会返回负值,那可能是安全的。

将缓冲区指针前移一个负长度可能会导致它越界。但我正在寻找一个真正发生这种情况的案例。如果存在这种情况,则可能需要增加其复杂性:

length += result = snprintf(...
Run Code Online (Sandbox Code Playgroud)

到目前为止,我找不到值得为检查编译器可能永远不会产生的值增加复杂性的场景。也许你可以举一个简单的例子。

chu*_*ica 5

应该返回 -1 的 sprintf 编码错误是什么?

在我的机器上,"%ls"不喜欢0xFFFF- 当然是编码错误。

  char buf[42];
  wchar_t s[] = { 0xFFFF,49,50,51,0 };
  int i = snprintf(buf, sizeof buf, "<%ls>", s);
  printf("%d\n", i);
Run Code Online (Sandbox Code Playgroud)

输出

-1
Run Code Online (Sandbox Code Playgroud)

下面的代码返回 -1,但与其说是由于编码错误,不如说是由于病态格式。

#include <stdio.h>

int main() {
  size_t n = 0xFFFFFFFFLLu + 1;
  char *fmt = malloc(n);
  if (fmt == NULL) {
    puts("OOM");
    return -42;
  }
  memset(fmt, 'x', n);
  fmt[n - 1] = '\0';
  char buf[42];
  int i = snprintf(buf, sizeof buf, fmt);
  printf("%d %x\n", i, (unsigned) i);
  free(fmt);
  return 7;
}
Run Code Online (Sandbox Code Playgroud)

输出

-1 ffffffff
Run Code Online (Sandbox Code Playgroud)

当传递太大的大小时,我确实得到了令人惊讶的 -1,即使只snprintf()需要 6 个字节。

  char buf[42];
  int i = snprintf(buf, 4299195472, "Hello");
  printf("%d\n", i);
Run Code Online (Sandbox Code Playgroud)

输出

-1
Run Code Online (Sandbox Code Playgroud)

*fprintf()由于方向stdout冲突,我能够想出一个简短的示例,在 a 上返回 -1 。

#include <wchar.h>
#include <stdio.h>

int main() {
  int w = wprintf(L"Hello wide world\n");
  wprintf(L"%d\n", w);
  int s = printf("Hello world\n");
  wprintf(L"%d\n", s);
}
Run Code Online (Sandbox Code Playgroud)

输出

Hello wide world
17
-1
Run Code Online (Sandbox Code Playgroud)