diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-06-19 14:58:35 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-06-24 16:51:35 -0400 |
commit | 458df361e0761651b6d17f4fb730f996243bc9f3 (patch) | |
tree | 34c63c86d8edd747d0d6f763584c7e8781cb6c29 /sc/source/core/data/cellvalue.cxx | |
parent | 3b0c069c9a157c4cd9ec5636c776115af6d9664f (diff) |
We need to clone the source cell value to prevent crash.
If we don't clone this, the original string value would become invalid
after the first insertion, which may cause a reallocation of the array
that stores the cell.
Change-Id: I5b1bb5f378ed5503169fce75fcbc7aeb85c5ed6e
Diffstat (limited to 'sc/source/core/data/cellvalue.cxx')
-rw-r--r-- | sc/source/core/data/cellvalue.cxx | 77 |
1 files changed, 57 insertions, 20 deletions
diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx index f9575d501294..617eb298f265 100644 --- a/sc/source/core/data/cellvalue.cxx +++ b/sc/source/core/data/cellvalue.cxx @@ -102,6 +102,31 @@ bool equalsWithoutFormatImpl( const _T& left, const _T& right ) return false; } +template<typename _T> +void commitToColumn( const _T& rCell, ScColumn& rColumn, SCROW nRow ) +{ + switch (rCell.meType) + { + case CELLTYPE_STRING: + rColumn.SetRawString(nRow, *rCell.mpString); + break; + case CELLTYPE_EDIT: + rColumn.SetEditText(nRow, ScEditUtil::Clone(*rCell.mpEditText, rColumn.GetDoc())); + break; + case CELLTYPE_VALUE: + rColumn.SetValue(nRow, rCell.mfValue); + break; + case CELLTYPE_FORMULA: + { + ScAddress aDestPos(rColumn.GetCol(), nRow, rColumn.GetTab()); + rColumn.SetFormulaCell(nRow, new ScFormulaCell(*rCell.mpFormula, rColumn.GetDoc(), aDestPos)); + } + break; + default: + rColumn.Delete(nRow); + } +} + bool hasStringImpl( CellType eType, ScFormulaCell* pFormula ) { switch (eType) @@ -132,6 +157,25 @@ bool hasNumericImpl( CellType eType, ScFormulaCell* pFormula ) } ScCellValue::ScCellValue() : meType(CELLTYPE_NONE), mfValue(0.0) {} + +ScCellValue::ScCellValue( const ScRefCellValue& rCell ) : meType(rCell.meType), mfValue(rCell.mfValue) +{ + switch (rCell.meType) + { + case CELLTYPE_STRING: + mpString = new OUString(*rCell.mpString); + break; + case CELLTYPE_EDIT: + mpEditText = rCell.mpEditText->Clone(); + break; + case CELLTYPE_FORMULA: + mpFormula = rCell.mpFormula->Clone(); + break; + default: + ; + } +} + ScCellValue::ScCellValue( double fValue ) : meType(CELLTYPE_VALUE), mfValue(fValue) {} ScCellValue::ScCellValue( const OUString& rString ) : meType(CELLTYPE_STRING), mpString(new OUString(rString)) {} ScCellValue::ScCellValue( const EditTextObject& rEditText ) : meType(CELLTYPE_EDIT), mpEditText(rEditText.Clone()) {} @@ -315,6 +359,11 @@ void ScCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const } } +void ScCellValue::commit( ScColumn& rColumn, SCROW nRow ) const +{ + commitToColumn(*this, rColumn, nRow); +} + void ScCellValue::release( ScDocument& rDoc, const ScAddress& rPos ) { switch (meType) @@ -404,6 +453,13 @@ ScCellValue& ScCellValue::operator= ( const ScCellValue& r ) return *this; } +ScCellValue& ScCellValue::operator= ( const ScRefCellValue& r ) +{ + ScCellValue aTmp(r); + swap(aTmp); + return *this; +} + void ScCellValue::swap( ScCellValue& r ) { std::swap(meType, r.meType); @@ -496,26 +552,7 @@ void ScRefCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const void ScRefCellValue::commit( ScColumn& rColumn, SCROW nRow ) const { - switch (meType) - { - case CELLTYPE_STRING: - rColumn.SetRawString(nRow, *mpString); - break; - case CELLTYPE_EDIT: - rColumn.SetEditText(nRow, ScEditUtil::Clone(*mpEditText, rColumn.GetDoc())); - break; - case CELLTYPE_VALUE: - rColumn.SetValue(nRow, mfValue); - break; - case CELLTYPE_FORMULA: - { - ScAddress aDestPos(rColumn.GetCol(), nRow, rColumn.GetTab()); - rColumn.SetFormulaCell(nRow, new ScFormulaCell(*mpFormula, rColumn.GetDoc(), aDestPos)); - } - break; - default: - rColumn.Delete(nRow); - } + commitToColumn(*this, rColumn, nRow); } bool ScRefCellValue::hasString() const |