3

My code

#include "libft.h"

size_t  ft_count_words(const char *s, char c)
{
    size_t  i;
    size_t  count;
    size_t  ibool;

    i = 0;
    count = 0;
    ibool = 1;
    while (*s)
    {
        while (*s == c && *s)
            s++;
        while (*s != c && *s)
        {
            if (ibool == 1)
                count++;
            ibool = 0;
            s++;
        }
        ibool = 1;
    }
    return (count);
}

size_t  ft_splitlen(const char *str, char c)
{
    size_t  i;

    i = 0;
    while (str[i] != c && str[i])
        i++;
    return (i);
}

char    *ft_splitdup(const char *str, char c)
{
    char    *word;
    size_t  i;

    i = 0;
    if (!(word = (char *)malloc((ft_splitlen(str, c) + 1) * sizeof(char))))
        return (NULL);
    while (str[i] != c && str[i])
    {
        word[i] = str[i];
        i++;
    }
    word[i] = '\0';
    return (word);
}

char    **ft_splitfree(char **base_split)
{
    size_t  i;

    i = 0;
    while (base_split[i])
    {
        free(base_split[i]);
        i++;
    }
    free(base_split);
    return (NULL);
}

char    **ft_split(const char *s, char c)
{
    char    **best_split;
    size_t  i;
    size_t  j;

    if (!s || (!s && !c))
        return (NULL);
    i = 0;
    j = 0;
    if (!(best_split = (char **)malloc(sizeof(char *) *\
        ft_count_words(s, c) + 1)))
        return (NULL);
    while (s[i])
    {
        while (s[i] == c && s[i])
            i++;
        while (s[i] != c && s[i])
        {
            if (!(best_split[j] = ft_splitdup(s + i, c)))
                return (ft_splitfree(best_split));
            i += ft_splitlen(s + i, c);
            j++;
        }
    }
    best_split[j] = NULL;
    return (best_split);
}

#include <stdio.h>

int                 main()
{
    char **test;
    test = ft_split("a b c d e", ' ');
    int i = 0;
    while (test[i])
    {
        printf("%d\t", i);
        printf("%s\n", test[i]);
        i++;
    }
}

And ASAN result

=================================================================
==2643==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x604000000038 at pc 0x5650a051182c bp 0x7ffc19904370 sp 0x7ffc19904360
WRITE of size 8 at 0x604000000038 thread T0
    #0 0x5650a051182b in ft_split (/home/taemkim/42_cursus/libft/test+0x182b)
    #1 0x5650a0511856 in main (/home/taemkim/42_cursus/libft/test+0x1856)
    #2 0x7f85cd8670b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #3 0x5650a05111ed in _start (/home/taemkim/42_cursus/libft/test+0x11ed)

0x604000000039 is located 0 bytes to the right of 41-byte region [0x604000000010,0x604000000039)
allocated by thread T0 here:
    #0 0x7f85cdb3fbc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #1 0x5650a051162b in ft_split (/home/taemkim/42_cursus/libft/test+0x162b)
    #2 0x5650a0511856 in main (/home/taemkim/42_cursus/libft/test+0x1856)
    #3 0x7f85cd8670b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/taemkim/42_cursus/libft/test+0x182b) in ft_split
Shadow bytes around the buggy address:
  0x0c087fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c087fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c087fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c087fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c087fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c087fff8000: fa fa 00 00 00 00 00[01]fa fa fa fa fa fa fa fa
  0x0c087fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==2643==ABORTING

I seem to have made the proper memory allocation. but result is heap-buffer-overflow.

ex) if ft_split("a b c d e", ' '),

best_split = (char **)malloc(sizeof(char *) * 5 + 1

best_split = [a, b, c, d, e, NULL]

I separated each character with a blank space, and added 1 because of the space for NULL.

I think good count and good size.

Why did this result? How do i fix this code?

Paul Floyd
  • 5,530
  • 5
  • 29
  • 43
taemkim
  • 43
  • 1
  • 4

1 Answers1

3

A heap buffer overflow is when you access outside an array that was allocated on the heap (i.e. using malloc()).

The problem is that the best_split array isn't big enough.

malloc(sizeof(char *) * ft_count_words(s, c) + 1)

multiplies the size of a pointer by the number of words, then adds only 1 byte to that, not the size of a pointer. You need to add 1 to the number of words so you get enough memory for the additional null pointer.

malloc(sizeof(char *) * (ft_count_words(s, c) + 1))

P.S. see Do I cast the result of malloc?

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Really thank you! It was a very rudimentary mistake. Now, I will catch memory leaks. haha... Thank you!! – taemkim Dec 08 '20 at 02:51