parent
8384884f79
commit
2490cd164b
@ -0,0 +1,91 @@
|
|||||||
|
From 586230c6bc2b7ecb285d9eb9a0e3898c074791bf Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
|
||||||
|
Date: Fri, 17 Jun 2016 15:24:58 +0100
|
||||||
|
Subject: [PATCH] Resolves: tdf#90579 crash on undo formula-to-value on two
|
||||||
|
formula cells
|
||||||
|
|
||||||
|
when the two cells have different formula.
|
||||||
|
|
||||||
|
On the undo we go from a single block of no-formulas to two blocks of one
|
||||||
|
formula each and the ScFormulaCell*s which belong to the undo are deleted
|
||||||
|
when they are transferred back to the ScDoc. Their pointers are still
|
||||||
|
use but they are now dangling pointers.
|
||||||
|
|
||||||
|
so on the undo...
|
||||||
|
|
||||||
|
in include/mdds/multi_type_vector_def.inl we enter
|
||||||
|
::swap_single_to_multi_blocks
|
||||||
|
|
||||||
|
and do...
|
||||||
|
|
||||||
|
// Get the new elements from the other container.
|
||||||
|
blocks_type new_blocks;
|
||||||
|
other.exchange_elements(
|
||||||
|
*blk_src->mp_data, src_offset, dst_block_index1, dst_offset1, dst_block_index2, dst_offset2, len, new_blocks);
|
||||||
|
|
||||||
|
in ::exchange_elements
|
||||||
|
|
||||||
|
after
|
||||||
|
|
||||||
|
element_block_func::assign_values_from_block(*blk->mp_data, src_data, src_offset, len);
|
||||||
|
|
||||||
|
using gdb and...
|
||||||
|
print ((const mdds::mtv::noncopyable_managed_element_block<54, ScFormulaCell> *)(m_blocks[0]->mp_data))->m_array[0]
|
||||||
|
|
||||||
|
we can see that other now has the value of the ScFormulaCell* that will be deleted
|
||||||
|
|
||||||
|
on return back to ::swap_single_to_multi_blocks we go to the src_offset == 0 and src_tail_len == 0 case which is
|
||||||
|
|
||||||
|
if (src_tail_len == 0)
|
||||||
|
{
|
||||||
|
// the whole block needs to be replaced.
|
||||||
|
delete_block(blk_src);
|
||||||
|
m_blocks.erase(m_blocks.begin()+block_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
print ((const mdds::mtv::noncopyable_managed_element_block<54, ScFormulaCell> *)(blk_src->mp_data))->m_array[0]
|
||||||
|
|
||||||
|
confirms that our ScFormulaCell* is here also and delete_block deletes the full
|
||||||
|
block and deletes the m_array which deletes the ScFormulaCell* and so its
|
||||||
|
deleted there while also still assigned in the new_block above.
|
||||||
|
|
||||||
|
The new block goes on to be inserted, but its all broken now because it refers
|
||||||
|
to dead data.
|
||||||
|
|
||||||
|
Presumably we need to either clear the part of the block that will be deleted
|
||||||
|
of its transferred data at exchange time. Or overwrite its data with zero. Or
|
||||||
|
swap at exchange time instead of copy. Or something of that nature anyway.
|
||||||
|
|
||||||
|
Here I go with calling element_block_func::erase whether or not we delete the
|
||||||
|
block which seems to do the right thing. Crash goes away anyway and make check
|
||||||
|
here and there passes.
|
||||||
|
---
|
||||||
|
include/mdds/multi_type_vector_def.inl | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/include/mdds/multi_type_vector_def.inl b/include/mdds/multi_type_vector_def.inl
|
||||||
|
index 0e2a15a..fe9c767 100644
|
||||||
|
--- a/include/mdds/multi_type_vector_def.inl
|
||||||
|
+++ b/include/mdds/multi_type_vector_def.inl
|
||||||
|
@@ -2306,6 +2306,9 @@ void multi_type_vector<_CellBlockFunc, _EventFunc>::swap_single_to_multi_blocks(
|
||||||
|
{
|
||||||
|
// Source range is at the top of a block.
|
||||||
|
|
||||||
|
+ // Shrink the current block by erasing the top part.
|
||||||
|
+ element_block_func::erase(*blk_src->mp_data, 0, len);
|
||||||
|
+
|
||||||
|
if (src_tail_len == 0)
|
||||||
|
{
|
||||||
|
// the whole block needs to be replaced.
|
||||||
|
@@ -2314,8 +2317,6 @@ void multi_type_vector<_CellBlockFunc, _EventFunc>::swap_single_to_multi_blocks(
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- // Shrink the current block by erasing the top part.
|
||||||
|
- element_block_func::erase(*blk_src->mp_data, 0, len);
|
||||||
|
blk_src->m_size -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.7.4
|
||||||
|
|
Loading…
Reference in new issue