gets() - fgets() & strcpy() - strncpy()

2016-12-02 12:52:08来源:网络收集作者:IT狂人人点击

第七城市


Neverusegets.
It offers no protections against a buffer overflow vulnerability (that is, you cannot tell it how big the buffer you pass to it is, so it cannot prevent a user from entering a line larger than the buffer and clobbering memory).



Avoid usingscanf.
If not used carefully, it can have the same buffer overflow problems asgets.
Even ignoring that,it has other problems that make it hard to use correctly.



Generally you should usefgetsinstead,
although it's sometimes inconvenient (you have to strip the newline, you must determine a buffer size ahead of time, and then you must figure out what to do with lines that are too long–do you keep the part you read anddiscard
the excess, discard the whole thing, dynamically grow the buffer and try again, etc.). There are some non-standard functions available that do this dynamic allocation for you (e.g.getlineon
POSIX systems,Chuck Falconer's public domainggetsfunction).
Note thatggetshasgets-like
semantics in that it strips a trailing newline for you.


Like:
char *result = fgets(str, sizeof(str), stdin);
char len = strlen(str);
if(result != NULL && str[len - 1] == '/n')
{
str[len - 1] = '/0';
}
else
{
// handle error
}
or
char *line = NULL;
size_t len = 0;
ssize_t count = getline(&line, &len, stdin);
if(count >= 1 && line[count - 1] == '/n')
{
line[count - 1] = '/0';
}
else
{
// Handle error
}
The advantage togetlineis
it does allocation and reallocation for you, it handles possible embedded NULLs, and it returns the count so you don't have to waste time withstrlen.
Note that you can't use an array withgetline.
The pointer must beNULLor
free-able.


Thestrncpy()function
was designed with a very particular problem in mind: manipulating strings stored in the manner of original UNIX directory entries. These used a fixed sized array, and a nul-terminator was only used if the filename was shorter than the array.



That's what's behind the two oddities ofstrncpy():


It doesn't put a nul-terminator on the destination if it is completely filled; andIt always completely fills the destination, with nuls if necessary.


For a "saferstrcpy()",
you are better off usingstrncat()like
so:


if (dest_size > 0)
{
dest[0] = '/0';
strncat(dest, source, dest_size - 1);
}


That will always nul-terminate the result, and won't copy more than necessary.



Thestrncpy()function
was designed with a very particular problem in mind: manipulating strings stored in the manner of original UNIX directory entries. These used a fixed sized array, and a nul-terminator was only used if the filename was shorter than the array.



That's what's behind the two oddities ofstrncpy():


It doesn't put a nul-terminator on the destination if it is completely filled; andIt always completely fills the destination, with nuls if necessary.


For a "saferstrcpy()",
you are better off usingstrncat()like
so:


if (dest_size > 0)
{
dest[0] = '/0';
strncat(dest, source, dest_size - 1);
}


That will always nul-terminate the result, and won't copy more than necessary.

第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台