From 3041393d2e6dc094652334fcb4bc35597632d228 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 24 Jan 2020 15:48:41 +0100 Subject: Fix flawed logic in QSystemLocalePrivate::getLocaleInfo() If the first call to GetLocaleInfo() returned non-zero, then GetLastError()'s return has nothing to do with GetLocaleInfo(), since it didn't fail. The check for ERROR_INSUFFICIENT_BUFFER as last error needs to happen in the branch where GetLocaleInfo() failed, returning zero. Change-Id: Idb6eaad1515a003133c787998aff0c265ef98251 Reviewed-by: Friedemann Kleint --- src/corelib/text/qlocale_win.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/corelib/text/qlocale_win.cpp') diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp index 4b4152c519..d7319c1532 100644 --- a/src/corelib/text/qlocale_win.cpp +++ b/src/corelib/text/qlocale_win.cpp @@ -214,9 +214,9 @@ inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int siz QString QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) { QVarLengthArray buf(maxlen ? maxlen : 64); - if (!getLocaleInfo(type, buf.data(), buf.size())) - return QString(); - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + if (!getLocaleInfo(type, buf.data(), buf.size())) { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return QString(); int cnt = getLocaleInfo(type, 0, 0); if (cnt == 0) return QString(); -- cgit v1.2.3 From e0f9b57462226b4f5842d1e857612d6c8fbe38fd Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 24 Jan 2020 16:01:33 +0100 Subject: qlocale_win.cpp: distinguish empty QString from null QVariant An empty string, when packaged as a QVariant, is non-null (as a QVariant); and QSystemLocale::query()'s callers care about the difference. Some callers of the internal getLocaleInfo(LCTYPE type, int maxlen) need an actual QString return, while others are what query() returns, so need to return a QVariant; where the former want an empty string, the latter need a null QVariant. So make that getLocaleInfo() into a template, so callers can chose QString or QVariant as return type, only affecting the failure returns. Change-Id: I7b9a698badedc0e0d8aef8c6e85c22931c33297a Reviewed-by: Friedemann Kleint Reviewed-by: Volker Hilsheimer --- src/corelib/text/qlocale_win.cpp | 55 +++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 26 deletions(-) (limited to 'src/corelib/text/qlocale_win.cpp') diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp index d7319c1532..faaa15cf6b 100644 --- a/src/corelib/text/qlocale_win.cpp +++ b/src/corelib/text/qlocale_win.cpp @@ -106,11 +106,11 @@ struct QSystemLocalePrivate { QSystemLocalePrivate(); - QString zeroDigit(); - QString decimalPoint(); - QString groupSeparator(); - QString negativeSign(); - QString positiveSign(); + QVariant zeroDigit(); + QVariant decimalPoint(); + QVariant groupSeparator(); + QVariant negativeSign(); + QVariant positiveSign(); QVariant dateFormat(QLocale::FormatType); QVariant timeFormat(QLocale::FormatType); QVariant dateTimeFormat(QLocale::FormatType); @@ -150,7 +150,9 @@ private: QString zero; // cached value for zeroDigit() int getLocaleInfo(LCTYPE type, LPWSTR data, int size); - QString getLocaleInfo(LCTYPE type, int maxlen = 0); + // Need to distinguish empty QString packaged as (non-null) QVariant from null QVariant: + template + T getLocaleInfo(LCTYPE type, int maxlen = 0); int getLocaleInfo_int(LCTYPE type, int maxlen = 0); int getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size); @@ -211,18 +213,19 @@ inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int siz #endif } -QString QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) +template +T QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) { QVarLengthArray buf(maxlen ? maxlen : 64); if (!getLocaleInfo(type, buf.data(), buf.size())) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - return QString(); + return {}; int cnt = getLocaleInfo(type, 0, 0); if (cnt == 0) - return QString(); + return {}; buf.resize(cnt); if (!getLocaleInfo(type, buf.data(), buf.size())) - return QString(); + return {}; } return QString::fromWCharArray(buf.data()); } @@ -298,7 +301,7 @@ QString &QSystemLocalePrivate::substituteDigits(QString &string) return string; } -QString QSystemLocalePrivate::zeroDigit() +QVariant QSystemLocalePrivate::zeroDigit() { if (zero.isEmpty()) { /* Ten digits plus a terminator. @@ -317,24 +320,24 @@ QString QSystemLocalePrivate::zeroDigit() return zero; } -QString QSystemLocalePrivate::decimalPoint() +QVariant QSystemLocalePrivate::decimalPoint() { - return getLocaleInfo(LOCALE_SDECIMAL); + return getLocaleInfo(LOCALE_SDECIMAL); } -QString QSystemLocalePrivate::groupSeparator() +QVariant QSystemLocalePrivate::groupSeparator() { - return getLocaleInfo(LOCALE_STHOUSAND); + return getLocaleInfo(LOCALE_STHOUSAND); } -QString QSystemLocalePrivate::negativeSign() +QVariant QSystemLocalePrivate::negativeSign() { - return getLocaleInfo(LOCALE_SNEGATIVESIGN); + return getLocaleInfo(LOCALE_SNEGATIVESIGN); } -QString QSystemLocalePrivate::positiveSign() +QVariant QSystemLocalePrivate::positiveSign() { - return getLocaleInfo(LOCALE_SPOSITIVESIGN); + return getLocaleInfo(LOCALE_SPOSITIVESIGN); } QVariant QSystemLocalePrivate::dateFormat(QLocale::FormatType type) @@ -392,10 +395,10 @@ QVariant QSystemLocalePrivate::dayName(int day, QLocale::FormatType type) day -= 1; if (type == QLocale::LongFormat) - return getLocaleInfo(long_day_map[day]); + return getLocaleInfo(long_day_map[day]); if (type == QLocale::NarrowFormat) - return getLocaleInfo(narrow_day_map[day]); - return getLocaleInfo(short_day_map[day]); + return getLocaleInfo(narrow_day_map[day]); + return getLocaleInfo(short_day_map[day]); } QVariant QSystemLocalePrivate::monthName(int month, QLocale::FormatType type) @@ -418,7 +421,7 @@ QVariant QSystemLocalePrivate::monthName(int month, QLocale::FormatType type) LCTYPE lctype = (type == QLocale::ShortFormat || type == QLocale::NarrowFormat) ? short_month_map[month] : long_month_map[month]; - return getLocaleInfo(lctype); + return getLocaleInfo(lctype); } QVariant QSystemLocalePrivate::toString(QDate date, QLocale::FormatType type) @@ -485,7 +488,7 @@ QVariant QSystemLocalePrivate::measurementSystem() QVariant QSystemLocalePrivate::collation() { - return getLocaleInfo(LOCALE_SSORTLOCALE); + return getLocaleInfo(LOCALE_SSORTLOCALE); } QVariant QSystemLocalePrivate::amText() @@ -687,12 +690,12 @@ QVariant QSystemLocalePrivate::uiLanguages() QVariant QSystemLocalePrivate::nativeLanguageName() { - return getLocaleInfo(LOCALE_SNATIVELANGUAGENAME); + return getLocaleInfo(LOCALE_SNATIVELANGUAGENAME); } QVariant QSystemLocalePrivate::nativeCountryName() { - return getLocaleInfo(LOCALE_SNATIVECOUNTRYNAME); + return getLocaleInfo(LOCALE_SNATIVECOUNTRYNAME); } -- cgit v1.2.3 From 3730452bfe098f8cdc68ec2183dd283a17f7ad39 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 23 Jan 2020 10:53:01 +0100 Subject: Fall back to "+" if MS returns empty string for positive sign MS's documentation says empty means "+" here, so implement that fallback (which shall over-ride whatever the CLDR has given us for the fallbackUiLanguage's positive sign). Task-number: QTBUG-81530 Change-Id: Ic3f10dd061d0c46d1433f29b8065988da94c38e6 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/corelib/text/qlocale_win.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/corelib/text/qlocale_win.cpp') diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp index faaa15cf6b..4a38adf309 100644 --- a/src/corelib/text/qlocale_win.cpp +++ b/src/corelib/text/qlocale_win.cpp @@ -216,9 +216,17 @@ inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int siz template T QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) { + // https://docs.microsoft.com/en-us/windows/win32/intl/locale-spositivesign + // says empty for LOCALE_SPOSITIVESIGN means "+", although GetLocaleInfo() + // is documented to return 0 only on failure, so it's not clear how it + // returns empty to mean this; hence the two checks for it below. + const QString plus = QStringLiteral("+"); QVarLengthArray buf(maxlen ? maxlen : 64); if (!getLocaleInfo(type, buf.data(), buf.size())) { - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + const auto lastError = GetLastError(); + if (type == LOCALE_SPOSITIVESIGN && lastError == ERROR_SUCCESS) + return plus; + if (lastError != ERROR_INSUFFICIENT_BUFFER) return {}; int cnt = getLocaleInfo(type, 0, 0); if (cnt == 0) @@ -227,6 +235,8 @@ T QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) if (!getLocaleInfo(type, buf.data(), buf.size())) return {}; } + if (type == LOCALE_SPOSITIVESIGN && !buf[0]) + return plus; return QString::fromWCharArray(buf.data()); } -- cgit v1.2.3