I am currently recoding srtcat() from the standard C library and I have set up some checks to avoid overlap problems. The problem is that my program still enters the error handling.
Here is the code:
char *my_strcat(char *restrict dest, const char *restrict src) { size_t dest_len = 0, src_len = 0; char *p = dest; src_len = my_strlen(src); if (!dest || !src) return NULL; dest_len = my_strlen(dest); if (src >= dest && src < dest + dest_len) { return NULL; } if (dest >= src && dest < src + src_len) { return NULL; } while (*p != '\0') p++, dest_len++; if (dest_len + src_len + 1 > sizeof(dest)) return NULL; p = dest + dest_len; while (*src != '\0') *p++ = *src++; *p = '\0'; return dest; } size_t my_strlen(const char *s) { size_t count = 0; if (s != NULL) { while (*s != 0) { count++; s++; } } return count; } I tested this way :
int main(int argc, char **argv) { const char *src = "Hello"; char dest[100] = " world!"; char *test = my_strcat(dest, src); printf("Src : %s Dest : %s\n", src, dest); printf("Return adress : %p, Value : %s\n", test, test); return 0; } According to gdb :
if (src >= dest && src < dest + dest_len) 1: dest = 0x7fffffffda70 " world!" 2: src = 0x555555557004 "Hello" 3: dest_len = 0 4: src_len = 5 Output
Src : Hello Dest : world! Return adress : (nil), Value : (null) Do you see the problem?
Update
Following your suggestions I have modified the code like this:
char *my_strcat(char *restrict dest, const char *restrict src, size_t d_size) { size_t dest_len = 0, src_len = 0; char *p = dest; if (!dest || !src) return NULL; src_len = my_strlen(src); dest_len = my_strlen(dest); if (src >= dest && src < dest + dest_len) { return NULL; } if (dest >= src && dest < src + src_len) { return NULL; } while (*p != '\0') p++, dest_len++; if (dest_len + src_len + 1 > d_size) return NULL; p = dest + dest_len; while (*src != '\0') *p++ = *src++; *p = '\0'; return dest; } And in the main : char *test = my_strcat(dest, src, sizeof(dest));
But it still doesn't work :
Src : Hello Dest : world! Return adress : 0x7fff74bc5650, Value : world!
sizeof(dest)in the function measures the size of the pointer. The function must be told by the caller the size of the destination array (in a 3rd parameter). The caller can see the array andsizeofmakes sense (as long as the elements are only 1 byte.) The function, as is, only receives the address of the first byte; nothing more...strcat()can be dangerous if used indiscriminately. When the function only gets pointers (addresses), it's up to the caller to make sure there's room in the destination array. (C's strings are null-terminated. You could, if you can, define some other "sentinel" to mark the absolute end ofdest, but this would be considered "hacky" and would make one more special byte value that cannot appear as ordinary data.if (!dest || !src)should be place beforesrc_len = my_strlen(src);Return adress : 0x7ffc573e3db0, Value : world!