mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-17 01:00:20 +02:00
Improve overflow checks in bytevector, string, and I/O operations.
* libguile/bytevectors.c (INTEGER_ACCESSOR_PROLOGUE) (scm_bytevector_copy_x, bytevector_large_set): Rewrite checks to reliably detect overflows. (make_bytevector): Constrain the bytevector length to avoid later overflows during allocation. (make_bytevector_from_buffer): Fix indentation. (scm_bytevector_length): Use 'scm_from_size_t' to convert a 'size_t', not 'scm_from_uint'. * libguile/fports.c (fport_seek): Check for overflow before the implicit conversion of the return value. * libguile/guardians.c (guardian_print): Use 'scm_from_ulong' to convert an 'unsigned long', not 'scm_from_uint'. * libguile/ports.c (scm_unread_string): Change a variable to type 'size_t'. (scm_seek, scm_truncate_file): Use 'scm_t_off' instead of 'off_t_or_off64_t' to avoid implicit type conversions that could overflow, because 'ptob->seek' and 'ptob->truncate' use 'scm_t_off'. * libguile/r6rs-ports.c (bytevector_input_port_seek) (custom_binary_port_seek, bytevector_output_port_seek): Rewrite offset calculations to reliably detect overflows. Use 'scm_from_off_t' to convert a 'scm_t_off', not 'scm_from_long' nor 'scm_from_int'. (scm_get_bytevector_n_x, scm_get_bytevector_all, scm_unget_bytevector) (bytevector_output_port_write): Rewrite checks to reliably detect overflows. Use 'size_t' where appropriate. (bytevector_output_port_buffer_grow): Rewrite size calculations to reliably detect overflows. Minor change in the calculation of the new size: now it is max(min_size, 2*current_size), whereas previously it would multiply current_size by the smallest power of 2 needed to surpass min_size. * libguile/strings.c (make_stringbuf): Constrain the stringbuf length to avoid later overflows during allocation. (scm_string_append): Change overflow check to use INT_ADD_OVERFLOW. * libguile/strports.c (string_port_write): Rewrite size calculations to reliably detect overflows. (string_port_seek): Rewrite offset calculations to reliably detect overflows. Use 'scm_from_off_t' to convert a 'scm_t_off', not 'scm_from_long'. (string_port_truncate): Use 'scm_from_off_t' to convert a 'scm_t_off', not 'scm_from_off_t_or_off64_t'. * libguile/vectors.c (scm_c_make_vector): Change a variable to type 'size_t'.
This commit is contained in:
parent
420c2632bb
commit
91ba73b397
8 changed files with 142 additions and 76 deletions
|
@ -31,6 +31,7 @@
|
|||
#include <unistr.h>
|
||||
#include <uniconv.h>
|
||||
#include <c-strcase.h>
|
||||
#include <intprops.h>
|
||||
|
||||
#include "striconveh.h"
|
||||
|
||||
|
@ -124,6 +125,12 @@ make_stringbuf (size_t len)
|
|||
lenhist[1000]++;
|
||||
#endif
|
||||
|
||||
/* Make sure that the total allocation size will not overflow size_t,
|
||||
with ~30 extra bytes to spare to avoid an overflow within the
|
||||
allocator. */
|
||||
if (INT_ADD_OVERFLOW (len, STRINGBUF_HEADER_BYTES + 32))
|
||||
scm_num_overflow ("make_stringbuf");
|
||||
|
||||
buf = SCM_PACK_POINTER (scm_gc_malloc_pointerless (STRINGBUF_HEADER_BYTES + len + 1,
|
||||
"string"));
|
||||
|
||||
|
@ -150,9 +157,16 @@ make_wide_stringbuf (size_t len)
|
|||
lenhist[1000]++;
|
||||
#endif
|
||||
|
||||
/* Make sure that the total allocation size will not overflow size_t,
|
||||
with ~30 extra bytes to spare to avoid an overflow within the
|
||||
allocator. */
|
||||
if (len > (((size_t) -(STRINGBUF_HEADER_BYTES + 32 + sizeof (scm_t_wchar)))
|
||||
/ sizeof (scm_t_wchar)))
|
||||
scm_num_overflow ("make_wide_stringbuf");
|
||||
|
||||
raw_len = (len + 1) * sizeof (scm_t_wchar);
|
||||
buf = SCM_PACK_POINTER (scm_gc_malloc_pointerless (STRINGBUF_HEADER_BYTES + raw_len,
|
||||
"string"));
|
||||
"string"));
|
||||
|
||||
SCM_SET_CELL_TYPE (buf, STRINGBUF_TAG | STRINGBUF_F_WIDE);
|
||||
SCM_SET_CELL_WORD_1 (buf, (scm_t_bits) len);
|
||||
|
@ -1388,8 +1402,8 @@ SCM_DEFINE (scm_string_append, "string-append", 0, 0, 1,
|
|||
s = SCM_CAR (l);
|
||||
SCM_VALIDATE_STRING (SCM_ARGn, s);
|
||||
len = scm_i_string_length (s);
|
||||
if (((size_t) -1) - total < len)
|
||||
scm_num_overflow (s_scm_string_append);
|
||||
if (INT_ADD_OVERFLOW (total, len))
|
||||
scm_num_overflow (FUNC_NAME);
|
||||
total += len;
|
||||
if (!scm_i_is_narrow_string (s))
|
||||
wide = 1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue