tdf#119457 - check for a valid range name and cell reference
Change-Id: If23eda52142ba5e59cfd354f2177b1ac1727efaa
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113341
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
diff --git a/sc/inc/rangenam.hxx b/sc/inc/rangenam.hxx
index bb524a2..f7c6cecc 100644
--- a/sc/inc/rangenam.hxx
+++ b/sc/inc/rangenam.hxx
@@ -58,7 +58,7 @@ public:
AbsPos = 0x0080
};
enum IsNameValidType
enum class IsNameValidType
{
NAME_VALID,
NAME_INVALID_CELL_REF,
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index 6779ffa..c276f30 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -467,15 +467,15 @@ ScRangeData::IsNameValidType ScRangeData::IsNameValid( const OUString& rName, co
* ScfTools::ConvertToScDefinedName needs to be changed too. */
char const a('.');
if (rName.indexOf(a) != -1)
return NAME_INVALID_BAD_STRING;
return IsNameValidType::NAME_INVALID_BAD_STRING;
sal_Int32 nPos = 0;
sal_Int32 nLen = rName.getLength();
if ( !nLen || !ScCompiler::IsCharFlagAllConventions( rName, nPos++, ScCharFlags::CharName ) )
return NAME_INVALID_BAD_STRING;
return IsNameValidType::NAME_INVALID_BAD_STRING;
while ( nPos < nLen )
{
if ( !ScCompiler::IsCharFlagAllConventions( rName, nPos++, ScCharFlags::Name ) )
return NAME_INVALID_BAD_STRING;
return IsNameValidType::NAME_INVALID_BAD_STRING;
}
ScAddress aAddr;
ScRange aRange;
@@ -487,10 +487,10 @@ ScRangeData::IsNameValidType ScRangeData::IsNameValid( const OUString& rName, co
if (aRange.Parse(rName, rDoc, details) != ScRefFlags::ZERO ||
aAddr.Parse(rName, rDoc, details) != ScRefFlags::ZERO )
{
return NAME_INVALID_CELL_REF;
return IsNameValidType::NAME_INVALID_CELL_REF;
}
}
return NAME_VALID;
return IsNameValidType::NAME_VALID;
}
FormulaError ScRangeData::GetErrCode() const
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index d69aac2..6303541 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -2349,7 +2349,8 @@ static ScNameInputType lcl_GetInputType( const OUString& rText )
eRet = SC_NAME_INPUT_ROW;
else if ( rDoc.GetTable( rText, nNameTab ) )
eRet = SC_NAME_INPUT_SHEET;
else if ( ScRangeData::IsNameValid( rText, rDoc ) == ScRangeData::NAME_VALID ) // nothing found, create new range?
else if (ScRangeData::IsNameValid(rText, rDoc)
== ScRangeData::IsNameValidType::NAME_VALID) // nothing found, create new range?
{
if ( rViewData.GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
eRet = SC_NAME_INPUT_DEFINE;
diff --git a/sc/source/ui/dbgui/dbnamdlg.cxx b/sc/source/ui/dbgui/dbnamdlg.cxx
index 361a4ba..4939663 100644
--- a/sc/source/ui/dbgui/dbnamdlg.cxx
+++ b/sc/source/ui/dbgui/dbnamdlg.cxx
@@ -402,7 +402,8 @@ IMPL_LINK_NOARG(ScDbNameDlg, AddBtnHdl, weld::Button&, void)
if ( aNewName.isEmpty() || aNewArea.isEmpty() )
return;
if ( ScRangeData::IsNameValid( aNewName, rDoc ) == ScRangeData::NAME_VALID && aNewName != STR_DB_LOCAL_NONAME )
if (ScRangeData::IsNameValid(aNewName, rDoc) == ScRangeData::IsNameValidType::NAME_VALID
&& aNewName != STR_DB_LOCAL_NONAME)
{
// because editing can be done now, parsing is needed first
ScRange aTmpRange;
diff --git a/sc/source/ui/namedlg/namedefdlg.cxx b/sc/source/ui/namedlg/namedefdlg.cxx
index 3f0905e..25ff6e1 100644
--- a/sc/source/ui/namedlg/namedefdlg.cxx
+++ b/sc/source/ui/namedlg/namedefdlg.cxx
@@ -138,14 +138,15 @@ bool ScNameDefDlg::IsNameValid()
m_xFtInfo->set_label(maStrInfoDefault);
return false;
}
else if ((eType = ScRangeData::IsNameValid( aName, mrDoc )) != ScRangeData::NAME_VALID)
else if ((eType = ScRangeData::IsNameValid(aName, mrDoc))
!= ScRangeData::IsNameValidType::NAME_VALID)
{
m_xFtInfo->set_label_type(weld::LabelType::Error);
if (eType == ScRangeData::NAME_INVALID_BAD_STRING)
if (eType == ScRangeData::IsNameValidType::NAME_INVALID_BAD_STRING)
{
m_xFtInfo->set_label(maErrInvalidNameStr);
}
else if (eType == ScRangeData::NAME_INVALID_CELL_REF)
else if (eType == ScRangeData::IsNameValidType::NAME_INVALID_CELL_REF)
{
m_xFtInfo->set_label(maErrInvalidNameCellRefStr);
}
diff --git a/sc/source/ui/namedlg/namedlg.cxx b/sc/source/ui/namedlg/namedlg.cxx
index 1b76dfa..977abd5 100644
--- a/sc/source/ui/namedlg/namedlg.cxx
+++ b/sc/source/ui/namedlg/namedlg.cxx
@@ -248,7 +248,7 @@ bool ScNameDlg::IsNameValid()
ScRangeName* pRangeName = GetRangeName( aScope );
if (ScRangeData::IsNameValid( aName, mrDoc ) != ScRangeData::NAME_VALID)
if (ScRangeData::IsNameValid(aName, mrDoc) != ScRangeData::IsNameValidType::NAME_VALID)
{
m_xFtInfo->set_label_type(weld::LabelType::Error);
m_xFtInfo->set_label(maErrInvalidNameStr);
diff --git a/sc/source/ui/unoobj/nameuno.cxx b/sc/source/ui/unoobj/nameuno.cxx
index bc15ba83..a9fa465 100644
--- a/sc/source/ui/unoobj/nameuno.cxx
+++ b/sc/source/ui/unoobj/nameuno.cxx
@@ -483,22 +483,38 @@ void SAL_CALL ScNamedRangesObj::addNewByName( const OUString& aName,
if (pDocShell)
{
ScDocument& rDoc = pDocShell->GetDocument();
ScRangeName* pNames = GetRangeName_Impl();
if (pNames && !pNames->findByUpperName(ScGlobal::getCharClassPtr()->uppercase(aName)))
// tdf#119457 - check for a valid range name and cell reference
switch (ScRangeData::IsNameValid(aName, rDoc))
{
std::unique_ptr<ScRangeName> pNewRanges(new ScRangeName( *pNames ));
// GRAM_API for API compatibility.
ScRangeData* pNew = new ScRangeData( rDoc, aName, aContent,
aPos, nNewType,formula::FormulaGrammar::GRAM_API );
if ( pNewRanges->insert(pNew) )
{
pDocShell->GetDocFunc().SetNewRangeNames(std::move(pNewRanges), mbModifyAndBroadcast, GetTab_Impl());
bDone = true;
}
else
{
pNew = nullptr;
}
case ScRangeData::IsNameValidType::NAME_INVALID_CELL_REF:
throw uno::RuntimeException(
"Invalid name. Reference to a cell, or a range of cells not allowed",
uno::Reference<uno::XInterface>(static_cast<::cppu::OWeakObject*>(this)));
break;
case ScRangeData::IsNameValidType::NAME_INVALID_BAD_STRING:
throw uno::RuntimeException(
"Invalid name. Start with a letter, use only letters, numbers and underscore",
uno::Reference<uno::XInterface>(static_cast<::cppu::OWeakObject*>(this)));
break;
case ScRangeData::IsNameValidType::NAME_VALID:
if (ScRangeName* pNames = GetRangeName_Impl();
pNames
&& !pNames->findByUpperName(ScGlobal::getCharClassPtr()->uppercase(aName)))
{
std::unique_ptr<ScRangeName> pNewRanges(new ScRangeName( *pNames ));
// GRAM_API for API compatibility.
ScRangeData* pNew = new ScRangeData( rDoc, aName, aContent,
aPos, nNewType,formula::FormulaGrammar::GRAM_API );
if ( pNewRanges->insert(pNew) )
{
pDocShell->GetDocFunc().SetNewRangeNames(std::move(pNewRanges), mbModifyAndBroadcast, GetTab_Impl());
bDone = true;
}
else
{
pNew = nullptr;
}
}
}
}
diff --git a/sc/source/ui/vba/vbanames.cxx b/sc/source/ui/vba/vbanames.cxx
index 79a7a80..7c145f8 100644
--- a/sc/source/ui/vba/vbanames.cxx
+++ b/sc/source/ui/vba/vbanames.cxx
@@ -104,12 +104,14 @@ ScVbaNames::Add( const css::uno::Any& Name ,
NameLocal >>= sName;
if ( !sName.isEmpty() )
{
if ( ScRangeData::IsNameValid( sName, getScDocument() ) != ScRangeData::NAME_VALID )
if (ScRangeData::IsNameValid(sName, getScDocument())
!= ScRangeData::IsNameValidType::NAME_VALID)
{
const sal_Int32 nIndex{ sName.indexOf('!') };
if (nIndex>=0)
sName = sName.copy(nIndex+1);
if ( ScRangeData::IsNameValid( sName, getScDocument() ) != ScRangeData::NAME_VALID )
if (ScRangeData::IsNameValid(sName, getScDocument())
!= ScRangeData::IsNameValidType::NAME_VALID)
throw uno::RuntimeException( "This Name is not valid ." );
}
}
diff --git a/test/source/sheet/xnamedranges.cxx b/test/source/sheet/xnamedranges.cxx
index 25726ca..e07911f 100644
--- a/test/source/sheet/xnamedranges.cxx
+++ b/test/source/sheet/xnamedranges.cxx
@@ -70,6 +70,13 @@ void XNamedRanges::testAddNewByName()
xNamedRanges->addNewByName(aName5, "D5", aBaseAddress, nType);
CPPUNIT_ASSERT_MESSAGE("Failed to create Namedrange Type ROW_HEADER",
xNamedRanges->hasByName(aName5));
// tdf#119457 - check for a valid range name
OUString aName6("type_INVALID_BAD_STRING.+:");
CPPUNIT_ASSERT_THROW(xNamedRanges->addNewByName(aName6, "D6", aBaseAddress, 0),
uno::RuntimeException);
CPPUNIT_ASSERT_MESSAGE("Created Namedrange with invalid name",
!xNamedRanges->hasByName(aName6));
}
void XNamedRanges::testAddNewFromTitles()