mirror of
https://github.com/tailix/libkernaux.git
synced 2025-02-17 15:45:32 -05:00
Main: include/kernaux/ntoa.h: Protect from too long prefix
This commit is contained in:
parent
4c326463ac
commit
9ec149a12d
9 changed files with 98 additions and 22 deletions
|
@ -1,3 +1,7 @@
|
|||
2022-06-31 Alex Kotov <kotovalexarian@gmail.com>
|
||||
|
||||
* include/kernaux/ntoa.h: Protect from too long prefix
|
||||
|
||||
2022-05-30 Alex Kotov <kotovalexarian@gmail.com>
|
||||
|
||||
* include/kernaux/ntoa.h: Functions "kernaux_utoa" and "kernaux_itoa"
|
||||
|
|
|
@ -7,6 +7,8 @@ extern "C" {
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#define KERNAUX_NTOA_MAX_PREFIX_LEN 100
|
||||
|
||||
#define KERNAUX_NTOA_DEFAULT_PREFIX_2 "0b"
|
||||
#define KERNAUX_NTOA_DEFAULT_PREFIX_8 "0o"
|
||||
#define KERNAUX_NTOA_DEFAULT_PREFIX_16 "0x"
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include <mruby/presym.h>
|
||||
#include <mruby/string.h>
|
||||
|
||||
#define MAX_PREFIX_LEN 100
|
||||
|
||||
static mrb_value rb_KernAux_utoa(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_itoa(mrb_state *mrb, mrb_value self);
|
||||
|
||||
|
@ -77,7 +75,7 @@ mrb_value rb_KernAux_utoa(mrb_state *mrb, mrb_value self)
|
|||
mrb_raise(mrb, E_RANGE_ERROR,
|
||||
"can't convert negative number to uint64_t");
|
||||
}
|
||||
if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
if (prefix_len > KERNAUX_NTOA_MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
struct RClass *const rb_KernAux =
|
||||
mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
||||
struct RClass *const rb_KernAux_TooLongNtoaPrefixError =
|
||||
|
@ -108,7 +106,7 @@ mrb_value rb_KernAux_itoa(mrb_state *mrb, mrb_value self)
|
|||
mrb_int prefix_len = 0;
|
||||
mrb_get_args(mrb, "io|s!", &value, &base, &prefix, &prefix_len);
|
||||
|
||||
if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
if (prefix_len > KERNAUX_NTOA_MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
struct RClass *const rb_KernAux =
|
||||
mrb_module_get_id(mrb, MRB_SYM(KernAux));
|
||||
struct RClass *const rb_KernAux_TooLongNtoaPrefixError =
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#include <kernaux.h>
|
||||
#include <ruby.h>
|
||||
|
||||
#define MAX_PREFIX_LEN 100
|
||||
|
||||
#ifdef HAVE_KERNAUX_UTOA
|
||||
static VALUE rb_KernAux_utoa(int argc, const VALUE *argv, VALUE self);
|
||||
#endif
|
||||
|
@ -139,7 +137,7 @@ VALUE rb_KernAux_utoa(const int argc, const VALUE *argv, const VALUE self)
|
|||
prefix = StringValueCStr(prefix_rb);
|
||||
prefix_len = RSTRING_LEN(prefix_rb);
|
||||
|
||||
if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
if (prefix_len > KERNAUX_NTOA_MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
rb_raise(
|
||||
rb_KernAux_TooLongNtoaPrefixError,
|
||||
"prefix length %ld is too long",
|
||||
|
@ -177,7 +175,7 @@ VALUE rb_KernAux_itoa(const int argc, const VALUE *argv, const VALUE self)
|
|||
prefix = StringValueCStr(prefix_rb);
|
||||
prefix_len = RSTRING_LEN(prefix_rb);
|
||||
|
||||
if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
if (prefix_len > KERNAUX_NTOA_MAX_PREFIX_LEN || prefix_len < 0) {
|
||||
rb_raise(
|
||||
rb_KernAux_TooLongNtoaPrefixError,
|
||||
"prefix length %ld is too long",
|
||||
|
|
|
@ -7,4 +7,4 @@ pub mod assert;
|
|||
pub mod ntoa;
|
||||
|
||||
pub use assert::*;
|
||||
pub use ntoa::*;
|
||||
pub use ntoa::{MAX_PREFIX_LEN as NTOA_MAX_PREFIX_LEN, *};
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use libc::{c_char, c_int};
|
||||
|
||||
pub const MAX_PREFIX_LEN: usize = 100;
|
||||
|
||||
pub const UTOA_MIN_BUFFER_SIZE: usize = 64 + 1;
|
||||
pub const ITOA_MIN_BUFFER_SIZE: usize = 65 + 1;
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use kernaux_sys::{
|
||||
use kernaux_sys::ntoa::{
|
||||
itoa as kernaux_itoa, itoa10 as kernaux_itoa10, itoa16 as kernaux_itoa16,
|
||||
itoa2 as kernaux_itoa2, itoa8 as kernaux_itoa8, utoa as kernaux_utoa,
|
||||
utoa10 as kernaux_utoa10, utoa16 as kernaux_utoa16, utoa2 as kernaux_utoa2,
|
||||
utoa8 as kernaux_utoa8, ITOA10_BUFFER_SIZE, ITOA16_BUFFER_SIZE,
|
||||
ITOA2_BUFFER_SIZE, ITOA8_BUFFER_SIZE, ITOA_MIN_BUFFER_SIZE,
|
||||
ITOA2_BUFFER_SIZE, ITOA8_BUFFER_SIZE, ITOA_MIN_BUFFER_SIZE, MAX_PREFIX_LEN,
|
||||
UTOA10_BUFFER_SIZE, UTOA16_BUFFER_SIZE, UTOA2_BUFFER_SIZE,
|
||||
UTOA8_BUFFER_SIZE, UTOA_MIN_BUFFER_SIZE,
|
||||
};
|
||||
|
@ -33,13 +33,13 @@ pub fn utoa(
|
|||
prefix: Option<&str>,
|
||||
) -> Result<String, Error> {
|
||||
if let Some(prefix) = prefix {
|
||||
if prefix.len() > 100 {
|
||||
if prefix.len() > MAX_PREFIX_LEN {
|
||||
return Err(Error::PrefixTooLong(prefix.len()));
|
||||
}
|
||||
}
|
||||
|
||||
let mut buffer: [i8; UTOA_MIN_BUFFER_SIZE + 100] =
|
||||
[0; UTOA_MIN_BUFFER_SIZE + 100];
|
||||
let mut buffer: [i8; UTOA_MIN_BUFFER_SIZE + MAX_PREFIX_LEN] =
|
||||
[0; UTOA_MIN_BUFFER_SIZE + MAX_PREFIX_LEN];
|
||||
|
||||
let prefix = if let Some(prefix) = prefix {
|
||||
Some(CString::new(prefix)?)
|
||||
|
@ -66,13 +66,13 @@ pub fn itoa(
|
|||
prefix: Option<&str>,
|
||||
) -> Result<String, Error> {
|
||||
if let Some(prefix) = prefix {
|
||||
if prefix.len() > 100 {
|
||||
if prefix.len() > MAX_PREFIX_LEN {
|
||||
return Err(Error::PrefixTooLong(prefix.len()));
|
||||
}
|
||||
}
|
||||
|
||||
let mut buffer: [i8; ITOA_MIN_BUFFER_SIZE + 100] =
|
||||
[0; ITOA_MIN_BUFFER_SIZE + 100];
|
||||
let mut buffer: [i8; ITOA_MIN_BUFFER_SIZE + MAX_PREFIX_LEN] =
|
||||
[0; ITOA_MIN_BUFFER_SIZE + MAX_PREFIX_LEN];
|
||||
|
||||
let prefix = if let Some(prefix) = prefix {
|
||||
Some(CString::new(prefix)?)
|
||||
|
|
11
src/ntoa.c
11
src/ntoa.c
|
@ -32,7 +32,16 @@ char *kernaux_utoa(uint64_t value, char *buffer, int base, const char *prefix)
|
|||
KERNAUX_ASSERT_RETVAL(base >= 2 && base <= 36, NULL);
|
||||
|
||||
// Write prefix
|
||||
if (prefix) while (*prefix) *(buffer++) = *(prefix++);
|
||||
if (prefix) {
|
||||
for (size_t prefix_len = 1; *prefix; ++prefix_len) {
|
||||
if (prefix_len > KERNAUX_NTOA_MAX_PREFIX_LEN) {
|
||||
// Protect caller from invalid state
|
||||
*buffer = '\0';
|
||||
KERNAUX_PANIC_RETVAL(prefix is too long, NULL);
|
||||
}
|
||||
*(buffer++) = *(prefix++);
|
||||
}
|
||||
}
|
||||
|
||||
// Write number
|
||||
char *pos = buffer;
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#define VALID_LONG_PREFIX "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
#define TOO_LONG_PREFIX "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
static const struct {
|
||||
const char *result;
|
||||
int base;
|
||||
|
@ -512,15 +515,21 @@ static const struct {
|
|||
|
||||
static unsigned int assert_count_exp = 0;
|
||||
static unsigned int assert_count_ctr = 0;
|
||||
|
||||
static const char *assert_last_file = NULL;
|
||||
static int assert_last_line = 0;
|
||||
static const char *assert_last_msg = NULL;
|
||||
|
||||
static void assert_cb(
|
||||
const char *const file,
|
||||
const int line __attribute__((unused)),
|
||||
const char *const msg __attribute__((unused))
|
||||
const int line,
|
||||
const char *const msg
|
||||
) {
|
||||
++assert_count_ctr;
|
||||
|
||||
assert_last_file = file;
|
||||
assert_last_line = line;
|
||||
assert_last_msg = msg;
|
||||
}
|
||||
|
||||
static void test_utoa_assert(char *const buffer, const int base)
|
||||
|
@ -528,6 +537,12 @@ static void test_utoa_assert(char *const buffer, const int base)
|
|||
assert(kernaux_utoa(0, buffer, base, NULL) == NULL);
|
||||
assert(assert_count_ctr == ++assert_count_exp);
|
||||
assert(strstr(assert_last_file, "src/ntoa.c") != NULL);
|
||||
assert(assert_last_line != 0);
|
||||
assert(assert_last_msg != NULL);
|
||||
|
||||
assert_last_file = NULL;
|
||||
assert_last_line = 0;
|
||||
assert_last_msg = NULL;
|
||||
}
|
||||
|
||||
static void test_itoa_assert(char *const buffer, const int base)
|
||||
|
@ -535,6 +550,12 @@ static void test_itoa_assert(char *const buffer, const int base)
|
|||
assert(kernaux_itoa(0, buffer, base, NULL) == NULL);
|
||||
assert(assert_count_ctr == ++assert_count_exp);
|
||||
assert(strstr(assert_last_file, "src/ntoa.c") != NULL);
|
||||
assert(assert_last_line != 0);
|
||||
assert(assert_last_msg != NULL);
|
||||
|
||||
assert_last_file = NULL;
|
||||
assert_last_line = 0;
|
||||
assert_last_msg = NULL;
|
||||
}
|
||||
|
||||
static const char *str_end(const char *str)
|
||||
|
@ -547,7 +568,28 @@ int main()
|
|||
kernaux_assert_cb = assert_cb;
|
||||
|
||||
{
|
||||
char buffer[KERNAUX_UTOA_MIN_BUFFER_SIZE];
|
||||
char buffer[KERNAUX_UTOA_MIN_BUFFER_SIZE + KERNAUX_NTOA_MAX_PREFIX_LEN];
|
||||
|
||||
const char *const end1 =
|
||||
kernaux_utoa(123, buffer, 'd', VALID_LONG_PREFIX);
|
||||
assert(strcmp(buffer, VALID_LONG_PREFIX"123") == 0);
|
||||
assert(end1 == str_end(buffer));
|
||||
assert(assert_count_ctr == assert_count_exp);
|
||||
assert(assert_last_file == NULL);
|
||||
assert(assert_last_line == 0);
|
||||
assert(assert_last_msg == NULL);
|
||||
|
||||
const char *const end2 =
|
||||
kernaux_utoa(123, buffer, 'd', TOO_LONG_PREFIX);
|
||||
assert(strcmp(buffer, VALID_LONG_PREFIX) == 0);
|
||||
assert(end2 == NULL);
|
||||
assert(assert_count_ctr == ++assert_count_exp);
|
||||
assert(strstr(assert_last_file, "src/ntoa.c") != NULL);
|
||||
assert(assert_last_line != 0);
|
||||
assert(strcmp(assert_last_msg, "prefix is too long") == 0);
|
||||
assert_last_file = NULL;
|
||||
assert_last_line = 0;
|
||||
assert_last_msg = NULL;
|
||||
|
||||
test_utoa_assert(NULL, 'd');
|
||||
test_utoa_assert(buffer, 0);
|
||||
|
@ -558,7 +600,28 @@ int main()
|
|||
}
|
||||
|
||||
{
|
||||
char buffer[KERNAUX_ITOA_MIN_BUFFER_SIZE];
|
||||
char buffer[KERNAUX_ITOA_MIN_BUFFER_SIZE + KERNAUX_NTOA_MAX_PREFIX_LEN];
|
||||
|
||||
const char *const end1 =
|
||||
kernaux_itoa(123, buffer, 'd', VALID_LONG_PREFIX);
|
||||
assert(strcmp(buffer, VALID_LONG_PREFIX"123") == 0);
|
||||
assert(end1 == str_end(buffer));
|
||||
assert(assert_count_ctr == assert_count_exp);
|
||||
assert(assert_last_file == NULL);
|
||||
assert(assert_last_line == 0);
|
||||
assert(assert_last_msg == NULL);
|
||||
|
||||
const char *const end2 =
|
||||
kernaux_itoa(123, buffer, 'd', TOO_LONG_PREFIX);
|
||||
assert(strcmp(buffer, VALID_LONG_PREFIX) == 0);
|
||||
assert(end2 == NULL);
|
||||
assert(assert_count_ctr == ++assert_count_exp);
|
||||
assert(strstr(assert_last_file, "src/ntoa.c") != NULL);
|
||||
assert(assert_last_line != 0);
|
||||
assert(strcmp(assert_last_msg, "prefix is too long") == 0);
|
||||
assert_last_file = NULL;
|
||||
assert_last_line = 0;
|
||||
assert_last_msg = NULL;
|
||||
|
||||
test_itoa_assert(NULL, 'd');
|
||||
test_itoa_assert(buffer, 0);
|
||||
|
|
Loading…
Add table
Reference in a new issue