簡體   English   中英

兩個字符串之間的重疊驗證問題

[英]Problem of overlap verification between two strings

我目前正在從標准 C 庫重新編碼srtcat()並且我已經設置了一些檢查以避免重疊問題。 問題是我的程序還是進入了錯誤處理。

這是代碼:

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;
}

我是這樣測試的:

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;
}

根據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)

你看到問題了嗎?

更新

根據您的建議,我修改了如下代碼:

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;
}

主要是: char *test = my_strcat(dest, src, sizeof(dest));

但它仍然不起作用:

Src : Hello Dest :  world!
Return adress : 0x7fff74bc5650, Value :  world!

在試圖引導理解這個問題之后,最好的辦法似乎是展示什么應該是工作代碼(供研究)。有時太多的詞只會混淆情況:

char *my_strcat(char *restrict dest, const char *restrict src, size_t d_size) {
    if( !dest || !src )
        return NULL;

    size_t src_len = strlen( src );
    size_t dest_len = strlen( dest );

    if( dest_len + src_len + 1 > d_size )
        return NULL;

    char *p = dest + dest_len;
    while( (*p++ = *src++ ) != '\0' )
        ;

    return dest;
}

int main() {
    const char *src = "Hello";
    char dest[100] = " world!";
    printf("Src : %s Dest : %s\n", src, dest);

    char *test = my_strcat( dest, src, sizeof dest );

    if( test )
        printf("Value : %s\n", test );

    return 0;
}

現在,可以通過將dest的大小縮小到大於“world”的大小來進行實驗。 但比“world.Hello”小?? 也許 9 個字節???

而且,既然串聯應該起作用(進入足夠大的緩沖區),添加代碼以確保實際字符 arrays 沒有重疊。已知 dest 的大小,並測量 src 的長度。

dest_len + src_len + 1 > sizeof(dest)

sizeof(dest)是指針sizeof(char*)的大小。 如果你想檢查dest是否會溢出,你必須將大小作為參數傳遞。 請參閱strlcpystrncpy

 src >= dest

請注意,比較不指向同一數組的指針在技術上是無效的。 為了帶來一些有效性,您可以執行(uintptr_t)stc >= (uintptr_t)dest 指針比較在 C 中如何工作? 可以比較不指向同一個數組的指針嗎? 如果兩個指針都被強制轉換為 integer 類型,是否正在比較具有 < undefined 行為的指針? 為什么比較具有未定義行為的指針仍會給出正確的結果? 等等

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM