I think there's a bug here that's fixed with the following patch:
==== strtab.cxx ====
***************
*** 312,320 ****
void
STR_TAB<STR>::copy_str (const char *str, UINT32 size)
{
UINT32 buffer_size = STR::get_buffer_length (size);
reserve (buffer_size);
! STR::copy (str, size, buffer + last_idx);
last_idx += buffer_size;
} // STR_TAB::copy_str
--- 312,331 ----
void
STR_TAB<STR>::copy_str (const char *str, UINT32 size)
{
+ /* Here's a nasty one. If the call to "reserve" forces a
+ reallocation of the strings in the table, and 'str' happens to
+ point to a string in the table, then after the reallocation,
+ 'str' could point to garbage. Why are we inserting a string that
+ is already in the table? Because we don't detect duplicates till
+ after inserting (and then undo the insert; see
+ STR_TAB<STR>::insert above). So make a local copy of 'str' to
+ prevent that from happening. */
UINT32 buffer_size = STR::get_buffer_length (size);
+ char *new_str = (char *) alloca (buffer_size);
+ STR::copy(str, size, new_str);
+
reserve (buffer_size);
! STR::copy (STR::get_str(new_str), size, buffer + last_idx);
last_idx += buffer_size;
} // STR_TAB::copy_str
|