1

MSDN は、RegEnumValue によって取得された文字列データについて次のように述べています。

データが REG_SZ、REG_MULTI_SZ、または REG_EXPAND_SZ 型の場合、文字列が適切な null 終了文字で格納されていない可能性があります。したがって、関数が ERROR_SUCCESS を返した場合でも、アプリケーションは文字列を使用する前に文字列が適切に終了していることを確認する必要があります。そうしないと、バッファが上書きされる可能性があります。(REG_MULTI_SZ 文字列には 2 つのヌル終了文字が必要であることに注意してください。)

値が REG_MULTI_SZ であるとします。これは、シーケンス内の各文字列を null で終了できる、またはできないことを意味しますか?それとも、最後の二重 null ターミネータのみが存在しない可能性がありますが、すべての内部 null ターミネータが存在することを意味しますか?

4

3 に答える 3

2

値が REG_MULTI_SZ であるとします。これは、シーケンス内の各文字列を null で終了できる、またはできないことを意味しますか?

シーケンス内の文字列はnull で終了する必要があります。そうしないと、文字列の 1 つがどこで終了し、次の文字列が開始するかを判断できなくなります。説明するレジストリ値の種類からREG_MULTI_SZ:

空の文字列 (\0) で終了する、null で終わる文字列のシーケンス。
次に例を示します。

    文字列1\0文字列2\0文字列3\0最後の文字列\0\0

最初の \0 は最初の文字列を終了し、最後から 2 番目の \0 は終了します
最後の文字列であり、最後の \0 はシーケンスを終了します。
最後のターミネータは、文字列の長さに組み込む必要があることに注意してください。

ドキュメントはあいまいですが、私の解釈では、最後の null ターミネータが欠落している可能性があります。

String1\0String2\0String3\0LastString

値を読み取るコードは、後続の文字列抽出のためにそれらが存在することを確認する必要があります。

値を格納するために使用されるバッファーが十分に大きく、末尾の null 文字のスペースを含めて、コードが末尾の null が存在することを保証する限り、心配する必要はありません。

于 2013-05-15T11:04:27.557 に答える
1

これは、C 文字列を処理するプログラムで非常に一般的なバグです。strlen() または wcslen() を使用して文字列の長さを簡単に測定し、それを RegSetValueEx() のcbData引数として渡します。ゼロターミネータを忘れて、これらのオフバイワンバグが蔓延しています。Windows は気にしません。バイトを書き込むだけで、文字列を解釈しようとしません。

そのため、レジストリ値を読み取ると、ゼロ ターミネータのないバイトが取得されます。その後、再度 C 文字列として解釈すると、実際の文字列が表示される確率はわずか 0.4% であり、デバッグ アロケータを使用すると確率はゼロになります。ゼロターミネータを自分で書くだけで回避できます。既に存在する場合は、バッファ オーバーランの可能性を除けば問題ありません。

于 2013-05-15T12:44:58.910 に答える