Skip to content

Commit

Permalink
Merge pull request #900 from no92/pwd
Browse files Browse the repository at this point in the history
Assortment of fixes from LFS
  • Loading branch information
Geertiebear authored Aug 16, 2023
2 parents 91b789a + e2d5394 commit 67bee48
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 27 deletions.
42 changes: 28 additions & 14 deletions options/ansi/generic/stdio-stubs.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
Expand Down Expand Up @@ -451,16 +452,6 @@ static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) {
fmt++;
break;
}
case '0': {
if (fmt[1] == 'x' || fmt[1] == 'X') {
base = 16;
fmt += 2;
break;
}
base = 8;
fmt++;
break;
}
}

// Leading whitespace is skipped for most conversions except these.
Expand All @@ -475,10 +466,29 @@ static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) {
base = 10;
[[fallthrough]];
case 'i': {
bool is_negative = false;
unsigned long long res = 0;

if((*fmt == 'i' || *fmt == 'd') && handler.look_ahead() == '-') {
handler.consume();
is_negative = true;
}

if(*fmt == 'i' && handler.look_ahead() == '0') {
handler.consume();
if(handler.look_ahead() == 'x') {
handler.consume();
base = 16;
} else {
base = 8;
}
}

char c = handler.look_ahead();
switch (base) {
case 10:
if(!isdigit(c))
return match_count;
while (c >= '0' && c <= '9') {
handler.consume();
res = res * 10 + (c - '0');
Expand Down Expand Up @@ -513,21 +523,25 @@ static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) {
case 8:
while (c >= '0' && c <= '7') {
handler.consume();
res = res * 10 + (c - '0');
res = res * 8 + (c - '0');
c = handler.look_ahead();
}
break;
}
if (dest)
store_int(dest, type, res);
if (dest) {
if(is_negative)
store_int(dest, type, -res);
else
store_int(dest, type, res);
}
break;
}
case 'o': {
unsigned long long res = 0;
char c = handler.look_ahead();
while (c >= '0' && c <= '7') {
handler.consume();
res = res * 10 + (c - '0');
res = res * 8 + (c - '0');
c = handler.look_ahead();
}
if (dest)
Expand Down
20 changes: 10 additions & 10 deletions options/posix/generic/pwd-stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ namespace {

struct passwd *getpwent(void) {
static passwd entry;
char line[512];
char line[NSS_BUFLEN_PASSWD];

if(!open_global_file()) {
return nullptr;
}

if (fgets(line, 512, global_file)) {
if (fgets(line, NSS_BUFLEN_PASSWD, global_file)) {
clear_entry(&entry);
if(!extract_entry(line, &entry)) {
errno = EINVAL; // I suppose this can be a valid errno?
Expand All @@ -146,8 +146,8 @@ struct passwd *getpwnam(const char *name) {
if(!file)
return nullptr;

char line[512];
while(fgets(line, 512, file)) {
char line[NSS_BUFLEN_PASSWD];
while(fgets(line, NSS_BUFLEN_PASSWD, file)) {
clear_entry(&entry);
if(!extract_entry(line, &entry))
continue;
Expand All @@ -174,8 +174,8 @@ int getpwnam_r(const char *name, struct passwd *pwd, char *buffer, size_t size,
return EIO;
}

char line[512];
while(fgets(line, 512, file)) {
char line[NSS_BUFLEN_PASSWD];
while(fgets(line, NSS_BUFLEN_PASSWD, file)) {
if(!extract_entry(line, pwd))
continue;
if(!strcmp(pwd->pw_name, name)) {
Expand Down Expand Up @@ -207,8 +207,8 @@ struct passwd *getpwuid(uid_t uid) {
if(!file)
return nullptr;

char line[512];
while(fgets(line, 512, file)) {
char line[NSS_BUFLEN_PASSWD];
while(fgets(line, NSS_BUFLEN_PASSWD, file)) {
clear_entry(&entry);
if(!extract_entry(line, &entry))
continue;
Expand All @@ -235,8 +235,8 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer, size_t size, struct
return EIO;
}

char line[512];
while(fgets(line, 512, file)) {
char line[NSS_BUFLEN_PASSWD];
while(fgets(line, NSS_BUFLEN_PASSWD, file)) {
if(!extract_entry(line, pwd))
continue;
if(pwd->pw_uid == uid) {
Expand Down
14 changes: 11 additions & 3 deletions options/posix/generic/unistd-stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <unistd.h>
#include <limits.h>
#include <termios.h>
#include <pwd.h>
#include <sys/ioctl.h>

#include <bits/ensure.h>
Expand All @@ -17,6 +18,12 @@
#include <mlibc/bsd-sysdeps.hpp>
#include <mlibc/thread.hpp>

namespace {

constexpr bool logExecvpeTries = false;

}

unsigned int alarm(unsigned int seconds) {
struct itimerval it = {}, old = {};
it.it_value.tv_sec = seconds;
Expand Down Expand Up @@ -184,7 +191,9 @@ int execvpe(const char *file, char *const argv[], char *const envp[]) {
path += "/";
path += file;

mlibc::infoLogger() << "mlibc: execvpe() tries '" << path.data() << "'" << frg::endlog;
if(logExecvpeTries)
mlibc::infoLogger() << "mlibc: execvpe() tries '" << path.data() << "'" << frg::endlog;

int e = mlibc::sys_execve(path.data(), argv, envp);
__ensure(e && "sys_execve() is supposed to never return with success");
switch(e) {
Expand Down Expand Up @@ -710,8 +719,7 @@ long sysconf(int number) {
mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_NPROCESSORS_ONLN) returns fallback value 1\e[39m" << frg::endlog;
return 1;
case _SC_GETPW_R_SIZE_MAX:
mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_GETPW_R_SIZE_MAX) returns fallback value 1024\e[39m" << frg::endlog;
return 1024;
return NSS_BUFLEN_PASSWD;
case _SC_GETGR_R_SIZE_MAX:
mlibc::infoLogger() << "\e[31mmlibc: sysconf(_SC_GETGR_R_SIZE_MAX) returns fallback value 1024\e[39m" << frg::endlog;
return 1024;
Expand Down
2 changes: 2 additions & 0 deletions options/posix/include/pwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ struct passwd {
char *pw_shell;
};

#define NSS_BUFLEN_PASSWD 512

#ifndef __MLIBC_ABI_ONLY

void endpwent(void);
Expand Down
73 changes: 73 additions & 0 deletions tests/ansi/sscanf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,69 @@
#include <string.h>
#include <assert.h>

struct format_test_cases {
const char *format;
const char *data;
int expected_int;
enum {
T_INT,
T_UINT,
T_CHAR,
T_NONE,
} type;
int ret;
} formats[] = {
{"%i", "0x420", 0x420, T_INT, 1},
{"%i", "0420", 0420, T_INT, 1},
{"%i", "420", 420, T_INT, 1},
{"%i", "-420", -420, T_INT, 1},
{"%d", "-12345", -12345, T_INT, 1},
{"%u", "69", 69, T_UINT, 1},
{"%u", "0420", 420, T_UINT, 1},
{"%o", "0420", 0420, T_UINT, 1},
{"%x", "0xCB7", 0xCB7, T_UINT, 1},
{"%%", "%", 0, T_NONE, 0},
{"%c", " I am not a fan of this solution.", ' ', T_CHAR, 1},
{" %c", " CBT (capybara therapy)", 'C', T_CHAR, 1},
};

#pragma GCC diagnostic ignored "-Wformat-security"

static void test_matrix() {
for(size_t i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) {
struct format_test_cases *f = &formats[i];
int ret = -1;
int data_int;
unsigned int data_uint;
char data_char;

switch(f->type) {
case T_INT: {
ret = sscanf(f->data, f->format, &data_int);
assert(data_int == f->expected_int);
break;
}
case T_UINT: {
ret = sscanf(f->data, f->format, &data_uint);
assert(data_uint == (unsigned int) f->expected_int);
break;
}
case T_CHAR: {
ret = sscanf(f->data, f->format, &data_char);
assert(data_char == (unsigned char) f->expected_int);
break;
}
case T_NONE: {
ret = sscanf(f->data, f->format);
break;
}

}

assert(ret == f->ret);
}
}

int main() {
{
int x = 0;
Expand Down Expand Up @@ -57,5 +120,15 @@ int main() {
assert(!strcmp(token, "MemTotal:"));
assert(amount == 16299664);
}

{
char buf[] = "SIGINT";
int sig;
int ret = sscanf(buf, "%d", &sig);
assert(!ret);
}

test_matrix();

return 0;
}

0 comments on commit 67bee48

Please sign in to comment.