sc/qa/unit/data/ods/autostyle-name-is-single-char.ods |binary
 sc/qa/unit/subsequent_export_test4.cxx                |   16 ++++++++++
 sc/source/filter/xml/XMLStylesExportHelper.cxx        |   28 +++++-------------
 3 files changed, 25 insertions(+), 19 deletions(-)

New commits:
commit 1533b7de758d28ec08f4859f921b2edf894e87e4
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Tue Jun 10 17:53:02 2025 +0500
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Jun 11 08:56:43 2025 +0200

    tdf#166939: Don't pass invalid starting index when creating a view
    
    A style name can be as short as one character; a two-character prefix
    can already be too long.
    
    Change-Id: I041894d8c68942a49aef399edaccbcd48522ae83
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186328
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit faab5ca6174e3e581661784216410e2bc88da081)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186344
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sc/qa/unit/data/ods/autostyle-name-is-single-char.ods 
b/sc/qa/unit/data/ods/autostyle-name-is-single-char.ods
new file mode 100644
index 000000000000..2ed461e173cb
Binary files /dev/null and 
b/sc/qa/unit/data/ods/autostyle-name-is-single-char.ods differ
diff --git a/sc/qa/unit/subsequent_export_test4.cxx 
b/sc/qa/unit/subsequent_export_test4.cxx
index 824215619e10..491743a6c87f 100644
--- a/sc/qa/unit/subsequent_export_test4.cxx
+++ b/sc/qa/unit/subsequent_export_test4.cxx
@@ -35,6 +35,7 @@
 #include <editeng/flditem.hxx>
 #include <editeng/justifyitem.hxx>
 #include <comphelper/scopeguard.hxx>
+#include <comphelper/propertyvalue.hxx>
 #include <formula/grammar.hxx>
 #include <tools/fldunit.hxx>
 #include <tools/UnitConversion.hxx>
@@ -2258,6 +2259,21 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf166712)
     assertXPath(pConn, "/x:connections/x:connection/x:olapPr", 0);
 }
 
+CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf166939)
+{
+    // Given a document with a column autostyle name equal to "a" (it could be 
any single-character
+    // name). Load it as template, to keep streams valid (see 
ScDocShell::SaveAs) to reuse existing
+    // autostyle names (see ScXMLExport::collectAutoStyles).
+    loadWithParams(createFileURL(u"ods/autostyle-name-is-single-char.ods"),
+                   { comphelper::makePropertyValue(u"AsTemplate"_ustr, true) 
});
+    // Saving it must not crash / fail an assertion!
+    save(u"calc8"_ustr);
+    // Check that we tested the codepath preserving existing names - otherwise 
test makes no sense
+    xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
+    CPPUNIT_ASSERT(pXmlDoc);
+    assertXPath(pXmlDoc, 
"//office:automatic-styles/style:style[@style:name='a']", 1);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLStylesExportHelper.cxx 
b/sc/source/filter/xml/XMLStylesExportHelper.cxx
index 9d81eb609436..1203e660465c 100644
--- a/sc/source/filter/xml/XMLStylesExportHelper.cxx
+++ b/sc/source/filter/xml/XMLStylesExportHelper.cxx
@@ -908,27 +908,17 @@ sal_Int32 ScColumnRowStylesBase::AddStyleName(const 
OUString & rString)
 
 sal_Int32 ScColumnRowStylesBase::GetIndexOfStyleName(std::u16string_view 
rString, std::u16string_view rPrefix)
 {
-    sal_Int32 nPrefixLength(rPrefix.size());
-    std::u16string_view sTemp(rString.substr(nPrefixLength));
-    sal_Int32 nIndex(o3tl::toInt32(sTemp));
-    if (nIndex > 0 && o3tl::make_unsigned(nIndex-1) < aStyleNames.size() && 
aStyleNames.at(nIndex - 1) == rString)
-        return nIndex - 1;
-    else
+    if (std::u16string_view rest; o3tl::starts_with(rString, rPrefix, &rest))
     {
-        sal_Int32 i(0);
-        bool bFound(false);
-        while (!bFound && o3tl::make_unsigned(i) < aStyleNames.size())
-        {
-            if (aStyleNames.at(i) == rString)
-                bFound = true;
-            else
-                ++i;
-        }
-        if (bFound)
-            return i;
-        else
-            return -1;
+        sal_Int32 nIndex(o3tl::toInt32(rest));
+        if (nIndex > 0 && o3tl::make_unsigned(nIndex - 1) < aStyleNames.size() 
&& aStyleNames[nIndex - 1] == rString)
+            return nIndex - 1;
     }
+
+    if (auto i = std::find(aStyleNames.begin(), aStyleNames.end(), rString); i 
!= aStyleNames.end())
+        return std::distance(i, aStyleNames.begin());
+
+    return -1;
 }
 
 OUString& ScColumnRowStylesBase::GetStyleNameByIndex(const sal_Int32 nIndex)

Reply via email to