libc: Allow empty fields in the password file
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
46be0bd458
commit
e5a3bbcbbc
@ -7,6 +7,36 @@ static struct passwd pwd;
|
||||
static FILE* f { nullptr };
|
||||
static char buf[4096];
|
||||
|
||||
// Variant of strtok that returns empty tokens when there are several delimiters, instead of skipping all at once.
|
||||
// Example:
|
||||
// strtok("hello:world::!:", ":") -> "hello", "world", "!"
|
||||
// _strtok_once("hello:world::!:", ":") -> "hello", "world", "", "!"
|
||||
static char* _strtok_once(char* str, const char* delim)
|
||||
{
|
||||
static char* s = nullptr;
|
||||
if (str) s = str;
|
||||
if (!s) return nullptr;
|
||||
|
||||
if (*s)
|
||||
{
|
||||
if (*s == 0) return nullptr;
|
||||
|
||||
size_t use = strcspn(s, delim);
|
||||
char* result = s;
|
||||
|
||||
if (s[use] != 0)
|
||||
{
|
||||
s[use] = 0;
|
||||
s += (use + 1);
|
||||
}
|
||||
else { s = nullptr; }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
struct passwd* getpwent()
|
||||
@ -22,25 +52,25 @@ extern "C"
|
||||
char* rc = fgets(buf, sizeof(buf), f);
|
||||
if (!rc) return nullptr;
|
||||
|
||||
char* name = strtok(rc, ":\n");
|
||||
char* name = _strtok_once(rc, ":\n");
|
||||
if (!name) continue;
|
||||
|
||||
char* passwd = strtok(nullptr, ":\n");
|
||||
char* passwd = _strtok_once(nullptr, ":\n");
|
||||
if (!passwd) continue;
|
||||
|
||||
char* uid = strtok(nullptr, ":\n");
|
||||
char* uid = _strtok_once(nullptr, ":\n");
|
||||
if (!uid) continue;
|
||||
|
||||
char* gid = strtok(nullptr, ":\n");
|
||||
char* gid = _strtok_once(nullptr, ":\n");
|
||||
if (!gid) continue;
|
||||
|
||||
char* gecos = strtok(nullptr, ":\n");
|
||||
char* gecos = _strtok_once(nullptr, ":\n");
|
||||
if (!gecos) continue;
|
||||
|
||||
char* dir = strtok(nullptr, ":\n");
|
||||
char* dir = _strtok_once(nullptr, ":\n");
|
||||
if (!dir) continue;
|
||||
|
||||
char* shell = strtok(nullptr, ":\n");
|
||||
char* shell = _strtok_once(nullptr, ":\n");
|
||||
if (!shell) continue;
|
||||
|
||||
pwd.pw_name = name;
|
||||
|
Loading…
Reference in New Issue
Block a user