diff options
author | Tim Janik <timj@gtk.org> | 2000-07-26 03:51:07 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 2000-07-26 03:51:07 +0000 |
commit | 83e49bd036d362eb626afa0aef347c08df3b72be (patch) | |
tree | 087b268e5379a09486e1f98f73850264fed8cf8a /glib | |
parent | cb2f0780515a11bd5ed8138cbf53428bb3c6d2ed (diff) | |
download | glib-83e49bd036d362eb626afa0aef347c08df3b72be.tar.gz |
added g_strlcat() and g_strlcpy() wrappers, supplied by David Wheeler
Wed Jul 26 05:47:48 2000 Tim Janik <timj@gtk.org>
* configure.in:
* testglib.c:
* gstrfuncs.c:
* glib.h: added g_strlcat() and g_strlcpy() wrappers, supplied by
David Wheeler <dwheeler@ida.org>:
* glib.h, gstrfuncs.c: added g_strlcpy and g_strlcat to support
safe manipulation of fixed-length string buffers.
These functions were originally developed by Todd Miller to simplify
development of security-related programs, and
are available on many (but not all) Unix-like systems,
including OpenBSD, FreeBSD, and Solaris. See
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
and http://www.openbsd.org/security.html.
If there's a strlcpy/strlcat on the system, it's called, otherwise
an implementation is provided.
* testglib.c: Added tests for g_strlcpy, g_strlcat.
Diffstat (limited to 'glib')
-rw-r--r-- | glib/glib.h | 6 | ||||
-rw-r--r-- | glib/gstrfuncs.c | 135 |
2 files changed, 136 insertions, 5 deletions
diff --git a/glib/glib.h b/glib/glib.h index 7f31ba9e0..bbc23dc25 100644 --- a/glib/glib.h +++ b/glib/glib.h @@ -1654,6 +1654,12 @@ gint g_strncasecmp (const gchar *s1, gchar* g_strdown (gchar *string); gchar* g_strup (gchar *string); gchar* g_strreverse (gchar *string); +gsize g_strlcpy (gchar *dest, + const gchar *src, + gsize dest_size); +gsize g_strlcat (gchar *dest, + const gchar *src, + gsize dest_size); /* removes leading spaces */ gchar* g_strchug (gchar *string); /* removes trailing spaces */ diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c index 0bec54367..b14f7ee54 100644 --- a/glib/gstrfuncs.c +++ b/glib/gstrfuncs.c @@ -797,25 +797,150 @@ extern const char * strsignal(int); } sprintf (msg, "unknown signal (%d)", signum); - + return msg; } +/* Functions g_strlcpy and g_strlcat were originally developed by + * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code. + * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3 + * for more information. + */ + +#ifdef HAVE_STRLCPY +/* Use the native ones, if available; they might be implemented in assembly */ +gsize +g_strlcpy (gchar *dest, + const gchar *src, + gsize dest_size) +{ + g_return_val_if_fail (dest != NULL, NULL); + g_return_val_if_fail (src != NULL, NULL); + + return strlcpy (dest, src, dest_size); +} + +gsize +g_strlcat (gchar *dest, + const gchar *src, + gsize dest_size) +{ + g_return_val_if_fail (dest != NULL, NULL); + g_return_val_if_fail (src != NULL, NULL); + + return strlcat (dest, src, dest_size); +} + +#else /* ! HAVE_STRLCPY */ +/* g_strlcpy + * + * Copy string src to buffer dest (of buffer size dest_size). At most + * dest_size-1 characters will be copied. Always NUL terminates + * (unless dest_size == 0). This function does NOT allocate memory. + * Unlike strncpy, this function doesn't pad dest (so it's often faster). + * Returns size of attempted result, strlen(src), + * so if retval >= dest_size, truncation occurred. + */ +gsize +g_strlcpy (gchar *dest, + const gchar *src, + gsize dest_size) +{ + register gchar *d = dest; + register const gchar *s = src; + register gsize n = dest_size; + + g_return_val_if_fail (dest != NULL, NULL); + g_return_val_if_fail (src != NULL, NULL); + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) + do + { + register gchar c = *s++; + + *d++ = c; + if (c == 0) + break; + } + while (--n != 0); + + /* If not enough room in dest, add NUL and traverse rest of src */ + if (n == 0) + { + if (dest_size != 0) + *d = 0; + while (*s++) + ; + } + + return s - src - 1; /* count does not include NUL */ +} + +/* g_strlcat + * + * Appends string src to buffer dest (of buffer size dest_size). + * At most dest_size-1 characters will be copied. + * Unlike strncat, dest_size is the full size of dest, not the space left over. + * This function does NOT allocate memory. + * This always NUL terminates (unless siz == 0 or there were no NUL characters + * in the dest_size characters of dest to start with). + * Returns size of attempted result, which is + * MIN (dest_size, strlen (original dest)) + strlen (src), + * so if retval >= dest_size, truncation occurred. + */ +gsize +g_strlcat (gchar *dest, + const gchar *src, + gsize dest_size) +{ + register gchar *d = dest; + register const gchar *s = src; + register gsize bytes_left = dest_size; + gsize dlength; /* Logically, MIN (strlen (d), dest_size) */ + + g_return_val_if_fail (dest != NULL, NULL); + g_return_val_if_fail (src != NULL, NULL); + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (*d != 0 && bytes_left-- != 0) + d++; + dlength = d - dest; + bytes_left = dest_size - dlength; + + if (bytes_left == 0) + return dlength + strlen (s); + + while (*s != 0) + { + if (bytes_left != 1) + { + *d++ = *s; + bytes_left--; + } + s++; + } + *d = 0; + + return dlength + (s - src); /* count does not include NUL */ +} +#endif /* ! HAVE_STRLCPY */ + gchar* g_strdown (gchar *string) { register guchar *s; - + g_return_val_if_fail (string != NULL, NULL); - + s = string; - + while (*s) { *s = tolower (*s); s++; } - + return string; } |