Kaydet (Commit) ade1df09 authored tarafından Luboš Luňák's avatar Luboš Luňák

avoid a crash with an editor-forced matrix formula (tdf#123479)

Normally when ScInterpreter has bMatrixFormula set, pMyFormulaCell
is set as well (done in the ctor). But in some rare cases,
this may not be so, and some functions such as ScRandom() already
check for this. But not all do, tdf#123479 specifically crashes
because ec974965 added AssertFormulaMatrix() to force
bMatrixFormula be set without pMyFormulaCell being set, and ScColumn()
doesn't handle this case.

Fix this by trying to pass ScFormulaCell* to ScInterpreter when
AssertFormulaMatrix() is used, this should ensure the result
in the formula editor fits better the edited formula. Since there
still may be cases when the cell is not set (e.g. editing a new
formula), also handle that case gracefully.

Ideally ScSimpleFormulaCalculator should pass ScMarkData to ScInterpreter
in such cases so that those functions use that when they can't use
GetMatColsRows(), but currently the handling of selections is rather
poor in the formula edit dialog: Non-array formulas are simply entered
in one cell and the selection is ignored, in case of a multi-selection
there's an error dialog only after the dialog is closed, and the result
field of the dialog is rather small and doesn't scroll, so e.g. matrix
result of ScRandom() wouldn't show more than one item anyway. Given that
tdf#123479 is a priority bug, better just fix it and possibly handle
selections better somewhen later.

Change-Id: I5fcbe1e358fac3623d4917eb0ead8eae00a1e153
Reviewed-on: https://gerrit.libreoffice.org/69161Reviewed-by: 's avatarDennis Francis <dennis.francis@collabora.com>
Reviewed-by: 's avatarMarkus Mohrhard <markus.mohrhard@googlemail.com>
Tested-by: 's avatarLuboš Luňák <l.lunak@collabora.com>
üst 0f3f4907
...@@ -45,14 +45,14 @@ void ScSimpleFormulaCalculator::Calculate() ...@@ -45,14 +45,14 @@ void ScSimpleFormulaCalculator::Calculate()
return; return;
mbCalculated = true; mbCalculated = true;
ScInterpreter aInt(nullptr, mpDoc, mpDoc->GetNonThreadedContext(), maAddr, *mpCode);
std::unique_ptr<sfx2::LinkManager> pNewLinkMgr( new sfx2::LinkManager(mpDoc->GetDocumentShell()) );
aInt.SetLinkManager( pNewLinkMgr.get() );
ScInterpreter aInt(mpDoc->GetFormulaCell( maAddr ), mpDoc, mpDoc->GetNonThreadedContext(), maAddr, *mpCode);
if (mbMatrixFormula) if (mbMatrixFormula)
aInt.AssertFormulaMatrix(); aInt.AssertFormulaMatrix();
std::unique_ptr<sfx2::LinkManager> pNewLinkMgr( new sfx2::LinkManager(mpDoc->GetDocumentShell()) );
aInt.SetLinkManager( pNewLinkMgr.get() );
formula::StackVar aIntType = aInt.Interpret(); formula::StackVar aIntType = aInt.Interpret();
if ( aIntType == formula::svMatrixCell ) if ( aIntType == formula::svMatrixCell )
{ {
...@@ -94,6 +94,8 @@ bool ScSimpleFormulaCalculator::IsValue() ...@@ -94,6 +94,8 @@ bool ScSimpleFormulaCalculator::IsValue()
bool ScSimpleFormulaCalculator::IsMatrix() bool ScSimpleFormulaCalculator::IsMatrix()
{ {
Calculate();
return mbMatrixResult; return mbMatrixResult;
} }
......
...@@ -1733,11 +1733,12 @@ void ScInterpreter::ScPi() ...@@ -1733,11 +1733,12 @@ void ScInterpreter::ScPi()
void ScInterpreter::ScRandom() void ScInterpreter::ScRandom()
{ {
if (bMatrixFormula && pMyFormulaCell) if (bMatrixFormula)
{ {
SCCOL nCols; SCCOL nCols = 0;
SCROW nRows; SCROW nRows = 0;
pMyFormulaCell->GetMatColsRows( nCols, nRows); if(pMyFormulaCell)
pMyFormulaCell->GetMatColsRows( nCols, nRows);
// ScViewFunc::EnterMatrix() might be asking for // ScViewFunc::EnterMatrix() might be asking for
// ScFormulaCell::GetResultDimensions(), which here are none so create // ScFormulaCell::GetResultDimensions(), which here are none so create
// a 1x1 matrix at least which exactly is the case when EnterMatrix() // a 1x1 matrix at least which exactly is the case when EnterMatrix()
...@@ -4380,9 +4381,10 @@ void ScInterpreter::ScColumn() ...@@ -4380,9 +4381,10 @@ void ScInterpreter::ScColumn()
nVal = aPos.Col() + 1; nVal = aPos.Col() + 1;
if (bMatrixFormula) if (bMatrixFormula)
{ {
SCCOL nCols; SCCOL nCols = 0;
SCROW nRows; SCROW nRows = 0;
pMyFormulaCell->GetMatColsRows( nCols, nRows); if (pMyFormulaCell)
pMyFormulaCell->GetMatColsRows( nCols, nRows);
if (nCols == 0) if (nCols == 0)
{ {
// Happens if called via ScViewFunc::EnterMatrix() // Happens if called via ScViewFunc::EnterMatrix()
...@@ -4483,9 +4485,10 @@ void ScInterpreter::ScRow() ...@@ -4483,9 +4485,10 @@ void ScInterpreter::ScRow()
nVal = aPos.Row() + 1; nVal = aPos.Row() + 1;
if (bMatrixFormula) if (bMatrixFormula)
{ {
SCCOL nCols; SCCOL nCols = 0;
SCROW nRows; SCROW nRows = 0;
pMyFormulaCell->GetMatColsRows( nCols, nRows); if (pMyFormulaCell)
pMyFormulaCell->GetMatColsRows( nCols, nRows);
if (nRows == 0) if (nRows == 0)
{ {
// Happens if called via ScViewFunc::EnterMatrix() // Happens if called via ScViewFunc::EnterMatrix()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment