mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 04:10:18 +02:00
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.
This commit is contained in:
parent
275c96dd1f
commit
6b1de860ab
4 changed files with 24 additions and 7 deletions
|
@ -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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
@ -662,6 +662,10 @@ 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);
|
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);
|
ret = make_bytevector (byte_len, SCM_ARRAY_ELEMENT_TYPE_VU8);
|
||||||
|
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);
|
memcpy (SCM_BYTEVECTOR_CONTENTS (ret), elts, byte_len);
|
||||||
|
|
||||||
scm_array_handle_release (&h);
|
scm_array_handle_release (&h);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* srfi-14.c --- SRFI-14 procedures for Guile
|
/* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* 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)
|
if (a->len != b->len)
|
||||||
return 0;
|
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)
|
if (memcmp (a->ranges, b->ranges, sizeof (scm_t_char_range) * a->len) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -340,10 +340,11 @@ setzone (SCM zone, int pos, const char *subr)
|
||||||
if (!SCM_UNBNDP (zone))
|
if (!SCM_UNBNDP (zone))
|
||||||
{
|
{
|
||||||
static char *tmpenv[2];
|
static char *tmpenv[2];
|
||||||
|
char dummy_buf[1];
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t zone_len;
|
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);
|
buf = scm_malloc (zone_len + sizeof (tzvar) + 1);
|
||||||
strcpy (buf, tzvar);
|
strcpy (buf, tzvar);
|
||||||
buf[sizeof(tzvar)-1] = '=';
|
buf[sizeof(tzvar)-1] = '=';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Copyright (C) 1995, 1996, 1998, 2000, 2001, 2004, 2006,
|
/* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* 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
|
size_t
|
||||||
scm_to_locale_stringbuf (SCM str, char *buf, size_t max_len)
|
scm_to_locale_stringbuf (SCM str, char *buf, size_t max_len)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len, copy_len;
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
if (!scm_is_string (str))
|
if (!scm_is_string (str))
|
||||||
scm_wrong_type_arg_msg (NULL, 0, str, "string");
|
scm_wrong_type_arg_msg (NULL, 0, str, "string");
|
||||||
result = scm_to_locale_stringn (str, &len);
|
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);
|
free (result);
|
||||||
|
|
||||||
scm_remember_upto_here_1 (str);
|
scm_remember_upto_here_1 (str);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue