Created
December 22, 2025 07:59
-
-
Save ClarkeRemy/ec5420c62be7d45b336e5f5fb7fece4c to your computer and use it in GitHub Desktop.
Bad String Concat in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdint.h> | |
| #include <stdlib.h> | |
| struct ByteSlice { uint8_t* ptr; uintptr_t len; }; | |
| /* caution this removes the null terminated char! */ | |
| struct ByteSlice nullTerminated_slice(uint8_t* str) { | |
| uintptr_t len = 0; | |
| if (str != 0) for (uint8_t* cursor = str; *cursor != 0; cursor+=1) { | |
| len+=1; | |
| } | |
| return (struct ByteSlice){ .ptr = str, .len = len }; | |
| } | |
| struct MyString | |
| { | |
| struct ByteSlice slice ; | |
| uintptr_t capacity; | |
| }; | |
| struct ByteSlice null_byte = { .ptr = "", .len = 1 }; | |
| struct ByteSlice myString_as_slice( struct MyString* string ) { | |
| return string->slice; | |
| } | |
| uint8_t* byteSlice_end(struct ByteSlice* slice) { | |
| return slice->ptr + slice->len; | |
| } | |
| struct MyString concat_strs ( struct ByteSlice* start, uintptr_t len ) | |
| { | |
| uintptr_t total_len = 0; | |
| struct ByteSlice* end = start + len; | |
| for ( struct ByteSlice* cursor = start; cursor != end; cursor+=1){ | |
| total_len += cursor->len; | |
| } | |
| uint8_t* ptr = malloc(total_len); | |
| uint8_t* out_cursor = ptr; | |
| for ( struct ByteSlice* cursor = start; cursor != end; cursor+=1) { | |
| uint8_t * slice_end = byteSlice_end(cursor); | |
| for (uint8_t* slice_cursor = cursor->ptr; slice_cursor != slice_end; slice_cursor+=1){ | |
| *out_cursor = *slice_cursor; | |
| out_cursor+=1; | |
| } | |
| } | |
| struct ByteSlice out_slice = { .ptr = ptr, .len = total_len }; | |
| return (struct MyString){ .slice = out_slice, .capacity = total_len }; | |
| } | |
| int main() { | |
| uint8_t* ab= "ab"; | |
| uint8_t* cd= "cd"; | |
| uint8_t* ef= "ef"; | |
| struct ByteSlice slices[5] = { | |
| nullTerminated_slice(ab), | |
| nullTerminated_slice(cd), | |
| nullTerminated_slice(ef), | |
| nullTerminated_slice("ghij"), | |
| null_byte, | |
| }; | |
| struct MyString front = concat_strs(slices, 4); | |
| printf("%s\n", front.slice.ptr); | |
| front.slice.len-=1; // remove null byte | |
| struct ByteSlice more[3] = { | |
| myString_as_slice(&front), | |
| nullTerminated_slice("xyz"), | |
| null_byte, | |
| }; | |
| struct MyString final = concat_strs(more, 3); | |
| printf("%s\n", final.slice.ptr); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment