diff options
author | Mark H Weaver <mhw@netris.org> | 2019-04-01 22:11:35 -0400 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2019-05-23 17:40:08 +0200 |
commit | 980d8265c2dc35d6e02e540c9041cbf0975dfede (patch) | |
tree | 067f18effb6989e30fa872310ff3bddd920a8ac8 /libguile/strings.c | |
parent | b38d9a1527a9d796034bf721c9a266d261db5ad0 (diff) | |
download | guile-980d8265c2dc35d6e02e540c9041cbf0975dfede.tar.gz |
Avoid passing NULL to 'memcpy' and 'memcmp'.
Reported by Jeffrey Walton <noloader@gmail.com> in
<https://lists.gnu.org/archive/html/guile-devel/2019-03/msg00001.html>.
Note that C11 section 7.1.4 (Use of library functions) states that:
"unless explicitly stated otherwise in the detailed descriptions [of
library functions] that follow: If an argument to a function has an
invalid value (such as ... a null pointer ...) ..., the behavior is
undefined." Note that 'strxfrm' is an example of a standard C function
that explicitly states otherwise, allowing NULL to be passed in the
first argument if the size argument is zero, but no similar allowance is
specified for 'memcpy' or 'memcmp'.
* libguile/bytevectors.c (scm_uniform_array_to_bytevector): Call memcpy
only if 'byte_len' is non-zero.
* libguile/srfi-14.c (charsets_equal): Call memcmp only if the number of
ranges is non-zero.
* libguile/stime.c (setzone): Pass 1-character buffer to
'scm_to_locale_stringbuf', instead of NULL.
* libguile/strings.c (scm_to_locale_stringbuf): Call memcpy only if the
number of bytes to copy is non-zero.
Diffstat (limited to 'libguile/strings.c')
-rw-r--r-- | libguile/strings.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/libguile/strings.c b/libguile/strings.c index a0a1555f5..b366f5b37 100644 --- a/libguile/strings.c +++ b/libguile/strings.c @@ -1,4 +1,4 @@ -/* Copyright 1995-1996,1998,2000-2001,2004,2006,2008-2016,2018 +/* Copyright 1995-1996,1998,2000-2001,2004,2006,2008-2016,2018-2019 Free Software Foundation, Inc. This file is part of Guile. @@ -2288,13 +2288,18 @@ scm_to_stringn (SCM str, size_t *lenp, const char *encoding, size_t scm_to_locale_stringbuf (SCM str, char *buf, size_t max_len) { - size_t len; + size_t len, copy_len; char *result = NULL; if (!scm_is_string (str)) scm_wrong_type_arg_msg (NULL, 0, str, "string"); result = scm_to_locale_stringn (str, &len); - memcpy (buf, result, (len > max_len) ? max_len : len); + copy_len = (len > max_len) ? max_len : len; + if (copy_len != 0) + /* Some users of 'scm_to_locale_stringbuf' may pass NULL for buf + when max_len is zero, and yet we must avoid passing NULL to + memcpy to avoid undefined behavior. */ + memcpy (buf, result, copy_len); free (result); scm_remember_upto_here_1 (str); |