summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libguile/bytevectors.c8
-rw-r--r--libguile/srfi-14.c10
-rw-r--r--libguile/stime.c3
-rw-r--r--libguile/strings.c11
4 files changed, 23 insertions, 9 deletions
diff --git a/libguile/bytevectors.c b/libguile/bytevectors.c
index 6e3c9503d..b4dc2ea04 100644
--- a/libguile/bytevectors.c
+++ b/libguile/bytevectors.c
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015,2018
+/* Copyright 2009-2015,2018-2019
Free Software Foundation, Inc.
This file is part of Guile.
@@ -671,7 +671,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 42ee85d57..bbddb0598 100644
--- a/libguile/srfi-14.c
+++ b/libguile/srfi-14.c
@@ -1,6 +1,4 @@
-/* srfi-14.c --- SRFI-14 procedures for Guile
-
- Copyright 2001,2004,2006-2007,2009,2011,2018
+/* Copyright 2001,2004,2006-2007,2009,2011,2018-2019
Free Software Foundation, Inc.
This file is part of Guile.
@@ -377,6 +375,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 2b9651c2e..6c17eb931 100644
--- a/libguile/stime.c
+++ b/libguile/stime.c
@@ -342,10 +342,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 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);