mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
util: Improve virStrncpy() implementation
We finally get rid of the strncpy()-like semantics and implement our own, more sensible ones instead. As a bonus, this also fixes compilation on MinGW. Signed-off-by: Andrea Bolognani <abologna@redhat.com>
This commit is contained in:
parent
19136bbf10
commit
7d70a63b94
@ -1121,22 +1121,22 @@
|
|||||||
<p>
|
<p>
|
||||||
Do not use the strncpy function. According to the man page, it
|
Do not use the strncpy function. According to the man page, it
|
||||||
does <b>not</b> guarantee a NULL-terminated buffer, which makes
|
does <b>not</b> guarantee a NULL-terminated buffer, which makes
|
||||||
it extremely dangerous to use. Instead, use one of the
|
it extremely dangerous to use. Instead, use one of the replacement
|
||||||
functionally equivalent functions:
|
functions provided by libvirt:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
virStrncpy(char *dest, const char *src, size_t n, size_t destbytes)
|
virStrncpy(char *dest, const char *src, size_t n, size_t destbytes)
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
The first three arguments have the same meaning as for strncpy;
|
The first two arguments have the same meaning as for strncpy,
|
||||||
namely the destination, source, and number of bytes to copy,
|
namely the destination and source of the copy operation. Unlike
|
||||||
respectively. The last argument is the number of bytes
|
strncpy, the function will always copy exactly the number of bytes
|
||||||
available in the destination string; if a copy of the source
|
requested and make sure the destination is NULL-terminated, as the
|
||||||
string (including a \0) will not fit into the destination, no
|
source is required to be; sanity checks are performed to ensure the
|
||||||
bytes are copied and the routine returns <0. Otherwise, n
|
size of the destination, as specified by the last argument, is
|
||||||
bytes from the source are copied into the destination and a
|
sufficient for the operation to succeed. On success, 0 is returned;
|
||||||
trailing \0 is appended.
|
on failure, a value <0 is returned instead.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
@ -1144,10 +1144,8 @@
|
|||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
Use this variant if you know you want to copy the entire src
|
Use this variant if you know you want to copy the entire src
|
||||||
string into dest. Note that this is a macro, so arguments could
|
string into dest.
|
||||||
be evaluated more than once. This is equivalent to
|
</p>
|
||||||
virStrncpy(dest, src, strlen(src), destbytes)
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
virStrcpyStatic(char *dest, const char *src)
|
virStrcpyStatic(char *dest, const char *src)
|
||||||
@ -1157,8 +1155,7 @@
|
|||||||
string into dest <b>and</b> you know that your destination string is
|
string into dest <b>and</b> you know that your destination string is
|
||||||
a static string (i.e. that sizeof(dest) returns something
|
a static string (i.e. that sizeof(dest) returns something
|
||||||
meaningful). Note that this is a macro, so arguments could be
|
meaningful). Note that this is a macro, so arguments could be
|
||||||
evaluated more than once. This is equivalent to
|
evaluated more than once.
|
||||||
virStrncpy(dest, src, strlen(src), sizeof(dest)).
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
@ -769,44 +769,66 @@ virAsprintfInternal(bool report,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virStrncpy
|
* virStrncpy:
|
||||||
*
|
*
|
||||||
* A safe version of strncpy. The last parameter is the number of bytes
|
* @dest: destination buffer
|
||||||
* available in the destination string, *not* the number of bytes you want
|
* @src: source buffer
|
||||||
* to copy. If the destination is not large enough to hold all n of the
|
* @n: number of bytes to copy
|
||||||
* src string bytes plus a \0, <0 is returned and no data is copied.
|
* @destbytes: number of bytes the destination can accomodate
|
||||||
* If the destination is large enough to hold the n bytes plus \0, then the
|
*
|
||||||
* string is copied and 0 is returned.
|
* Copies the first @n bytes of @src to @dest.
|
||||||
|
*
|
||||||
|
* @src must be NULL-terminated; if successful, @dest is guaranteed to
|
||||||
|
* be NULL-terminated as well.
|
||||||
|
*
|
||||||
|
* @n must be a reasonable value, that is, it must not exceed either
|
||||||
|
* the length of @src or the size of @dest. For the latter constraint,
|
||||||
|
* the fact that @dest needs to accomodate a NULL byte in addition to
|
||||||
|
* the bytes copied from @src must be taken into account.
|
||||||
|
*
|
||||||
|
* If you want to copy *all* of @src to @dest, use virStrcpy() or
|
||||||
|
* virStrcpyStatic() instead.
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, <0 on failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virStrncpy(char *dest, const char *src, size_t n, size_t destbytes)
|
virStrncpy(char *dest, const char *src, size_t n, size_t destbytes)
|
||||||
{
|
{
|
||||||
if (n > (destbytes - 1))
|
size_t src_len = strlen(src);
|
||||||
|
|
||||||
|
/* As a special case, -1 means "copy the entire string".
|
||||||
|
*
|
||||||
|
* This is to avoid calling strlen() twice, once in the virStrcpy()
|
||||||
|
* wrapper and once here for bound checking purposes. */
|
||||||
|
if (n == -1)
|
||||||
|
n = src_len;
|
||||||
|
|
||||||
|
if (n <= 0 || n > src_len || n > (destbytes - 1))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
strncpy(dest, src, n);
|
memcpy(dest, src, n);
|
||||||
/* strncpy NULL terminates iff the last character is \0. Therefore
|
|
||||||
* force the last byte to be \0
|
|
||||||
*/
|
|
||||||
dest[n] = '\0';
|
dest[n] = '\0';
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virStrcpy
|
* virStrcpy:
|
||||||
*
|
*
|
||||||
* A safe version of strcpy. The last parameter is the number of bytes
|
* @dest: destination buffer
|
||||||
* available in the destination string, *not* the number of bytes you want
|
* @src: source buffer
|
||||||
* to copy. If the destination is not large enough to hold all n of the
|
* @destbytes: number of bytes the destination can accomodate
|
||||||
* src string bytes plus a \0, <0 is returned and no data is copied.
|
*
|
||||||
* If the destination is large enough to hold the source plus \0, then the
|
* Copies @src to @dest.
|
||||||
* string is copied and 0 is returned.
|
*
|
||||||
|
* See virStrncpy() for more information.
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, <0 on failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virStrcpy(char *dest, const char *src, size_t destbytes)
|
virStrcpy(char *dest, const char *src, size_t destbytes)
|
||||||
{
|
{
|
||||||
return virStrncpy(dest, src, strlen(src), destbytes);
|
return virStrncpy(dest, src, -1, destbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user