diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 2562eb5416..253f18488f 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -988,25 +988,60 @@ static char * IsoLocaleName(const char *winlocname) { #ifdef _MSC_VER - static char iso_lc_messages[32]; - _locale_t loct = NULL; + static char iso_lc_messages[LOCALE_NAME_MAX_LENGTH]; + _locale_t loct; if (pg_strcasecmp("c", winlocname) == 0 || pg_strcasecmp("posix", winlocname) == 0) { - strcpy(iso_lc_messages, "C"); - return iso_lc_messages; + return "C"; } - loct = _create_locale(LC_CTYPE, winlocname); if (loct != NULL) { size_t rc; - char *hyphen; + char* hyphen; + +#if _WIN32_WINNT >= 0x0600 + WCHAR wc_locale_name[LOCALE_NAME_MAX_LENGTH]; + WCHAR buffer[LOCALE_NAME_MAX_LENGTH]; + char loc_name[LOCALE_NAME_MAX_LENGTH]; + char* tmp; + + /* + * We know input locale is valid and has following syntax + * [_[.]] + * GetLocaleInfoEx can only take locale name without code-page + * so we are trimming the unwanted part from the locale name. + */ + tmp = strchr(winlocname, '.'); + if (tmp != NULL) { + size_t cp_index; + cp_index = (size_t)(tmp - winlocname); + strncpy(loc_name, winlocname, cp_index); + loc_name[cp_index] = '\0'; + } + else { + // assuming only locale name is given as input string. + strcpy(loc_name, winlocname); + } + memset(wc_locale_name, 0, sizeof(wc_locale_name)); + memset(buffer, 0, sizeof(buffer)); + MultiByteToWideChar(CP_ACP, 0, loc_name, -1, wc_locale_name, + LOCALE_NAME_MAX_LENGTH); + if ((GetLocaleInfoEx(wc_locale_name, LOCALE_SNAME, + (LPWSTR)&buffer, LOCALE_NAME_MAX_LENGTH)) > 0) { + rc = wchar2char(iso_lc_messages, buffer, sizeof(iso_lc_messages), + NULL); + } + else + return NULL; +#else /* _WIN32_WINNT < 0x0600 */ /* Locale names use only ASCII, any conversion locale suffices. */ rc = wchar2char(iso_lc_messages, loct->locinfo->locale_name[LC_CTYPE], sizeof(iso_lc_messages), NULL); +#endif /* _WIN32_WINNT >= 0x0600 */ _free_locale(loct); if (rc == -1 || rc == sizeof(iso_lc_messages)) return NULL;