Skip to content

Commit

Permalink
Add more tests and fix %c in r_str_scanf
Browse files Browse the repository at this point in the history
  • Loading branch information
trufae authored Feb 8, 2024
1 parent bf78d09 commit f368c8c
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 8 deletions.
29 changes: 21 additions & 8 deletions libr/util/bscanf.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,29 @@ R_API int r_str_scanf(const char *buffer, const char *format, ...) {
_BSCANF_CONSUME_WSPACE ();
_BSCANF_MATCH ();
buf_ptr++;
} else if ('c' == *fmt_ptr || 's' == *fmt_ptr) {
/* 'c'/'s': match a character sequence/string. */
/* String conversion requires a width. */
// _BSCANF_CHECK_STRING (); -- we want to actually *str = 0 instead of early fail

/* 'c' conversion specifiers DO NOT consume whitespace. */
if ('c' != *fmt_ptr) {
} else if ('c' == *fmt_ptr) {
if (is_suppressed) {
_BSCANF_CONSUME_WSPACE ();
buf_ptr++;
fmt_ptr++;
} else if ('l' == length_mod) {
wchar_ptr = va_arg (args, wchar_t*);
wchar_t *wbuf_ptr = (wchar_t *) buf_ptr;
*wchar_ptr = *wbuf_ptr;
buf_ptr = (char *) (wbuf_ptr + 1);
fmt_ptr++;
} else {
_BSCANF_CONSUME_WSPACE ();
char_ptr = va_arg (args, char*);
*char_ptr = *buf_ptr;
buf_ptr++;
fmt_ptr++;
}

num_args_set++;
} else if ('s' == *fmt_ptr) {
/* 's': match a character sequence/string. */
/* String conversion requires a width. */
// _BSCANF_CHECK_STRING (); -- we want to actually *str = 0 instead of early fail
if (is_suppressed) {
/* Consume the character (string) and ignore it in this case. */
while (true) {
Expand Down
77 changes: 77 additions & 0 deletions test/unit/test_scanf.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,87 @@ bool test_r_str_scanf_scanset(void) {
mu_end;
}

bool test_r_str_scanf_other(void) {
short half;
int res = r_str_scanf ("fa82", "%hx", &half);
mu_assert_eq (half, -1406, "half check");
mu_assert_eq (res, 1, "return value for scanf failed");
res = sscanf ("fa82", "%hx", &half);
mu_assert_eq (half, -1406, "half check");
mu_assert_eq (res, 1, "return value for scanf failed");
res = r_str_scanf ("1234", "%hx", &half);
mu_assert_eq (half, 0x1234, "half check");
mu_assert_eq (res, 1, "return value for scanf failed");
mu_end;
}

bool test_r_str_scanf_procstat(void) {
char no_str[128];
long unsigned int no_lui;
long int no_li;
int no_num;
int p_nice;
int p_num_threads;
int p_flag;
int p_sid;
int p_s_name;
int p_pid;
int p_ppid;
int p_pgrp;
const char *fmt = "%d %.s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld";
const char *buff = "70735 (apache2) S 1833 1833 1833 0 -1 4194624 223 0 0 0 0 0 0 0 20 0 1 0 13243950 225329152 72 18446744073709551615 1 1 0 0 0 0 0 16781314 134235881 0 0 0 17 3 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
int ret = r_str_scanf (buff, fmt, &p_pid,
sizeof (no_str), no_str,
&p_s_name, &p_ppid, &p_pgrp, &no_num, &no_num,
&p_sid, &p_flag, &no_lui, &no_lui, &no_lui,
&no_lui, &no_lui, &no_lui, &no_li, &no_li,
&no_li, &p_nice, &p_num_threads);
mu_assert_eq (ret, 20, "return value for scanf failed");
mu_assert_streq (no_str, "(apache2)", "process name");

const char *fmt2 = "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld";
int res = sscanf (buff, fmt2, &p_pid, no_str,
&p_s_name, &p_ppid, &p_pgrp, &no_num, &no_num,
&p_sid, &p_flag, &no_lui, &no_lui, &no_lui,
&no_lui, &no_lui, &no_lui, &no_li, &no_li,
&no_li, &p_nice, &p_num_threads);
mu_assert_eq (res, 20, "return value for scanf failed");
mu_assert_streq (no_str, "(apache2)", "process name");

mu_end;
}

bool test_r_str_scanf_iomaps(void) {
ut64 addr0, addr1;
char perm[8];
char name[32];
const char fmt[] = "0x%Lx - 0x%Lx %.s %.s";
const char str[] = "0x8048000 - 0x9284955085 r-x hello";
int res = r_str_scanf (str, fmt, &addr0, &addr1, sizeof (perm), perm, sizeof (name), name);
mu_assert_eq (res, 4, "return value for scanf failed");
mu_assert_eq (addr0, 0x8048000, "addr0 fail");
mu_assert_eq (addr1, 0x9284955085, "addr1 fail");
mu_assert_streq (perm, "r-x", "perm fail");
mu_assert_streq (name, "hello", "name fail");

const char fmt2[] = "0x%"PFMT64x" - 0x%"PFMT64x" %s %s";
res = sscanf (str, fmt2, &addr0, &addr1, perm, name);
mu_assert_eq (res, 4, "return value for scanf failed");
mu_assert_eq (addr0, 0x8048000, "addr0 fail");
mu_assert_eq (addr1, 0x9284955085, "addr1 fail");
mu_assert_streq (perm, "r-x", "perm fail");
mu_assert_streq (name, "hello", "name fail");

mu_end;
}

bool all_tests(void) {
mu_run_test (test_r_str_scanf);
mu_run_test (test_r_str_scanf_pointer);
mu_run_test (test_r_str_scanf_scanset);
mu_run_test (test_r_str_scanf_other);
mu_run_test (test_r_str_scanf_procstat);
mu_run_test (test_r_str_scanf_iomaps);
return tests_passed != tests_run;
}

Expand Down

0 comments on commit f368c8c

Please sign in to comment.