Mercurial > hg > CbC > CbC_gcc
diff gcc/testsuite/gcc.dg/pr90037.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/testsuite/gcc.dg/pr90037.c Thu Feb 13 11:34:05 2020 +0900 @@ -0,0 +1,161 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wnull-dereference" } */ + +typedef __SIZE_TYPE__ size_t; +typedef unsigned long int uintmax_t; + +struct group +{ + char *gr_name; + char *gr_passwd; + unsigned gr_gid; + char **gr_mem; +}; + +struct passwd +{ + char *pw_name; + char *pw_passwd; + + unsigned pw_uid; + unsigned pw_gid; + char *pw_gecos; + char *pw_dir; + char *pw_shell; +}; + +extern struct group *getgrnam (const char *); +extern struct group *getgrgid (unsigned); +extern void endgrent (void); +extern struct passwd *getpwnam (const char *); +extern void endpwent (void); +extern unsigned long int strtoul (const char *__restrict, + char **__restrict, int); + +char const * +parse_with_separator (char const *spec, char const *separator, + unsigned *uid, unsigned *gid, + char **username, char **groupname) +{ + static const char *E_invalid_user = "invalid user"; + static const char *E_invalid_group = "invalid group"; + static const char *E_bad_spec = "invalid spec"; + const char *error_msg; + struct passwd *pwd; + struct group *grp; + char *u; + char const *g; + char *gname = 0; + unsigned unum = *uid; + unsigned gnum = gid ? *gid : (unsigned)-1; + + error_msg = 0; + + if (username) + *username = 0; + + if (groupname) + *groupname = 0; + + u = 0; + if (separator == 0) + { + if (*spec) + u = __builtin_strdup (spec); + } + else + { + size_t ulen = separator - spec; + if (ulen != 0) + { + u = __builtin_malloc (ulen + 1); + __builtin_memcpy (u, spec, ulen + 1); + u[ulen] = '\0'; + } + } + + g = (separator == 0 || *(separator + 1) == '\0' ? 0 : separator + 1); + + if (u != 0) + { + pwd = (*u == '+' ? 0 : getpwnam (u)); + if (pwd == 0) + { + _Bool use_login_group = (separator != 0 && g == 0); + if (use_login_group) + { + error_msg = E_bad_spec; + } + else + { + unsigned long int tmp; + tmp = strtoul (u, 0, 10); + if (tmp <= (1ul << 31) && (unsigned) tmp != (unsigned) -1) + unum = tmp; + else + error_msg = E_invalid_user; + } + } + else + { + unum = pwd->pw_uid; + if (g == 0 && separator != 0) + { + char buf[128]; + gnum = pwd->pw_gid; + grp = getgrgid (gnum); + + gname = buf; + + if (grp) + gname = __builtin_strdup (grp->gr_name); + else + __builtin_snprintf (buf, sizeof(buf), "%ju", (uintmax_t)gnum); + + endgrent (); + } + } + + endpwent (); + } + + if (g != 0 && error_msg == 0) + { + grp = (*g == '+' ? 0 : getgrnam (g)); + if (grp == 0) + { + unsigned long int tmp = strtoul (g, 0, 10); + + if (tmp <= (1ul << 31) && (unsigned) tmp != (unsigned) -1) + gnum = tmp; + else + error_msg = E_invalid_group; + } + else + gnum = grp->gr_gid; + endgrent (); + gname = __builtin_strdup (g); + } + + if (error_msg == 0) + { + *uid = unum; + if (gid) + *gid = gnum; + if (username) + { + *username = u; + u = 0; + } + if (groupname) + { + *groupname = gname; + gname = 0; + } + } + + __builtin_free (u); + __builtin_free (gname); + return error_msg ? error_msg : 0; +} +