diff options
author | Eike Rathke <erack@redhat.com> | 2022-06-14 17:21:18 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2022-06-15 11:03:53 +0200 |
commit | 8661d5579bd19a9e294ddff64bbe817b537dbd46 (patch) | |
tree | a3dba05dcb75abf15622ce7969fa36a284ce45e5 /svl | |
parent | 20b19869eab5b991551a6bee7803e5b5c3dffee3 (diff) |
Resolves: tdf#149325 tdf#52602 SvNumberFormatsObj::queryKey try also uppercase
... keywords; that should catch most lower case queries. If there
are still remaining mismatches then either implement the bScan
thing, or enhance addNew() to not fail on case-different format
codes. That could be hit for the `General` keyword, for example.
Change-Id: Ic728b8c5e38db76eb791cb305595f84acf7dc867
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135854
Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'svl')
-rw-r--r-- | svl/source/numbers/numfmuno.cxx | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/svl/source/numbers/numfmuno.cxx b/svl/source/numbers/numfmuno.cxx index 98ead86e432d..4c3d4abda553 100644 --- a/svl/source/numbers/numfmuno.cxx +++ b/svl/source/numbers/numfmuno.cxx @@ -411,8 +411,55 @@ sal_Int32 SAL_CALL SvNumberFormatsObj::queryKey( const OUString& aFormat, { //! FIXME: Something still needs to happen here ... } - sal_Int32 nRet = pFormatter->GetEntryKey( aFormat, eLang ); - return nRet; + sal_uInt32 nRet = pFormatter->GetEntryKey( aFormat, eLang ); + if (nRet == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + // This seems to be a workaround for what maybe the bScan option was + // intended for? Tokenize the format code? + + // The format string based search is vague and fuzzy, as it is case + // sensitive, but the format string is only half way cased, the + // keywords (except the "General" keyword) are uppercased and literals + // of course are not. Clients using this queryKey() and if not + // successful addNew() may still fail if the result of PutEntry() is + // false because the format actually existed, just with a different + // casing. The only clean way is to just use PutEntry() and ignore the + // duplicate case, which clients can't because the API doesn't provide + // the information. + // Try just another possibilty here, without any guarantee. + + // Use only ASCII upper, because keywords are only those. + // Do not transliterate any quoted literals. + const sal_Int32 nLen = aFormat.getLength(); + OUStringBuffer aBuf(0); + sal_Unicode* p = aBuf.appendUninitialized( nLen + 1); + memcpy( p, aFormat.getStr(), (nLen + 1) * sizeof(sal_Unicode)); // including 0-char + aBuf.setLength( nLen); + assert(p == aBuf.getStr()); + sal_Unicode const * const pStop = p + aBuf.getLength(); + bool bQuoted = false; + for ( ; p < pStop; ++p) + { + if (bQuoted) + { + // Format codes don't have embedded doubled quotes, i.e. "a""b" + // is two literals displayed as `ab`. + if (*p == '"') + bQuoted = false; + } + else if (*p == '"') + bQuoted = true; + else if ('a' <= *p && *p <= 'z') + *p -= 0x20; // upper + else if (*p == '\\') + ++p; // skip escaped next char + // Theoretically that should cater for UTF-32 with + // iterateCodePoints(), but such character would not match any + // of [a-z\"] in its UTF-16 units. + } + nRet = pFormatter->GetEntryKey( aBuf, eLang ); + } + return static_cast<sal_Int32>(nRet); } sal_Int32 SAL_CALL SvNumberFormatsObj::addNew( const OUString& aFormat, |