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 )
     {

Reply via email to