🐛 fix memory out of bound error in str module

This commit is contained in:
ValKmjolnir 2024-10-30 00:12:48 +08:00
parent f15ff19517
commit 67c4a448ae
3 changed files with 34 additions and 12 deletions

View File

@ -41,8 +41,8 @@ jobs:
make colgm.ll
/opt/homebrew/opt/llvm@17/bin/clang colgm.ll -o colgm
./colgm
./colgm src/main.colgm --lex --ast
./colgm src/lexer.colgm --lex --ast
./colgm src/main.colgm --ast
./colgm src/lexer.colgm --ast
- name: release
run: |
tar -czf colgm-mac-nightly.tgz .
@ -75,8 +75,8 @@ jobs:
make colgm.ll
/usr/bin/clang-14 colgm.ll -o colgm
./colgm
./colgm src/main.colgm --lex --ast
./colgm src/lexer.colgm --lex --ast
./colgm src/main.colgm --ast
./colgm src/lexer.colgm --ast
- name: release
run: |
touch colgm-linux-x86_64-nightly.tgz

View File

@ -14,9 +14,6 @@ pub enum flag {
}
pub func readfile_into_string(filename: i8*, dst: str*) -> i64 {
io::stdout().out("remained info size: ")
.out_i64(dst->size => i64)
.out(" in 0x").out_hex(dst->c_str => i64).out("\n");
var fd = open(filename, (flag::O_RDONLY => i32) | (flag::O_BINARY => i32));
if (fd < (0 => i32)) {
return fd => i64;
@ -36,8 +33,6 @@ pub func readfile_into_string(filename: i8*, dst: str*) -> i64 {
}
}
io::stdout().out("load into 0x").out_hex(dst->c_str => i64)
.out(", size ").out_i64(dst->size => i64).out("\n");
close(fd);
return 0;
}

View File

@ -21,11 +21,11 @@ impl str {
}
pub func init(self) {
self->c_str = malloc(256 => u64);
self->c_str = malloc(16 => u64);
self->c_str[0] = '\0';
self->size = 0 => u64;
self->capacity = 256 => u64;
self->capacity = 16 => u64;
}
pub func copy_instance(self) -> str {
@ -84,7 +84,34 @@ impl str {
}
pub func append_char(self, ch: i8) -> str* {
if (self->size == self->capacity) {
// self->size == self->capacity will cause memory out of bounds error
// but only crashes on macOS aarch64
// crash happens in this case:
//
// | str 1 capacity 8 | str 2 capacity 8 |
// -^- continuous allocated memory block
// | str 1 | str 2 |
// |+++++++0| |
// ^ size = 7 (real 8), capacity = 8
//
// if expands when size + 1 == capacity
// | str 1 | str 2 |
// |++++++++0 | |
// ^ size = 8 (real 9), capacity = 16
//
// if not
// | str 1 | str 2 |
// |++++++++0 |
// ^ size = 8 (real 9), capacity = 8
// ^ this breaks the memory block of str2
//
// so after str2 is freed, the memory block head is still broken
// and then we use malloc to allocate this memory block again
// and free again, the memory block will cause
// "free(): invalid pointer"
// "malloc: *** error for object 0x.....: pointer being freed was not allocated"
// that's wired T^T
if (self->size + (1 => u64) == self->capacity) {
self->expand_capacity();
}