Home > other >  Why does strncpy() produce garbage when the dest is smaller than the src but large enough to fit the
Why does strncpy() produce garbage when the dest is smaller than the src but large enough to fit the

Time:07-09

I tried to limit the number of n bytes copied to dest (here str1) by using strncpy(). The dest is big enough for the n bytes, but the output produced garbage when dest is smaller than the source (here argv[1]). This looks different, when i make dest large enough to hold the source.

Here's the code:

#include <stdio.h>                                                              
#include <string.h>                                                             
                                                                                
int main(int argc, char *argv[])                                                
{                                                                               
/* // Works when str1[?] is 20:                                                                    
  char str1[20];                                                                
  char str2[20]; */                                                             
                                                                                
  // produces garbage, str1 is smaller than argv[1] but big enough for the 4 bytes copied                                                            
  char str1[10];                                                                
  char str2[10];                                                                
                                                                                
  printf("argc = %i\n", argc);                                                  
  if (argc <= 1 || argc > 2){                                                   
    printf("Input Example:\n"                                                   
           "  %s SEGMENT:OFFSET\n"                                              
           "  %s 0100:F00A\n", argv[0], argv[0]);                               
    return 0;                                                                   
  }                                                                             
  printf("strlen(argv[1]) = %li, argv[1] = %s\n"                                
          , strlen(argv[1]), argv[1]);                                          
                                                                                
  // str1                                                                       
  strncpy(str1, argv[1], 4); // copying 4 bytes to str1                                                   
  printf("Copy only 4 Bytes -> sizeof(str1) = %li, "                            
         "strlen(str1) = %li, str1 = %s\n", sizeof(str1), strlen(str1), str1);  
                                                                                
  // str2                                                                       
  strncpy(str2, argv[1], 3); // copying 3 bytes to str2                                                   
  printf("Copy only 3 Bytes -> sizeof(str2) = %li, "                            
         "strlen(str2) = %li, str2 = %s\n", sizeof(str2), strlen(str2), str2);  
                                                                                
  return 0;                                                                     
}                      

The input of 0100:F00A produces:

./test.bin 0100:F00A
argc = 2
strlen(argv[1]) = 9, argv[1] = 0100:F00A
Copy only 4 Bytes -> sizeof(str1) = 10, strlen(str1) = 8, str1 = 0100�U
Copy only 3 Bytes -> sizeof(str2) = 10, strlen(str2) = 3, str2 = 010

Expected was just str1 = 0100.

I also do wonder why str2 is correct, its initial array size is as small as str1.

When i change

char str1[10] 

to

char str1[20]

and by doing so make it larger than the input of argv[1], then the output is correct:

./test.bin 0100:F00A
argc = 2
strlen(argv[1]) = 9, argv[1] = 0100:F00A
Copy only 4 Bytes -> sizeof(str1) = 20, strlen(str1) = 4, str1 = 0100
Copy only 3 Bytes -> sizeof(str2) = 20, strlen(str2) = 3, str2 = 010

It seems like strncpy is first copying everything to dest and then cutting away the rest after it. But is that the way how strncpy works? I assumed it is only copying what is need, the 4 bytes.

CodePudding user response:

from man page https://linux.die.net/man/3/strncpy

The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.

ie in your case not null is placed in dest

CodePudding user response:

From the GLIBC manual page for strncpy():

Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.

You are observing the effect.

  • Related