Memory confusion for strncpy in C

This week, my colleague discussed one problem:

Code Example 1:

int main()
{
    #define Str "This is String."
    char dest[1];
    char buff[10];

    strncpy(dest, Str, sizeof(Str));
    printf("Dest: %s\n", dest);
    printf("Buff: %s\n", buff);
}

Output:

Dest: This is String.
Buff: his is String.

Code Example 2:

int main()
{
    #define Str "This is String."
    char dest[1];
    //char buff[10];

    strncpy(dest, Str, sizeof(Str));
    printf("Dest: %s\n", dest);
    //printf("Buff: %s\n", buff);
}

Conclusion:

Dest: This is String.
*** stack smashing detected ***: ./test terminated
Aborted (core dumped)

I do not understand why I get this conclusion in case 1? since buff is not even used in strncpy, and if I comment on the buff variable, it will detect a stack split, but with the output for dest. Also for buff, why do I get Output as "its like a string".

+4
source share
4 answers

, - . , , " " . ( undefined ). , , ,

enter image description here

, , . strncpy

enter image description here

, , , buf "h". Printf , , . , " " buf. , 1 - ( /). , , , 1 ( , Str ).

2 strncpy , main , , .

, .

P.S. .

+4

C strncpy :

7.24.2.4 strncpy

#include <string.h>
 char *strncpy(char * restrict s1,
      const char * restrict s2,
      size_t n);

strncpy n (, , ) , s2, , s1.

, undefined.

, s2, , n, , s1, , , n .

strncpy s1.

: strncpy strcpy, NOT , n.

n : undefined, .

, , buff dest ( ) strncpy. , .

: . C, : strncpy !

, ​​ :

// Utility function: copy with truncation, return source string length
// truncation occurred if return value >= size argument
size_t bstrcpy(char *dest, size_t size, const char *src) {
    size_t i;
    /* copy the portion that fits */
    for (i = 0; i + 1 < size && src[i] != '\0'; i++) {
        dest[i] = src[i];
    }
    /* null terminate destination unless size == 0 */
    if (i < size) {
        dest[i] = '\0';
    }
    /* compute necessary length to allow truncation detection */
    while (src[i] != '\0') {
        i++;
    }
    return i;
}

:

int main(void) {
    #define Str "This is String."
    char dest[12];

    // the size of the destination array is passed
    // after the pointer, just as for `snprintf`
    bstrcpy(dest, sizeof dest, Str);
    printf("Dest: %s\n", dest);
    return 0;
}

:

This is a S
+3

: -

0. dest
1. buff
12. canary
16. Return address

buff, .

undefined ( dest, ). , . .

undefined , " @xxxxxx" - . , , .

. dest vs buff . , , , printf, , , dest, , , , .

0

strncpy(dest, Str, sizeof(Str));

dest - , , , undefined. , , .

buf , dest buf. , dest, buf. buf, .

, , , .

Summary: never do anything that causes undefined behavior. In strncpyyou should use sizeof(dest), and not sizeof(src)allocate enough memory for the destination, so that data from the source is not lost.

0
source

Source: https://habr.com/ru/post/1663814/


All Articles