Ticket #9567 (closed defect: fixed)
Small patch for stable behavior in wxGridCellAttrData
|Reported by:||kjones@…||Owned by:|
|Keywords:||wxGridCellAttrData SetAttr NULL wxGridCellWithAttrArray wxGridCellAttr||Cc:||something.appropriate@…|
This patch fixes a crash that can happen when calling wxGridCellAttrData::SetAttr twice on the same cell, as described below.
Imagine that you want to "cancel" any cell attributes on a given cell. It seems to me that the
logical way to proceed would be to call wxGridCellAttrData::SetAttr and pass in NULL to indicate
that you want to nullify any attributes that may or may not be present on that cell.
However, currently (i.e. without this patch), it is "safe" to call wxGridCellAttrData::SetAttr with NULL **only** if a non-null attribute has previously been assigned to that cell.
In cases were you want to make sure that no attributes are present on a cell, then given the current code you would need to perform a query on every cell first to see if it actually has attributes before you NULL them. This doesn't seem right.
With this very tiny patch I am submitting, you can now set NULL attributes on a cell without caring whether it previously had NULL or non-NULL attributes.
Without the patch, then here is the crash that can happen:
1. Take a cell that already has NULL attributes. (For example, I will use row = 1, col = 1.)
2. Call wxGridCellAttrData::SetAttr(NULL, 1, 1)
3. That call to SetAttr will complete without any apparent difficulty.
4. Now instantiate a non-NULL wxGridCellAttr and call SetAttr again.
5. Call wxGridCellAttrData::SetAttr(p_nonNull, 1, 1)
6. That will crash.
The reason why the second call crashes is because the first call created an entry in "m_attrs" (which is a wxGridCellWithAttrArray) and then stored the NULL in the array. Then in the second call to SetAttr we do **NOT** enter the wxNOT_FOUND block, when actually I believe that we should. A NULL attribute is the same as the cell not having an attribute, so therefore it should not be stored in the wxGridCellWithAttrArray. If the code had refrained from storing the NULL during the first call to SetAttr, then we would correctly enter the wxNOT_FOUND block during the second call, and we could then store our new (non-null) attribute without crashing the program.