xmloff/source/style/chrlohdl.cxx |   58 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 2 deletions(-)

New commits:
commit cb56ec6aa8f03fbc70c808bd4f519ce9d3c21f7d
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Fri Oct 22 01:56:46 2021 +0200
Commit:     Eike Rathke <er...@redhat.com>
CommitDate: Fri Oct 22 04:02:12 2021 +0200

    Resolves: tdf#92015 Handle malused *:rfc-language-tag ODF violation
    
    ... and don't let it overwrite existing fo:* tags with less
    information.
    
    Change-Id: I63c223f6bccd682e4173449ddc76c36e8fac6c35
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124042
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins

diff --git a/xmloff/source/style/chrlohdl.cxx b/xmloff/source/style/chrlohdl.cxx
index 4b6b1aebbf1d..05dd6d770e5a 100644
--- a/xmloff/source/style/chrlohdl.cxx
+++ b/xmloff/source/style/chrlohdl.cxx
@@ -339,8 +339,62 @@ bool XMLCharRfcLanguageTagHdl::importXML( const OUString& 
rStrImpValue, uno::Any
 
     if( !IsXMLToken( rStrImpValue, XML_NONE ) )
     {
-        aLocale.Variant = rStrImpValue;
-        aLocale.Language = I18NLANGTAG_QLT;
+        // Stored may be a *:rfc-language-tag in violation of ODF v1.3
+        // 19.516 style:rfc-language-tag "It shall only be used if its value
+        // cannot be expressed as a valid combination of the fo:language
+        // 19.871, fo:script 19.242 and fo:country 19.234 attributes".
+        // That could override a more detailed fo:* and we also don't want an
+        // unjustified I18NLANGTAG_QLT extended locale tag, but fetch the
+        // values in case fo:* doesn't follow.
+        // Rule out the obvious.
+        if (rStrImpValue.getLength() < 7)
+        {
+            SAL_WARN("xmloff.style","rfc-language-tag too short: {" << 
rStrImpValue << "} Set: "
+                    << aLocale.Language <<","<< aLocale.Country <<","<< 
aLocale.Variant);
+            // Ignore empty and keep Ssss or any earlier qlt already set.
+            if (!rStrImpValue.isEmpty() && aLocale.Language != I18NLANGTAG_QLT)
+            {
+                // Shorter than ll-Ssss, so try ll-CC or lll-CC or ll or lll
+                sal_Int32 h = rStrImpValue.indexOf('-');
+                OUString aLang;
+                if (2 <= h && h <= 3)
+                    aLang = rStrImpValue.copy(0, h);
+                else if (h < 0 && 2 <= rStrImpValue.getLength() && 
rStrImpValue.getLength() <= 3)
+                    aLang = rStrImpValue;
+                OUString aCoun;
+                if (!aLang.isEmpty() && aLang.getLength() + 3 == 
rStrImpValue.getLength())
+                    aCoun = rStrImpValue.copy( aLang.getLength() + 1);
+                // Ignore identical value or less information.
+                if ((!aLang.isEmpty() && aLang != aLocale.Language) ||
+                    (!aCoun.isEmpty() && aCoun != aLocale.Country))
+                {
+                    // Do not override existing values.
+                    if (aLocale.Language.isEmpty())
+                        aLocale.Language = aLang;
+                    if (aLocale.Country.isEmpty())
+                        aLocale.Country = aCoun;
+                    if (aLang != aLocale.Language || aCoun != aLocale.Country)
+                    {
+                        // No match, so we still need the qlt anyway. 
Whatever..
+                        aLocale.Variant = rStrImpValue;
+                        aLocale.Language = I18NLANGTAG_QLT;
+                    }
+                }
+                else if (aLang.isEmpty() && aCoun.isEmpty())
+                {
+                    // Both empty, some other tag.
+                    aLocale.Variant = rStrImpValue;
+                    aLocale.Language = I18NLANGTAG_QLT;
+                }
+            }
+            SAL_WARN("xmloff.style","rfc-language-tag too short: now set: "
+                    << aLocale.Language <<","<< aLocale.Country <<","<< 
aLocale.Variant);
+        }
+        else
+        {
+            aLocale.Variant = rStrImpValue;
+            aLocale.Language = I18NLANGTAG_QLT;
+        }
     }
 
     rValue <<= aLocale;

Reply via email to