Skip to content

Commit

Permalink
Add helper method to read an integer from a buffer
Browse files Browse the repository at this point in the history
Change-Id: Ifdd2122a3e60cdb11cc9df67570ab5628bfcdeea
Signed-off-by: Arne Schwabe <[email protected]>
  • Loading branch information
schwabe committed Jan 16, 2024
1 parent 4d8b780 commit ef2917f
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
25 changes: 25 additions & 0 deletions src/openvpn/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,3 +1443,28 @@ buffer_read_from_file(const char *filename, struct gc_arena *gc)
fclose(fp);
return ret;
}

bool
buffer_read_int(struct buffer *buf, int *result)
{
*result = 0;
bool ret = false;

while (buf_len(buf))
{
uint8_t c = *BPTR(buf);
if (c >= '0' && c <= '9')
{
*result = *result * 10;
/* lower nibble of ascii digits is their value */
*result += (c & 0x0f);
buf_advance(buf, 1);
ret = true;
}
else
{
return ret;
}
}
return ret;
}
10 changes: 10 additions & 0 deletions src/openvpn/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -1233,4 +1233,14 @@ struct buffer_list *buffer_list_file(const char *fn, int max_line_len);
*/
struct buffer buffer_read_from_file(const char *filename, struct gc_arena *gc);

/**
* will read a decimal integer from a buffer until the next non-decimal
* character. If successful the method will return true and the integer
* in \c result. The buffer will be advanced to the next character after
* the integer
*
*/
bool
buffer_read_int(struct buffer *buf, int *result);

#endif /* BUFFER_H */
34 changes: 33 additions & 1 deletion tests/unit_tests/openvpn/test_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,37 @@ test_env_special_free(void **state)
assert_true(unit_test_free_called);
}

static void
test_buffer_read_int(void **state)
{
struct gc_arena gc = gc_new();
struct buffer buf = alloc_buf_gc(1000, &gc);

buf_printf(&buf, "72732,1234");

int tmp = -1;
assert_true(buffer_read_int(&buf, &tmp));
assert_int_equal(tmp, 72732);
assert_int_equal(*BPTR(&buf), ',');

buf_advance(&buf, 1);

assert_true(buffer_read_int(&buf, &tmp));
assert_int_equal(tmp, 1234);
assert_int_equal(buf_len(&buf), 0);

buf = alloc_buf_gc(1000, &gc);
buf_printf(&buf, "fo42,7777");

assert_false(buffer_read_int(&buf, &tmp));

buf = alloc_buf_gc(1000, &gc);
buf_printf(&buf, "");
assert_false(buffer_read_int(&buf, &tmp));

gc_free(&gc);
}

int
main(void)
{
Expand Down Expand Up @@ -435,7 +466,8 @@ main(void)
cmocka_unit_test(test_buffer_free_gc_two),
cmocka_unit_test(test_buffer_gc_realloc),
cmocka_unit_test(test_character_class),
cmocka_unit_test(test_env_special_free)
cmocka_unit_test(test_env_special_free),
cmocka_unit_test(test_buffer_read_int),
};

return cmocka_run_group_tests_name("buffer", tests, NULL, NULL);
Expand Down

0 comments on commit ef2917f

Please sign in to comment.