diff options
-rw-r--r-- | libguile/bytevectors.c | 8 | ||||
-rw-r--r-- | libguile/srfi-14.c | 9 | ||||
-rw-r--r-- | libguile/stime.c | 3 | ||||
-rw-r--r-- | libguile/strings.c | 11 |
4 files changed, 24 insertions, 7 deletions
diff --git a/libguile/bytevectors.c b/libguile/bytevectors.c index 1d4129705..e42a48c4e 100644 --- a/libguile/bytevectors.c +++ b/libguile/bytevectors.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2009-2015 Free Software Foundation, Inc. +/* Copyright (C) 2009-2015, 2019 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -662,7 +662,11 @@ SCM_DEFINE (scm_uniform_array_to_bytevector, "uniform-array->bytevector", SCM_MISC_ERROR ("uniform elements larger than 8 bits must fill whole bytes", SCM_EOL); ret = make_bytevector (byte_len, SCM_ARRAY_ELEMENT_TYPE_VU8); - memcpy (SCM_BYTEVECTOR_CONTENTS (ret), elts, byte_len); + if (byte_len != 0) + /* Empty arrays may have elements == NULL. We must avoid passing + NULL to memcpy, even if the length is zero, to avoid undefined + behavior. */ + memcpy (SCM_BYTEVECTOR_CONTENTS (ret), elts, byte_len); scm_array_handle_release (&h); diff --git a/libguile/srfi-14.c b/libguile/srfi-14.c index af7c1d95b..a4d71e8eb 100644 --- a/libguile/srfi-14.c +++ b/libguile/srfi-14.c @@ -1,6 +1,7 @@ /* srfi-14.c --- SRFI-14 procedures for Guile * - * Copyright (C) 2001, 2004, 2006, 2007, 2009, 2011 Free Software Foundation, Inc. + * Copyright (C) 2001, 2004, 2006, 2007, 2009, 2011, + * 2019 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -363,6 +364,12 @@ charsets_equal (scm_t_char_set *a, scm_t_char_set *b) if (a->len != b->len) return 0; + /* Empty charsets may have ranges == NULL. We must avoid passing + NULL to memcmp, even if the length is zero, to avoid undefined + behavior. */ + if (a->len == 0) + return 1; + if (memcmp (a->ranges, b->ranges, sizeof (scm_t_char_range) * a->len) != 0) return 0; diff --git a/libguile/stime.c b/libguile/stime.c index 060a49642..b681d7ee3 100644 --- a/libguile/stime.c +++ b/libguile/stime.c @@ -340,10 +340,11 @@ setzone (SCM zone, int pos, const char *subr) if (!SCM_UNBNDP (zone)) { static char *tmpenv[2]; + char dummy_buf[1]; char *buf; size_t zone_len; - zone_len = scm_to_locale_stringbuf (zone, NULL, 0); + zone_len = scm_to_locale_stringbuf (zone, dummy_buf, 0); buf = scm_malloc (zone_len + sizeof (tzvar) + 1); strcpy (buf, tzvar); buf[sizeof(tzvar)-1] = '='; diff --git a/libguile/strings.c b/libguile/strings.c index 5f35617a2..62ff2e303 100644 --- a/libguile/strings.c +++ b/libguile/strings.c @@ -1,5 +1,5 @@ /* Copyright (C) 1995, 1996, 1998, 2000, 2001, 2004, 2006, - * 2008-2016, 2018 Free Software Foundation, Inc. + * 2008-2016, 2018, 2019 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -2283,13 +2283,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); |