Kaydet (Commit) bfe6e9ec authored tarafından Eike Rathke's avatar Eike Rathke

Handle English vs locale's General keyword, tdf#33689 follow-up, tdf#107867

Caller of ImpSvNumberformatScan::GetKeyWord() needs to know if
English or locale's keyword was found and act on it.

Pointed out by an assert when attempting to copy "STANDARD" length
characters (8) from "General" (7), which doesn't harm because when
not in debug it copied the terminating 0-character. However, the
keyword name also needs to be replaced for the locale's resulting
format code.

Change-Id: Ia5211b307ea44c1ba9c2b86786368355c570d4a2
Reviewed-on: https://gerrit.libreoffice.org/55293Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
Tested-by: 's avatarJenkins <ci@libreoffice.org>
üst 39e2c1f2
...@@ -667,17 +667,21 @@ Color* ImpSvNumberformatScan::GetColor(OUString& sStr) ...@@ -667,17 +667,21 @@ Color* ImpSvNumberformatScan::GetColor(OUString& sStr)
return pResult; return pResult;
} }
short ImpSvNumberformatScan::GetKeyWord( const OUString& sSymbol, sal_Int32 nPos ) const short ImpSvNumberformatScan::GetKeyWord( const OUString& sSymbol, sal_Int32 nPos, bool& rbFoundEnglish ) const
{ {
OUString sString = pFormatter->GetCharClass()->uppercase( sSymbol, nPos, sSymbol.getLength() - nPos ); OUString sString = pFormatter->GetCharClass()->uppercase( sSymbol, nPos, sSymbol.getLength() - nPos );
const NfKeywordTable & rKeyword = GetKeywords(); const NfKeywordTable & rKeyword = GetKeywords();
// #77026# for the Xcl perverts: the GENERAL keyword is recognized anywhere // #77026# for the Xcl perverts: the GENERAL keyword is recognized anywhere
if ( sString.startsWith( rKeyword[NF_KEY_GENERAL] ) || if (sString.startsWith( rKeyword[NF_KEY_GENERAL] ))
((meKeywordLocalization == KeywordLocalization::AllowEnglish) &&
sString.startsWith( sEnglishKeyword[NF_KEY_GENERAL])))
{ {
return NF_KEY_GENERAL; return NF_KEY_GENERAL;
} }
if ((meKeywordLocalization == KeywordLocalization::AllowEnglish) &&
sString.startsWith( sEnglishKeyword[NF_KEY_GENERAL]))
{
rbFoundEnglish = true;
return NF_KEY_GENERAL;
}
//! MUST be a reverse search to find longer strings first //! MUST be a reverse search to find longer strings first
short i = NF_KEYWORD_ENTRIES_COUNT-1; short i = NF_KEYWORD_ENTRIES_COUNT-1;
bool bFound = false; bool bFound = false;
...@@ -733,6 +737,7 @@ short ImpSvNumberformatScan::GetKeyWord( const OUString& sSymbol, sal_Int32 nPos ...@@ -733,6 +737,7 @@ short ImpSvNumberformatScan::GetKeyWord( const OUString& sSymbol, sal_Int32 nPos
} }
if ( j && sEnglishKeyword[j].getLength() > sEnglishKeyword[i].getLength() ) if ( j && sEnglishKeyword[j].getLength() > sEnglishKeyword[i].getLength() )
{ {
rbFoundEnglish = true;
return j; return j;
} }
} }
...@@ -898,7 +903,8 @@ short ImpSvNumberformatScan::Next_Symbol( const OUString& rStr, ...@@ -898,7 +903,8 @@ short ImpSvNumberformatScan::Next_Symbol( const OUString& rStr,
} }
else if ( pChrCls->isLetter( rStr, nPos-1 ) ) else if ( pChrCls->isLetter( rStr, nPos-1 ) )
{ {
short nTmpType = GetKeyWord( rStr, nPos-1 ); bool bFoundEnglish = false;
short nTmpType = GetKeyWord( rStr, nPos-1, bFoundEnglish);
if ( nTmpType ) if ( nTmpType )
{ {
bool bCurrency = false; bool bCurrency = false;
...@@ -906,7 +912,7 @@ short ImpSvNumberformatScan::Next_Symbol( const OUString& rStr, ...@@ -906,7 +912,7 @@ short ImpSvNumberformatScan::Next_Symbol( const OUString& rStr,
// like "R" (Rand) and 'R' (era) // like "R" (Rand) and 'R' (era)
if ( nCurrPos >= 0 && if ( nCurrPos >= 0 &&
nPos-1 + sCurString.getLength() <= rStr.getLength() && nPos-1 + sCurString.getLength() <= rStr.getLength() &&
sCurString.startsWith( sKeyword[nTmpType] ) ) sCurString.startsWith( bFoundEnglish ? sEnglishKeyword[nTmpType] : sKeyword[nTmpType]))
{ {
OUString aTest = pChrCls->uppercase( rStr.copy( nPos-1, sCurString.getLength() ) ); OUString aTest = pChrCls->uppercase( rStr.copy( nPos-1, sCurString.getLength() ) );
if ( aTest == sCurString ) if ( aTest == sCurString )
...@@ -922,8 +928,22 @@ short ImpSvNumberformatScan::Next_Symbol( const OUString& rStr, ...@@ -922,8 +928,22 @@ short ImpSvNumberformatScan::Next_Symbol( const OUString& rStr,
else else
{ {
eType = nTmpType; eType = nTmpType;
sal_Int32 nLen = sKeyword[eType].getLength(); // The code to be advanced is the detected keyword,
sSymbol = rStr.copy( nPos-1, nLen ); // not necessarily the locale's keyword, but the
// symbol is to be the locale's keyword.
sal_Int32 nLen;
if (bFoundEnglish)
{
nLen = sEnglishKeyword[eType].getLength();
// Use the locale's General keyword name, not uppercase.
sSymbol = (eType == NF_KEY_GENERAL ? sNameStandardFormat : sKeyword[eType]);
}
else
{
nLen = sKeyword[eType].getLength();
// Preserve a locale's keyword's case as entered.
sSymbol = rStr.copy( nPos-1, nLen);
}
if ((eType == NF_KEY_E || IsAmbiguousE(eType)) && nPos < rStr.getLength()) if ((eType == NF_KEY_E || IsAmbiguousE(eType)) && nPos < rStr.getLength())
{ {
sal_Unicode cNext = rStr[nPos]; sal_Unicode cNext = rStr[nPos];
...@@ -975,7 +995,8 @@ short ImpSvNumberformatScan::Next_Symbol( const OUString& rStr, ...@@ -975,7 +995,8 @@ short ImpSvNumberformatScan::Next_Symbol( const OUString& rStr,
case SsGetWord: case SsGetWord:
if ( pChrCls->isLetter( rStr, nPos-1 ) ) if ( pChrCls->isLetter( rStr, nPos-1 ) )
{ {
short nTmpType = GetKeyWord( rStr, nPos-1 ); bool bFoundEnglish = false;
short nTmpType = GetKeyWord( rStr, nPos-1, bFoundEnglish);
if ( nTmpType ) if ( nTmpType )
{ {
// beginning of keyword, stop scan and put back // beginning of keyword, stop scan and put back
...@@ -3070,7 +3091,8 @@ sal_Int32 ImpSvNumberformatScan::FinalScan( OUString& rString ) ...@@ -3070,7 +3091,8 @@ sal_Int32 ImpSvNumberformatScan::FinalScan( OUString& rString )
sal_Int32 nLen = rStr.getLength(); sal_Int32 nLen = rStr.getLength();
for ( sal_Int32 j = 0; j < nLen; j++ ) for ( sal_Int32 j = 0; j < nLen; j++ )
{ {
if ( (j == 0 || rStr[j - 1] != '\\') && GetKeyWord( rStr, j ) ) bool bFoundEnglish = false;
if ( (j == 0 || rStr[j - 1] != '\\') && GetKeyWord( rStr, j, bFoundEnglish) )
{ {
rStr = "\"" + rStr + "\""; rStr = "\"" + rStr + "\"";
break; // for break; // for
......
...@@ -247,8 +247,15 @@ private: // Private section ...@@ -247,8 +247,15 @@ private: // Private section
short PreviousType( sal_uInt16 i ) const; // Returns type before position skips EMPTY short PreviousType( sal_uInt16 i ) const; // Returns type before position skips EMPTY
bool IsLastBlankBeforeFrac(sal_uInt16 i) const; // True <=> there won't be a ' ' until the '/' bool IsLastBlankBeforeFrac(sal_uInt16 i) const; // True <=> there won't be a ' ' until the '/'
void Reset(); // Reset all variables before starting the analysis void Reset(); // Reset all variables before starting the analysis
short GetKeyWord( const OUString& sSymbol, // Determine keyword at nPos
sal_Int32 nPos ) const; // Return 0 <=> not found /** Determine keyword at nPos.
@param rbFoundEnglish set if English instead of locale's keyword
found, never cleared, thus init with false.
@return 0 if not found, else keyword enumeration.
*/
short GetKeyWord( const OUString& sSymbol,
sal_Int32 nPos,
bool& rbFoundEnglish ) const;
bool IsAmbiguousE( short nKey ) const // whether nKey is ambiguous E of NF_KEY_E/NF_KEY_EC bool IsAmbiguousE( short nKey ) const // whether nKey is ambiguous E of NF_KEY_E/NF_KEY_EC
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment