1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-30 06:50:31 +02:00

fix write beyond array end in arrays.c

* libguile/arrays.c (scm_i_read_array): Fix write past end of array
  while reading array type tag.  Fix non-ascii type tag elements.
  Thanks to http://article.gmane.org/gmane.lisp.guile.devel/12685.
This commit is contained in:
Andy Wingo 2011-07-28 19:04:38 +02:00
parent 2b14df4bc7
commit eff3dd99f7

View file

@ -822,15 +822,6 @@ scm_i_print_array (SCM array, SCM port, scm_print_state *pstate)
C is the first character read after the '#'. C is the first character read after the '#'.
*/ */
static SCM
tag_to_type (const char *tag, SCM port)
{
if (*tag == '\0')
return SCM_BOOL_T;
else
return scm_from_locale_symbol (tag);
}
static int static int
read_decimal_integer (SCM port, int c, ssize_t *resp) read_decimal_integer (SCM port, int c, ssize_t *resp)
{ {
@ -860,10 +851,10 @@ SCM
scm_i_read_array (SCM port, int c) scm_i_read_array (SCM port, int c)
{ {
ssize_t rank; ssize_t rank;
char tag[80]; scm_t_wchar tag_buf[8];
int tag_len; int tag_len;
SCM shape = SCM_BOOL_F, elements; SCM tag, shape = SCM_BOOL_F, elements;
/* XXX - shortcut for ordinary vectors. Shouldn't be necessary but /* XXX - shortcut for ordinary vectors. Shouldn't be necessary but
the array code can not deal with zero-length dimensions yet, and the array code can not deal with zero-length dimensions yet, and
@ -887,7 +878,7 @@ scm_i_read_array (SCM port, int c)
return SCM_BOOL_F; return SCM_BOOL_F;
} }
rank = 1; rank = 1;
tag[0] = 'f'; tag_buf[0] = 'f';
tag_len = 1; tag_len = 1;
goto continue_reading_tag; goto continue_reading_tag;
} }
@ -904,12 +895,21 @@ scm_i_read_array (SCM port, int c)
*/ */
tag_len = 0; tag_len = 0;
continue_reading_tag: continue_reading_tag:
while (c != EOF && c != '(' && c != '@' && c != ':' && tag_len < 80) while (c != EOF && c != '(' && c != '@' && c != ':'
&& tag_len < sizeof tag_buf / sizeof tag_buf[0])
{ {
tag[tag_len++] = c; tag_buf[tag_len++] = c;
c = scm_getc (port); c = scm_getc (port);
} }
tag[tag_len] = '\0'; if (tag_len == 0)
tag = SCM_BOOL_T;
else
{
tag = scm_string_to_symbol (scm_from_utf32_stringn (tag_buf, tag_len));
if (tag_len == sizeof tag_buf / sizeof tag_buf[0])
scm_i_input_error (NULL, port, "invalid array tag, starting with: ~a",
scm_list_1 (tag));
}
/* Read shape. /* Read shape.
*/ */
@ -983,7 +983,7 @@ scm_i_read_array (SCM port, int c)
/* Construct array. /* Construct array.
*/ */
return scm_list_to_typed_array (tag_to_type (tag, port), shape, elements); return scm_list_to_typed_array (tag, shape, elements);
} }