sc/source/core/tool/compiler.cxx | 43 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-)
New commits: commit 9fd870f301fe546dd79eb7e26b021e7fd770c831 Author: Karthik Godha <[email protected]> AuthorDate: Sun Feb 8 09:39:44 2026 +0530 Commit: Michael Stahl <[email protected]> CommitDate: Wed Feb 11 16:36:28 2026 +0100 XLSX: Quote sheet-names containing cell references If a cell reference (ex: "a1") is used as a sheet name then it should be quoted bug-document: forum-mso-en4-242275.xls Change-Id: I67ade8629644a97d0d0308715df04a8a1ac206ba Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198940 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index e2f4e8ced711..af3c0df1b573 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -1977,6 +1977,45 @@ ScCompiler::~ScCompiler() { } +static bool lcl_TabContainsReference(const OUString& rString) +{ + sal_Int32 nLen = rString.getLength(), nPos = 0; + + if (nLen < 2 || !rtl::isAsciiAlpha(static_cast<unsigned char>(rString[0]))) + return false; + + // If the first two characters are a R1C1 style reference, Excel always quotes the string + sal_Unicode first = rString[0]; + if ((first == 'R' || first == 'r' || first == 'C' || first == 'c') + && rtl::isAsciiDigit(static_cast<unsigned char>(rString[1]))) + { + return true; + } + + // Check for A1 style refernce + while (nPos < nLen && rtl::isAsciiAlpha(static_cast<unsigned char>(rString[nPos]))) + nPos++; + + sal_Int32 nAlphaEnd = nPos; + + while (nPos < nLen && rtl::isAsciiDigit(static_cast<unsigned char>(rString[nPos]))) + nPos++; + + if (nPos != nLen || nAlphaEnd == nLen || nAlphaEnd > 3) + return false; + + // Max row: 2^20 and Max col: XFD + constexpr sal_Int32 MAX_ROW = 1048576; + + OUString sCol = rString.copy(0, nAlphaEnd).toAsciiUpperCase(); + sal_Int32 nRow = rtl_ustr_toInt32(rString.getStr() + nAlphaEnd, 10); + + bool bValidCol = (nAlphaEnd < 3 || sCol.compareToAscii("XFD") < 0); + bool bValidRow = (nRow > 0 && nRow <= MAX_ROW); + + return bValidCol && bValidRow; +} + void ScCompiler::CheckTabQuotes( OUString& rString, const FormulaGrammar::AddressConvention eConv ) { @@ -1984,7 +2023,9 @@ void ScCompiler::CheckTabQuotes( OUString& rString, sal_Int32 nContFlags = nStartFlags | KParseTokens::ANY_NUMBER; ParseResult aRes = ScGlobal::getCharClass().parsePredefinedToken( KParseType::IDENTNAME, rString, 0, nStartFlags, OUString(), nContFlags, OUString()); - bool bNeedsQuote = !((aRes.TokenType & KParseType::IDENTNAME) && aRes.EndPos == rString.getLength()); + bool bNeedsQuote + = (!((aRes.TokenType & KParseType::IDENTNAME) && aRes.EndPos == rString.getLength()) + || lcl_TabContainsReference(rString)); switch ( eConv ) {
