在数组中设置值会导致分段错误

问题描述 投票:0回答:0

我有一个函数可以从字符串中提取出 pgn 元数据(标签对) 并将它们放入一个结构中。结构定义为:

typedef struct {
    char key[15];
    char value[31];
} metadata_txt;

功能:

// (szt is size_t and u8f is uint_fast8_t)
void carve_metadata(char* line, metadata_txt* metadata_buf) {
    if (metadata_buf == NULL) {
        console_error("PANIC. METADATA_BUF IS NULL %s, %d, %s", __FILE__, __LINE__, __FUNCTION__);
        exit(1);
    }

    if (line == NULL) {
        console_error("PANIC. LINE IS NULL %s, %d, %s", __FILE__, __LINE__, __FUNCTION__);
        exit(1);
    }

    register szt length = strlen(line);
    if (length < 5) {
        console_error("PANIC. LINE LENGTH IS LESS THAN 5 %s, %d, %s", __FILE__, __LINE__, __FUNCTION__); 
        // The smallest valid tag pair should be [ ""] whichs length is 5.
    }
    
    // Example input string: [Foo "Bar"] 
    line++; length--; // Remove the `[` ==> Foo "Bar"]
    line[length-1] = '\0'; line[length-2] = '\0'; length -= 2; // Removes the ending `"]` ==> Foo "Bar 
    
    // Extract the key
    register u8f i = 0;

    while (*line != ' ') {
        // printf("%c | i: %d | line: %s\n", *line, i, line); fflush(stdout);
        metadata_buf->key[i] = *line;
        i++; line++; length--;
    } // ==> "Bar
    
    line += 2; length -= 2; // Remove the ` "`. ==> Bar 
    // Now, all that's left in line is the value. So we can copy it into the metadata_buf->value
    strncpy(metadata_buf->value, line, length);
}

使用-fsanitize=address编译程序后,发现是metadata_buf->key[i] = *line;这一行引起的crash。我进一步调查,发现 i 在这种情况下是 0。另外,metadata_buf is 初始化为 0。

输入字符串 (char* line): [Site "Buenos Aires"]

fsanitize 输出:

==906==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffe1c40c2 at pc 0x7fa318a914fc bp 0x7ffffe1c3a80 sp 0x7ffffe1c3a70
WRITE of size 1 at 0x7ffffe1c40c2 thread T0
    #0 0x7fa318a914fb in carve_metadata src/convert.c:55
    #1 0x7fa318a92941 in convert_pgn_to_cmbr src/convert.c:199
    #2 0x7fa318a937d3 in main src/main.c:68
    #3 0x7fa317e19d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #4 0x7fa317e19e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #5 0x7fa318a90204 in _start (/mnt/c/Users/datag/Desktop/programming/c/cmbr/out/main+0x5204)

(这是在 wsl 下运行的)

编译标志:-Wall -Wextra -Werror -std=c99 -fuse-ld=mold -fsanitize=address -ggdb

抄送:gcc

我尝试使用 -fsanitize=address 和 printf 调试。使用 gdb 是不可能的,因为我在 WSL 上运行

提前谢谢你。

c buffer-overflow
© www.soinside.com 2019 - 2024. All rights reserved.