Monday, May 18, 2009

WinSTL Registry library mods and fixes, part 1: empty values

An STLSoft user recently posted a possible defect in the implementation of the WinSTL Registry Library's winstl::basic_reg_value class, reporting that a registry value (of type REG_SZ) yields a data value of size 0, leading to a crash.

Upon first examination, I thought this was a result of the fragility of the Windows Registry with respect to race conditions, as I'll discuss in a follow-up post.

However, closer examination reveals it to be a true defect. The precise circumstances in which this occur are as follows:
  • the registry-value whose value is being elicited - as a string (REG_SZ) or as an array of strings (REG_MULTI_SZ) has zero size, and
  • it has one or more peer registry-values whose values are of non-zero size
This precise set of circumstances causes the defect to fault. The reason lies in a call to winstl::reg_traits<>::reg_query_info at the start of the winstl::basic_reg_value<>::value_sz() method. This is used to determine the maximum size of the value of any if the current key's registry-values. This is useful to be able to provide a buffer of the appropriate size to the subsequent call to winstl::reg_traits<>::reg_query_value(), which actually retrieves the value in question.

The problem occurs when the value's size is 0. The last block in the method decrements this - to account for the space for the nul-terminator added earlier - and then explicitly sets the nul-terminator. (I actually forget why it does this, but I do recall that it must be done this way.)

Anyway, when the value's size is 0, decrementing it gives a very large number, and so the next statement results in an access-violation. Yuck!

STLSoft 1.9.83 will contain the fix for this, which is simply to test again that the data size is non-0.

No comments: