将空字符添加到非空终止字符串有什么问题?

What is wrong with adding null character to non null-terminated string?

为什么我不应该像 answer 那样在非空终止字符串的末尾添加空字符?我的意思是,如果我有一个非 null 终止的字符串并在字符串的末尾添加 null 字符,我现在有一个 null 终止的字符串,这应该很好,对吧? 有没有我没看到的安全问题?

以下是防止答案被删除的代码:

char letters[SIZE + 1];  // Leave room for the null-terminator.

// ...
// Populate letters[].
// ...

letters[SIZE] = '[=10=]';  // Null-terminate the array.

要知道字符串的结尾你必须有一个以空字符结尾的字符串,否则无法知道字符串的结尾

以这种方式用 [=10=] 终止字符串在技术上没有任何错误。但是,您可以用来填充数组 before 添加 [=10=] 的方法很容易出错。看看一些情况:

  1. 假设您决定逐个字符填充 letters 个字符。如果您忘记添加一些字母会怎样?如果您添加的字母多于预期大小怎么办?

  2. 如果有数千个字母填充数组怎么办?

  3. 如果您需要用 Unicode 字符填充 letters,而这些字符(通常)每个符号需要一个字节以上,该怎么办?

当然你可以非常小心地处理这些情况,但在维护代码时它们仍然容易出错。

明确一点:C always 中的 string 有一个且只有一个空字符 - 它是字符串的最后一个字符.字符串是字符数组。如果字符数组没有空字符,则它不是字符串。

A string is a contiguous sequence of characters terminated by and including the first null character. C11dr 7.1.1 1

在 OP 编码的字符数组中添加空字符没有错。

如果满足以下条件,这是形成字符串的好方法:

  1. 前面的字符全部定义。

  2. 直到写入空字符后才调用字符串函数。

一般来说,有两种方法可以跟踪一些可变数量的事物的数组:

  1. 使用终止符。当然,这是表示字符串的 C 方法:一些未知大小的字符数组,实际字符串长度由空终止符给出。
  2. 使用存储在其他地方的显式计数。 (碰巧,这就是 Pascal 传统上表示字符串的方式。)

如果您有一个包含已知但不是以 null 终止的字符序列的数组,并且如果您想将它变成一个适当的以 null 终止的字符串,并且如果您知道底层数组分配得足够大包含空终止符,那么是的,明确地将 array[N] 设置为 '[=11=]' 不仅是可以接受的,而且是 的方法。

底线:这是一项很好的技术(如果满足约束条件)。我不知道为什么之前的回答受到批评和否决。

您不应该使用它,以避免因混合 C/Pascal 字符串而导致的错误(或安全漏洞)。

  • C 风格字符串:char 数组,以 NULL ('\0') 结尾
  • Pascal 风格的字符串:一种结构,带有一个表示字符串大小的整数,以及一个包含字符串本身的数组。

Pascal 风格不使用in-band control,所以它可以使用其中的任何字符,比如NULL。 C 字符串不能,因为它们将其用作信号控制。

问题是当您将它们混合使用时,或者当它是另一种时采用一种风格。或者甚至尝试在它们之间进行转换。

将 C 字符串转换为 Pascal 不会有任何坏处。但是,如果您有一个包含多个 NULL 字符的合法 Pascal 字符串,将其转换为 C 样式会导致问题,因为它无法表示它。

一个很好的例子是 X.509 Null Char Exploit,您可以在其中注册一个 ssl 证书到:

www.mysimplesite.com[=10=]www.bigbank.com

X.509 证书使用 Pascal 字符串,因此有效。但是在检查时,CA 可以使用或假定只看到第一个 www.mysimplesite.com 并签署证书的 C 代码或字符串样式。一些兄弟将此证书解析为对 www.bigbank.com.

也有效

因此,您可以使用它,但您应该不,因为它有导致错误甚至安全漏洞的风险.

更多详情和信息: https://www.blackhat.com/presentations/bh-usa-09/MARLINSPIKE/BHUSA09-Marlinspike-DefeatSSL-SLIDES.pdf https://sites.google.com/site/cse825maninthemiddle/odds-and-ends/x-509-null-char-exploit