From 450e36f8ddf974e503731288c8d8bb8c62e67e47 Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 17 Jul 2020 16:33:45 +0200 Subject: Fixing ft_strtol overflow --- .gitignore | 1 + include/libft_lst.h | 3 +- script/generate_boilerplate_test.sh | 9 --- src/str/ft_strtol.c | 24 ++++--- test/src/ht/test_ft_htget.c | 2 - test/src/ht/test_ft_htnew.c | 4 +- test/src/main.c | 3 + test/src/runner/test_runner_str.c | 6 ++ test/src/str/test_ft_strtol.c | 129 ++++++++++++++++++++++++++++++++++++ 9 files changed, 158 insertions(+), 23 deletions(-) delete mode 100755 script/generate_boilerplate_test.sh create mode 100644 test/src/str/test_ft_strtol.c diff --git a/.gitignore b/.gitignore index 6d5b87d..cf870d3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ rendu.makefile doc/* tmp/* *.gz +vgcore.* diff --git a/include/libft_lst.h b/include/libft_lst.h index 2938bd2..1d02b4e 100644 --- a/include/libft_lst.h +++ b/include/libft_lst.h @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/01/31 10:36:39 by cacharle #+# #+# */ -/* Updated: 2020/04/01 17:59:50 by charles ### ########.fr */ +/* Updated: 2020/07/13 13:11:55 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -52,6 +52,7 @@ void ft_lstreverse(t_ftlst **lst); void ft_lstremove_if(t_ftlst **lst, t_ftcompar_func cmp, const void *ref, t_ftdel_func del); +void ft_lstinsert(t_ftlst **lst, t_ftlst *insert, size_t i); t_ftlst *ft_lstbsearch(t_ftlst *lst, t_ftcompar_func cmp, const void *ref); t_ftlst *ft_lstlsearch(t_ftlst *lst, t_ftcompar_func cmp, diff --git a/script/generate_boilerplate_test.sh b/script/generate_boilerplate_test.sh deleted file mode 100755 index ef6a2cf..0000000 --- a/script/generate_boilerplate_test.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -for f in $@ -do - test_name="test_`basename $f | sed 's/\..*//'`" - - - echo $test_name -done diff --git a/src/str/ft_strtol.c b/src/str/ft_strtol.c index 82276d8..925c66d 100644 --- a/src/str/ft_strtol.c +++ b/src/str/ft_strtol.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/01/15 10:26:45 by cacharle #+# #+# */ -/* Updated: 2020/02/10 02:21:16 by cacharle ### ########.fr */ +/* Updated: 2020/07/17 16:29:33 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -39,10 +39,10 @@ static int st_strtol_handle_base(int base, const char **str) return (10); } -static long st_errno_return(int err) +static long st_errno_return(int err, long ret) { errno = err; - return (0); + return (ret); } /* @@ -53,9 +53,9 @@ static long st_errno_return(int err) long ft_strtol(const char *str, char **endptr, int base) { - t_ftbool is_negative; - long long nb; - char base_str[37]; + t_ftbool is_negative; + unsigned long long nb; + char base_str[37]; while (ft_isspace(*str)) str++; @@ -63,16 +63,24 @@ long ft_strtol(const char *str, char **endptr, int base) if (*str == '-' || *str == '+') str++; if ((base = st_strtol_handle_base(base, &str)) == -1) - return (st_errno_return(EINVAL)); + return (st_errno_return(EINVAL, 0)); ft_strncpy(base_str, STRTOL_STD_BASE, base); base_str[base] = '\0'; nb = 0; while (*str != '\0' && ft_strchr(base_str, *str) != NULL) { nb *= base; + if (is_negative ? (nb > -(unsigned long long)LONG_MIN) : (nb > LONG_MAX)) + { + errno = ERANGE; + return (is_negative ? LONG_MIN : LONG_MAX); + } nb += ft_strchr(base_str, ft_tolower(*str++)) - base_str; - if (((long)nb ^ (long)(nb / base)) < 0) + if (is_negative ? (nb > -(unsigned long long)LONG_MIN) : (nb > LONG_MAX)) + { errno = ERANGE; + return (is_negative ? LONG_MIN : LONG_MAX); + } } if (endptr != NULL) *endptr = (char*)str; diff --git a/test/src/ht/test_ft_htget.c b/test/src/ht/test_ft_htget.c index 4d4b4eb..cddec56 100644 --- a/test/src/ht/test_ft_htget.c +++ b/test/src/ht/test_ft_htget.c @@ -14,8 +14,6 @@ TEST_TEAR_DOWN(ft_htget) /* ft_htdestroy_key(ht); */ } -int helper_segfault_pid; - TEST(ft_htget, segfault) { TEST_ASSERT_SEGFAULT(ft_htget((t_ftht*)NULL, "")); diff --git a/test/src/ht/test_ft_htnew.c b/test/src/ht/test_ft_htnew.c index 17bca6a..b68daa6 100644 --- a/test/src/ht/test_ft_htnew.c +++ b/test/src/ht/test_ft_htnew.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/12 22:30:06 by cacharle #+# #+# */ -/* Updated: 2020/02/28 12:15:32 by cacharle ### ########.fr */ +/* Updated: 2020/07/17 14:17:11 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,8 +20,6 @@ TEST_SETUP(ft_htnew) TEST_TEAR_DOWN(ft_htnew) {} -int helper_segfault_pid; - TEST(ft_htnew, segfault) { TEST_ASSERT_SEGFAULT(ft_htnew(10)); diff --git a/test/src/main.c b/test/src/main.c index e962577..9636cf7 100644 --- a/test/src/main.c +++ b/test/src/main.c @@ -1,5 +1,7 @@ #include "libft_test.h" +int helper_segfault_pid = -1; + static void run_all_test(void) { // ctype @@ -34,6 +36,7 @@ static void run_all_test(void) RUN_TEST_GROUP(ft_strsjoinf); RUN_TEST_GROUP(ft_strsub); RUN_TEST_GROUP(ft_strsubf); + RUN_TEST_GROUP(ft_strtol); // ht RUN_TEST_GROUP(ft_htentry_new); diff --git a/test/src/runner/test_runner_str.c b/test/src/runner/test_runner_str.c index 8d3b68a..6806060 100644 --- a/test/src/runner/test_runner_str.c +++ b/test/src/runner/test_runner_str.c @@ -29,3 +29,9 @@ TEST_GROUP_RUNNER(ft_strsubf) { RUN_TEST_CASE(ft_strsubf, basic); } + +TEST_GROUP_RUNNER(ft_strtol) +{ + RUN_TEST_CASE(ft_strtol, basic); + RUN_TEST_CASE(ft_strtol, limits); +} diff --git a/test/src/str/test_ft_strtol.c b/test/src/str/test_ft_strtol.c new file mode 100644 index 0000000..eacaa82 --- /dev/null +++ b/test/src/str/test_ft_strtol.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* test_ft_strtol.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/04/01 19:41:59 by charles #+# #+# */ +/* Updated: 2020/07/17 16:31:20 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft_test.h" + +TEST_GROUP(ft_strtol); + +TEST_SETUP(ft_strtol) +{} + +TEST_TEAR_DOWN(ft_strtol) +{} + +static long expected; +static long actual; +static char *expected_rest; +static char *actual_rest; +static int expected_errno; +static int actual_errno; +static char error_buf[2048]; + +static char *rest = NULL; + +#define TEST_ASSERT_FT_STRTOL(str, base) do { \ + errno = 0; \ + expected = strtol(str, &rest, base); \ + expected_rest = rest; \ + expected_errno = errno; \ + errno = 0; \ + actual = ft_strtol(str, &rest, base); \ + actual_rest = rest; \ + actual_errno = errno; \ + if (actual != expected || actual_errno != expected_errno || expected_rest != actual_rest) \ + { \ + snprintf(error_buf, 2048, \ + "with: ("#str", "#base") expected: %ld actual: %ld " \ + "rest: expected: \"%s\" actual: \"%s\" " \ + "errno: expected: %d actual: %d", \ + expected, actual, expected_rest, actual_rest, expected_errno, actual_errno); \ + TEST_FAIL_MESSAGE(error_buf); \ + } \ +} while(0); + +TEST(ft_strtol, basic) +{ + TEST_ASSERT_FT_STRTOL("", 10); + TEST_ASSERT_FT_STRTOL("0", 10); + TEST_ASSERT_FT_STRTOL("000000000", 10); + TEST_ASSERT_FT_STRTOL("1", 10); + TEST_ASSERT_FT_STRTOL("2", 10); + TEST_ASSERT_FT_STRTOL("3", 10); + TEST_ASSERT_FT_STRTOL("4", 10); + TEST_ASSERT_FT_STRTOL("5", 10); + TEST_ASSERT_FT_STRTOL("6", 10); + TEST_ASSERT_FT_STRTOL("7", 10); + TEST_ASSERT_FT_STRTOL("8", 10); + TEST_ASSERT_FT_STRTOL("9", 10); + TEST_ASSERT_FT_STRTOL("000000000000000000000000000000000000000000000000000000000008", 10); + + TEST_ASSERT_FT_STRTOL(" 9", 10); + TEST_ASSERT_FT_STRTOL(" \v \t\f\t\t\t\n\r\f\r\v9", 10); + /* TEST_ASSERT_FT_STRTOL(" \v . \t\f\t\t\t\n\r\f\r\v9", 10); */ // dont really care atm + TEST_ASSERT_FT_STRTOL(" 9bonjour", 10); + TEST_ASSERT_FT_STRTOL(" \v \t\f\t\t\t\n\r\f\r\v9 \t\t\v\r\f\r", 10); + /* TEST_ASSERT_FT_STRTOL(" \v . \t\f\t\t\t\n\r\f\r\v9 \t bonjour", 10); */ +} + +TEST(ft_strtol, limits) +{ + TEST_ASSERT_FT_STRTOL("-128", 10); + TEST_ASSERT_FT_STRTOL("127", 10); + TEST_ASSERT_FT_STRTOL("255", 10); + TEST_ASSERT_FT_STRTOL("-128", 10); + TEST_ASSERT_FT_STRTOL("127", 10); + TEST_ASSERT_FT_STRTOL("-32768", 10); + TEST_ASSERT_FT_STRTOL("32767", 10); + TEST_ASSERT_FT_STRTOL("65535", 10); + TEST_ASSERT_FT_STRTOL("-2147483648", 10); + TEST_ASSERT_FT_STRTOL("2147483647", 10); + TEST_ASSERT_FT_STRTOL("4294967295", 10); + TEST_ASSERT_FT_STRTOL("-9223372036854775808", 10); + TEST_ASSERT_FT_STRTOL("9223372036854775807", 10); + TEST_ASSERT_FT_STRTOL("18446744073709551615", 10); + + TEST_ASSERT_FT_STRTOL("-129", 10); + TEST_ASSERT_FT_STRTOL("126", 10); + TEST_ASSERT_FT_STRTOL("254", 10); + TEST_ASSERT_FT_STRTOL("-127", 10); + TEST_ASSERT_FT_STRTOL("126", 10); + TEST_ASSERT_FT_STRTOL("-32767", 10); + TEST_ASSERT_FT_STRTOL("32766", 10); + TEST_ASSERT_FT_STRTOL("65534", 10); + TEST_ASSERT_FT_STRTOL("-2147483647", 10); + TEST_ASSERT_FT_STRTOL("2147483646", 10); + TEST_ASSERT_FT_STRTOL("4294967294", 10); + TEST_ASSERT_FT_STRTOL("-9223372036854775807", 10); + TEST_ASSERT_FT_STRTOL("9223372036854775806", 10); + TEST_ASSERT_FT_STRTOL("18446744073709551614", 10); + + TEST_ASSERT_FT_STRTOL("-129", 10); + TEST_ASSERT_FT_STRTOL("128", 10); + TEST_ASSERT_FT_STRTOL("256", 10); + TEST_ASSERT_FT_STRTOL("-129", 10); + TEST_ASSERT_FT_STRTOL("128", 10); + TEST_ASSERT_FT_STRTOL("-32769", 10); + TEST_ASSERT_FT_STRTOL("32768", 10); + TEST_ASSERT_FT_STRTOL("65536", 10); + TEST_ASSERT_FT_STRTOL("-2147483649", 10); + TEST_ASSERT_FT_STRTOL("2147483648", 10); + TEST_ASSERT_FT_STRTOL("4294967296", 10); + TEST_ASSERT_FT_STRTOL("-9223372036854775809", 10); + TEST_ASSERT_FT_STRTOL("9223372036854775808", 10); + TEST_ASSERT_FT_STRTOL("18446744073709551616", 10); + + TEST_ASSERT_FT_STRTOL("-9223372036854775809", 10); + TEST_ASSERT_FT_STRTOL("9223372036854775808", 10); + TEST_ASSERT_FT_STRTOL("-9223372036854775808", 10); + TEST_ASSERT_FT_STRTOL("18446744073709551615", 10); + TEST_ASSERT_FT_STRTOL("18446744073709551616", 10); +} -- cgit