Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

problem with strncpy function

Status
Not open for further replies.

loraron

Programmer
Dec 19, 2007
1
0
0
US
I do strncpy from one buff to another. On some length of source buffer in the second buffer appears additional characters at the end. Code is very simple and clear:
len=strlen(argv[2]);
param=(char*)malloc(sizeof(char*)*(len+1));
strcpy(param,argv[2]);
confname=strrchr(param,'/')+1;
len1=strlen(confname);
printf("Argument - %s\n",param);
strncpy(confpath,param,(len-len1));
printf("confpath %s\n",confpath);
______________________________________________
Result:
Argument - /home/vsergeev/usr/local/conf1/sazc.conf
confpath /home/vsergeev/usr/local/conf1PC
Argument - /home/vsergeev/usr/local/conf12/sazc.conf
confpath /home/vsergeev/usr/local/conf12/\PC
Argument - /home/vsergeev/usr/local/conf1234567890/sazc.conf
confpath /home/vsergeev/usr/local/conf1234567890/C
Argument -/home/vsergeev/usr/local/conf12345678901/sazc.conf
confpath /home/vsergeev/usr/local/conf12345678901/
 
Hi,

This is a common problem with using uninitialized (zeroed memory) for string storage. An example.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSZ 200


int main(int argc, char **argv) {
int len_1,len_2;
char *r_buff = NULL, *a_buff;
char stack_store[MAXSZ];

                     if (argc != 2){printf("Please provide an argument for string operations with the / character included.\n"); return 1;}
                     printf("Before modification pointer buffers at: %p,%p and = %s,%s\n",r_buff,a_buff,r_buff,a_buff);
                     len_1 = strlen(argv[1]);
                     r_buff = malloc((len_1 + 1) * sizeof(char));
                     if (r_buff == NULL) {printf("malloc failed\n"); return 1;}
                     strncpy(r_buff,argv[1],len_1);

                     if ( (a_buff = strrchr(r_buff,'/')) != NULL) {
                          a_buff += 1;
                          printf("a_buff %p = %s after strrchr.\n",a_buff,a_buff);
                          len_2 = strlen(a_buff) + 1;
                          bzero(stack_store,MAXSZ);
                          strncpy(stack_store,r_buff,(len_1 - len_2));
                          printf("Stack store %p = %s after strncpy.\n",stack_store,stack_store);
                          free(r_buff);
                    }
                    return 0;
}
Output:
Before modification pointer buffers at: (nil),0xb7f71ff4 and = (null),
a_buff 0x804b01b = examplecode after strrchr.
Stack store 0xbfb52038 = /home_nis/username after strncpy.

Now comment out the bzero..
Code:
/* bzero(stack_store,MAXSZ);*/
Before modification pointer buffers at: (nil),0xb7f7fff4 and = (null),
a_buff 0x804b01b = examplecode after strrchr.
Stack store 0xbfa45738 = /home_nis/username?N=?after strncpy.
 
strncpy() does not add terminating null, when length of source string is equal or bigger than count of bytes parameter. This parameter actually means "destination buffer size". So strncpy() should be followed by
Code:
confpath[len-len1] = 0;
 
If you use calloc instead of malloc the dynamic memory will be zero-filled initially.

Lee
 
Best practice? Zeroing array to allocated length or truncating array at 'length'? I'm more comfortable always zeroing, especially when using pointer arithmetic.

Pure curiosity,no criticism intended.
 
When we play this game with ASCIIZ strings, the only safe way is to terminate dynamically formed char sequence explicitly. For example, the original post describes a case where calloc does not help (it's lack of consideration for library function specification, see mingis's post;). As usually, calloc allocation brings illusory safety (and unnecessary overheads;).
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top