1

MSDN 说关于 RegEnumValue 获得的字符串数据

如果数据具有 REG_SZ、REG_MULTI_SZ 或 REG_EXPAND_SZ 类型,则该字符串可能未使用正确的空终止字符进行存储。因此,即使函数返回 ERROR_SUCCESS,应用程序在使用前也应确保字符串正确终止;否则,它可能会覆盖缓冲区。(注意 REG_MULTI_SZ 字符串应该有两个空终止字符。)

假设一个值为 REG_MULTI_SZ,这是否意味着序列中的每个字符串都可以或不能以 null 终止,或者只是可能不存在最后一个双 null 终止符,但所有内部 null 终止符都存在?

4

3 回答 3

2

假设一个值为 REG_MULTI_SZ,这是否意味着序列中的每个字符串可以或不能以空值结尾

序列中的字符串必须以空值结尾,否则将无法确定其中一个字符串的结束位置和下一个字符串的开始位置。从注册表值类型描述REG_MULTI_SZ

一系列以空字符结尾的字符串,以空字符串 (\0) 结尾。
下面是一个例子:

    String1\0String2\0String3\0LastString\0\0

第一个 \0 终止第一个字符串,倒数第二个 \0 终止
最后一个字符串,最后一个 \0 终止序列。
请注意,最后的终止符必须计入字符串的长度。

文档含糊不清,但我的解释是最后一个空终止符可能会丢失:

String1\0String2\0String3\0LastString

并且读取该值的代码必须确保它们存在于后续字符串提取中。

如果用于包含该值的缓冲区足够大,包括用于终止空字符的空间,只要代码确保存在尾随空值,则无需担心。

于 2013-05-15T11:04:27.557 回答
1

这是处理 C 字符串的程序中的一个非常常见的错误,它们很容易使用 strlen() 或 wcslen() 来测量字符串长度并将其作为 RegSetValueEx() 的cbData参数传递。忘记零终结符,那些一成不变的错误很猖獗。Windows 不在乎,它只是写入字节并且不尝试解释字符串。

所以问题是当您读取注册表值时,您将获得没有零终止符的字节。如果您随后再次将其解释为 C 字符串,那么您看到实际字符串的几率只有 0.4%,而使用调试分配器的几率为零。您只需自己编写零终止符即可避免它。如果它已经存在那么没关系,以可能的缓冲区溢出为模,如果没有,那么您可以避免使用错误数据的程序。

于 2013-05-15T12:44:58.910 回答
1

你只需要注意最后一个终结者。只需检查它是否存在。

于 2013-05-15T11:00:10.737 回答