提交 acb871dc 编写于 作者: zzuli_lyw's avatar zzuli_lyw

Fix setlocale return value

Issue: https://gitee.com/openharmony/third_party_musl/issues/I7JK2Z

test: libc-test
Signed-off-by: zzuli_lyw's avatarzzulilyw <378305181@qq.com>
上级 52dae72b
......@@ -55,7 +55,7 @@ void duplocale_0200(void)
locale_t global = duplocale(LC_GLOBAL_LOCALE);
EXPECT_PTRNE("duplocale_0200", global, NULL);
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL);
locale_t newlocale_ = newlocale(LC_ALL_MASK, "C.UTF-8", NULL);
EXPECT_PTRNE("duplocale_0200", newlocale_, NULL);
locale_t clonelocale = duplocale(newlocale_);
......@@ -70,6 +70,10 @@ void duplocale_0200(void)
freelocale(newlocale_);
newlocale_ = NULL;
}
if (global) {
freelocale(global);
global = NULL;
}
}
int main(void)
......
......@@ -29,7 +29,7 @@ static const int lcMarkArry[] = {
/**
* @tc.name : newlocale_0100
* @tc.desc : Check whether the LC_ALL type is passed to newlocale to create a custom locale environment
* @tc.desc : en-US is a invalid locale. The newlocale should return null
* @tc.level : Level 0
*/
void newlocale_0100(void)
......@@ -40,7 +40,7 @@ void newlocale_0100(void)
return;
}
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL);
EXPECT_PTRNE("newlocale_0100", newlocale_, NULL);
EXPECT_PTREQ("newlocale_0100", newlocale_, NULL);
if (newlocale_) {
freelocale(newlocale_);
......@@ -73,6 +73,7 @@ void newlocale_0200(void)
* @tc.name : newlocale_0300
* @tc.desc : Determines whether the custom locale environment is created successfully
* by passing different LC data types to newlocale
* tips: en-US is a invalid locale. The newlocale should return null
* @tc.level : Level 0
*/
void newlocale_0300(void)
......@@ -84,7 +85,7 @@ void newlocale_0300(void)
}
for (int i = 0; i < sizeof(lcMarkArry) / sizeof(lcMarkArry[0]); i++) {
locale_t newlocale_ = newlocale(lcMarkArry[i], "en-US", NULL);
EXPECT_PTRNE("newlocale_0300", newlocale_, NULL);
EXPECT_PTREQ("newlocale_0300", newlocale_, NULL);
if (newlocale_) {
freelocale(newlocale_);
......@@ -93,11 +94,50 @@ void newlocale_0300(void)
}
}
/**
* @tc.name : newlocale_0400
* @tc.desc : Determines whether the custom locale environment is created successfully
* by passing different LC data types to newlocale
* tips: en-US is a invalid locale. The newlocale should return null
* @tc.level : Level 0
*/
void newlocale_0400(void)
{
for (int i = 0; i < sizeof(lcMarkArry) / sizeof(lcMarkArry[0]); i++) {
locale_t newlocale_ = newlocale(lcMarkArry[i], "C", NULL);
EXPECT_PTRNE("newlocale_0400", newlocale_, NULL);
if (newlocale_) {
freelocale(newlocale_);
newlocale_ = NULL;
}
newlocale_ = newlocale(lcMarkArry[i], "C.UTF-8", NULL);
EXPECT_PTRNE("newlocale_0400", newlocale_, NULL);
if (newlocale_) {
freelocale(newlocale_);
newlocale_ = NULL;
}
}
}
void newlocale_0500(void)
{
locale_t newlocale_ = newlocale(LC_ALL_MASK, "de.UTF-8", NULL);
EXPECT_PTREQ("newlocale_0500", newlocale_, NULL);
if (newlocale_) {
freelocale(newlocale_);
newlocale_ = NULL;
}
}
int main(void)
{
newlocale_0100();
newlocale_0200();
newlocale_0300();
newlocale_0400();
return t_status;
}
\ No newline at end of file
......@@ -113,12 +113,10 @@ void setlocale_0400(void)
for (unsigned int i = 0; i < sizeof(envforlocale) / sizeof(envforlocale[0]); i++) {
setenv(envforlocale[i], "da_DK", 1);
const char *locale = setlocale(LcArry[i], "");
if (!locale) {
if (locale) {
t_error("[%s] failed\n", "setlocale_0400");
return;
}
EXPECT_STRNE("SetlocaleTest_0400", locale, "da_DK");
EXPECT_STREQ("SetlocaleTest_0400", locale, "C");
}
}
......@@ -159,19 +157,10 @@ void setlocale_0600(void)
setenv(envforlocale[i], "ar_QA", 1);
char *locale = setlocale(LC_ALL, "");
if (locale == NULL) {
if (locale) {
t_error("[%s] failed\n", "setlocale_0600");
return;
}
char *token = strtok(locale, flag);
while (token != NULL && count < LC_ALL) {
vec[count] = token;
token = strtok(NULL, flag);
count++;
}
EXPECT_NE("setlocale_0600", count, 0);
}
}
......
......@@ -49,11 +49,13 @@ void uselocale_0200(void)
}
uselocale(NULL);
locale_t newLocale = newlocale(LC_PAPER_MASK, "en_ZA", NULL);
if (newLocale == NULL) {
EXPECT_PTRNE("uselocale_0200", newLocale, NULL);
if (newLocale) {
EXPECT_PTREQ("uselocale_0200", newLocale, NULL);
freelocale(newLocale);
newLocale = NULL;
return;
}
newLocale = newlocale(LC_PAPER_MASK, "C.UTF-8", NULL);
locale_t usenow = uselocale(newLocale);
EXPECT_PTREQ("uselocale_0200", usenow, LC_GLOBAL_LOCALE);
locale_t it = uselocale(NULL);
......
......@@ -55,7 +55,7 @@ void duplocale_0200(void)
locale_t global = duplocale(LC_GLOBAL_LOCALE);
EXPECT_PTRNE("duplocale_0200", global, NULL);
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL);
locale_t newlocale_ = newlocale(LC_ALL_MASK, "C.UTF-8", NULL);
EXPECT_PTRNE("duplocale_0200", newlocale_, NULL);
locale_t clonelocale = duplocale(newlocale_);
......@@ -70,6 +70,10 @@ void duplocale_0200(void)
freelocale(newlocale_);
newlocale_ = NULL;
}
if (global) {
freelocale(global);
global = NULL;
}
}
int main(void)
......
......@@ -38,7 +38,7 @@ void newlocale_0100(void)
return;
}
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL);
EXPECT_PTRNE("newlocale_0100", newlocale_, NULL);
EXPECT_PTREQ("newlocale_0100", newlocale_, NULL);
if (newlocale_) {
freelocale(newlocale_);
......@@ -82,7 +82,7 @@ void newlocale_0300(void)
}
for (int i = 0; i < sizeof(lcMarkArry) / sizeof(lcMarkArry[0]); i++) {
locale_t newlocale_ = newlocale(lcMarkArry[i], "en-US", NULL);
EXPECT_PTRNE("newlocale_0300", newlocale_, NULL);
EXPECT_PTREQ("newlocale_0300", newlocale_, NULL);
if (newlocale_) {
freelocale(newlocale_);
......
......@@ -104,12 +104,10 @@ void setlocale_0400(void)
for (unsigned int i = 0; i < sizeof(envforlocale) / sizeof(envforlocale[0]); i++) {
setenv(envforlocale[i], "da_DK", 1);
const char *locale = setlocale(LcArry[i], "");
if (!locale) {
if (locale) {
t_error("[%s] failed\n", "setlocale_0400");
return;
}
EXPECT_STRNE("SetlocaleTest_0400", locale, "da_DK");
EXPECT_STREQ("SetlocaleTest_0400", locale, "C");
}
}
......@@ -150,19 +148,10 @@ void setlocale_0600(void)
setenv(envforlocale[i], "ar_QA", 1);
char *locale = setlocale(LC_ALL, "");
if (locale == NULL) {
if (locale) {
t_error("[%s] failed\n", "setlocale_0600");
return;
}
char *token = strtok(locale, flag);
while (token != NULL && count < LC_ALL) {
vec[count] = token;
token = strtok(NULL, flag);
count++;
}
EXPECT_NE("setlocale_0600", count, 0);
}
}
......
......@@ -49,11 +49,13 @@ void uselocale_0200(void)
}
uselocale(NULL);
locale_t newLocale = newlocale(LC_PAPER_MASK, "en_ZA", NULL);
if (newLocale == NULL) {
EXPECT_PTRNE("uselocale_0200", newLocale, NULL);
if (newLocale) {
EXPECT_PTREQ("uselocale_0200", newLocale, NULL);
freelocale(newLocale);
newLocale = NULL;
return;
}
newLocale = newlocale(LC_PAPER_MASK, "C.UTF-8", NULL);
locale_t usenow = uselocale(newLocale);
EXPECT_PTREQ("uselocale_0200", usenow, LC_GLOBAL_LOCALE);
locale_t it = uselocale(NULL);
......
......@@ -33,7 +33,7 @@ void wcsftime_l_0100(void)
wchar_t buffer[80];
time(&rtime);
timeinfo = localtime(&rtime);
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL);
locale_t newlocale_ = newlocale(LC_ALL_MASK, "C.UTF-8", NULL);
size_t result = wcsftime_l(buffer, 80, L"%I:%M%p", timeinfo, newlocale_);
if (!result) {
t_error("%s wcsftime_l failed\n", __func__);
......@@ -60,7 +60,7 @@ void wcsftime_l_0200(void)
.tm_min = 10,
.tm_sec = 20,
};
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL);
locale_t newlocale_ = newlocale(LC_ALL_MASK, "C.UTF-8", NULL);
size_t result = wcsftime_l(buff, sizeof buff, L"%A %c", &mtime, newlocale_);
if (!result) {
t_error("%s wcsftime_l failed\n", __func__);
......
......@@ -44,7 +44,7 @@ void strftime_l_0100(void)
return;
}
char buffer[gBufferSize];
locale_t m_locale = newlocale(LC_ALL_MASK, "zh_cn.UTF-8", NULL);
locale_t m_locale = newlocale(LC_ALL_MASK, "C.UTF-8", NULL);
strftime_l(buffer, sizeof(buffer) - 1, "%c", timeptr, m_locale);
EXPECT_STREQ("strftime_l_0100", buffer, test_asctime_data[i].result);
}
......
......@@ -2161,6 +2161,7 @@ musl_src_porting_file = [
"src/locale/dcngettext.c",
"src/locale/locale_map.c",
"src/locale/langinfo.c",
"src/locale/newlocale.c",
"src/time/__tz.c",
"src/time/gmtime_r.c",
"src/time/strftime.c",
......
......@@ -33,7 +33,6 @@ hidden int __loc_is_allocated(locale_t);
hidden char *__gettextdomain(void);
#define LOC_MAP_FAILED ((const struct __locale_map *)-1)
#define LOC_MAP_BUILTIN ((const struct __locale_map *)-2)
#define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)])
#define LCTRANS_CUR(msg) __lctrans_cur(msg)
......
......@@ -51,19 +51,25 @@ static const char envvars[][18] = {
volatile int __locale_lock[1];
volatile int *const __locale_lockptr = __locale_lock;
static void *volatile loc_head;
struct __locale_map *common_logic(int cat, const char *val, int *length)
const struct __locale_map *__get_locale(int cat, const char *val)
{
static void *volatile loc_head;
const struct __locale_map *p;
struct __locale_map *new = 0;
const char *path = 0, *z;
char buf[256];
size_t l, n;
if (!*val) {
(val = getenv("LC_ALL")) && *val ||
(val = getenv(envvars[cat])) && *val ||
(val = getenv("LANG")) && *val ||
(val = "C.UTF-8");
}
/* Limit name length and forbid leading dot or any slashes. */
for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++);
*length = n;
if (val[0]=='.' || val[n]) {
val = "C.UTF-8";
}
......@@ -74,7 +80,7 @@ struct __locale_map *common_logic(int cat, const char *val, int *length)
if (builtin) {
if (cat == LC_CTYPE && val[1] == '.')
return (void *)&__c_dot_utf8;
return LOC_MAP_BUILTIN;
return 0;
}
for (p=loc_head; p; p=p->next) {
......@@ -87,81 +93,36 @@ struct __locale_map *common_logic(int cat, const char *val, int *length)
path = getenv("MUSL_LOCPATH");
}
if (path) {
for (; *path; path=z+!!*z) {
z = __strchrnul(path, ':');
l = z - path;
if (l >= sizeof buf - n - 2) {
continue;
}
memcpy(buf, path, l);
buf[l] = '/';
memcpy(buf+l+1, val, n);
buf[l+1+n] = 0;
size_t map_size;
const void *map = __map_file(buf, &map_size);
if (map) {
new = malloc(sizeof *new);
if (!new) {
__munmap((void *)map, map_size);
break;
}
new->map = map;
new->map_size = map_size;
memcpy(new->name, val, n);
new->name[n] = 0;
new->next = loc_head;
new->flag = VALID;
loc_head = new;
break;
}
if (path) for (; *path; path=z+!!*z) {
z = __strchrnul(path, ':');
l = z - path;
if (l >= sizeof buf - n - 2) {
continue;
}
}
return new;
}
char *get_next_val(int cat, int *idx)
{
char *str = 0;
switch (*idx) {
case 0:
*idx = 1;
if (str = getenv("LC_ALL") && *str) {
memcpy(buf, path, l);
buf[l] = '/';
memcpy(buf+l+1, val, n);
buf[l+1+n] = 0;
size_t map_size;
const void *map = __map_file(buf, &map_size);
if (map) {
new = malloc(sizeof *new);
if (!new) {
__munmap((void *)map, map_size);
break;
}
case 1:
*idx = 2;
if (str = getenv(envvars[cat]) && *str) {
break;
}
case 2:
*idx = 3;
if (str = getenv("LANG") && *str) {
break;
}
case 3:
str = "C.UTF-8";
*idx = 4;
}
return str;
}
const struct __locale_map *__get_locale(int cat, const char *val)
{
int n = 0;
struct __locale_map *new = 0;
if (!*val) {
int idx = 0;
while (idx < 4 && !new) {
val = get_next_val(cat, &idx);
new = common_logic(cat, val, &n);
new->map = map;
new->map_size = map_size;
memcpy(new->name, val, n);
new->name[n] = 0;
new->next = loc_head;
new->flag = VALID;
loc_head = new;
break;
}
} else {
new = common_logic(cat, val, &n);
}
if (new == LOC_MAP_BUILTIN) {
return 0;
}
/* If no locale definition was found, make a locale map
* object anyway to store the name, which is kept for the
* sake of being able to do message translations at the
......
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "locale_impl.h"
#include "lock.h"
#define malloc __libc_malloc
#define calloc undef
#define realloc undef
#define free undef
static int default_locale_init_done;
static struct __locale_struct default_locale, default_ctype_locale;
int __loc_is_allocated(locale_t loc)
{
return loc && loc != C_LOCALE && loc != UTF8_LOCALE
&& loc != &default_locale && loc != &default_ctype_locale;
}
static locale_t do_newlocale(int mask, const char *name, locale_t loc)
{
struct __locale_struct tmp;
for (int i=0; i<LC_ALL; i++) {
tmp.cat[i] = (!(mask & (1<<i)) && loc) ? loc->cat[i] :
__get_locale(i, (mask & (1<<i)) ? name : "");
if (tmp.cat[i] == LOC_MAP_FAILED || tmp.cat[i] && tmp.cat[i]->flag == INVALID)
return 0;
}
/* For locales with allocated storage, modify in-place. */
if (__loc_is_allocated(loc)) {
*loc = tmp;
return loc;
}
/* Otherwise, first see if we can use one of the builtin locales.
* This makes the common usage case for newlocale, getting a C locale
* with predictable behavior, very fast, and more importantly, fail-safe. */
if (!memcmp(&tmp, C_LOCALE, sizeof tmp)) return C_LOCALE;
if (!memcmp(&tmp, UTF8_LOCALE, sizeof tmp)) return UTF8_LOCALE;
/* And provide builtins for the initial default locale, and a
* variant of the C locale honoring the default locale's encoding. */
if (!default_locale_init_done) {
for (int i=0; i<LC_ALL; i++)
default_locale.cat[i] = __get_locale(i, "");
default_ctype_locale.cat[LC_CTYPE] = default_locale.cat[LC_CTYPE];
default_locale_init_done = 1;
}
if (!memcmp(&tmp, &default_locale, sizeof tmp)) return &default_locale;
if (!memcmp(&tmp, &default_ctype_locale, sizeof tmp))
return &default_ctype_locale;
/* If no builtin locale matched, attempt to allocate and copy. */
if ((loc = malloc(sizeof *loc))) *loc = tmp;
return loc;
}
locale_t __newlocale(int mask, const char *name, locale_t loc)
{
LOCK(__locale_lock);
loc = do_newlocale(mask, name, loc);
UNLOCK(__locale_lock);
return loc;
}
weak_alias(__newlocale, newlocale);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册