diff --git a/src/reader.c b/src/reader.c index 86254ff8..3dfd3b04 100644 --- a/src/reader.c +++ b/src/reader.c @@ -69,7 +69,6 @@ reader_end_of_word_p (int c) SCM reader_read_identifier_or_number (int c) { - char buf[MAX_STRING]; int i = 0; long n = 0; int negative_p = 0; @@ -82,7 +81,7 @@ reader_read_identifier_or_number (int c) } while (isdigit (c)) { - buf[i++] = c; + g_buf[i++] = c; n *= 10; n += c - '0'; c = readchar (); @@ -97,12 +96,12 @@ reader_read_identifier_or_number (int c) /* Fallthrough: Note that `4a', `+1b' are identifiers */ while (!reader_end_of_word_p (c)) { - buf[i++] = c; + g_buf[i++] = c; c = readchar (); } unreadchar (c); - buf[i] = 0; - return cstring_to_symbol (buf); + g_buf[i] = 0; + return cstring_to_symbol (g_buf); } SCM @@ -433,12 +432,12 @@ reader_read_hex () SCM reader_read_string () { - char buf[MAX_STRING]; size_t i = 0; int c; do { - assert (i < MAX_STRING); + if (i > MAX_STRING) + assert_max_string (i, "reader_read_string", g_buf); c = readchar (); if (c == '"') break; @@ -472,11 +471,11 @@ reader_read_string () else if (c == 'x') c = VALUE (reader_read_hex ()); } - buf[i++] = c; + g_buf[i++] = c; } while (1); - buf[i] = 0; - return make_string (buf, i); + g_buf[i] = 0; + return make_string (g_buf, i); } int g_tiny = 0; diff --git a/src/strings.c b/src/strings.c index 86828461..4aa80f52 100644 --- a/src/strings.c +++ b/src/strings.c @@ -18,25 +18,39 @@ * along with GNU Mes. If not, see . */ -#include +#define MAX_STRING 524288 +char g_buf[MAX_STRING]; -#define MAX_STRING 4096 +void +assert_max_string (size_t i, char const* msg, char* string) +{ + if (i > MAX_STRING) // Mes must be able to make g_buf + { + eputs (msg); + eputs (":string too long["); + eputs (itoa (i)); + eputs ("]:"); + string[MAX_STRING-1] = 0; + eputs (string); + error (cell_symbol_system_error, cell_f); + } +} char const* list_to_cstring (SCM list, size_t* size) { - static char buf[MAX_STRING]; size_t i = 0; - char *p = buf; + char *p = g_buf; while (list != cell_nil) { - assert (i < MAX_STRING); - buf[i++] = VALUE (car (list)); + if (i > MAX_STRING) + assert_max_string (i, "list_to_string", g_buf); + g_buf[i++] = VALUE (car (list)); list = cdr (list); } - buf[i] = 0; + g_buf[i] = 0; *size = i; - return buf; + return g_buf; } size_t @@ -71,7 +85,8 @@ make_bytes (char const* s, size_t length) SCM make_string (char const* s, size_t length) { - assert (length < HALFLONG_MAX); + if (length > MAX_STRING) + assert_max_string (length, "make_string", s); SCM x = make_cell__ (TSTRING, length, 0); SCM v = make_bytes (s, length); CDR (x) = v; @@ -230,25 +245,24 @@ read_string (SCM port) ///((arity . n)) if (TYPE (port) == TPAIR && TYPE (car (port)) == TNUMBER) g_stdin = VALUE (CAR (port)); int c = readchar (); - static char buf[MAX_STRING]; size_t i = 0; while (c != -1) { - assert (i < MAX_STRING); - buf[i++] = c; + if (i > MAX_STRING) + assert_max_string (i, "read_string", g_buf); + g_buf[i++] = c; c = readchar (); } - buf[i] = 0; + g_buf[i] = 0; g_stdin = fd; - return make_string (buf, i); + return make_string (g_buf, i); } SCM string_append (SCM x) ///((arity . n)) { - static char buf[MAX_STRING]; - char const *p = buf; - buf[0] = 0; + char const *p = g_buf; + g_buf[0] = 0; size_t size = 0; while (x != cell_nil) { @@ -257,10 +271,11 @@ string_append (SCM x) ///((arity . n)) memcpy (p, CSTRING (string), LENGTH (string) + 1); p += LENGTH (string); size += LENGTH (string); - assert (size < MAX_STRING); + if (size > MAX_STRING) + assert_max_string (size, "string_append", g_buf); x = CDR (x); } - return make_string (buf, size); + return make_string (g_buf, size); } SCM @@ -277,7 +292,7 @@ string_ref (SCM str, SCM k) assert (TYPE (k) == TNUMBER); size_t size = LENGTH (str); size_t i = VALUE (k); - if (i >= size) + if (i > size) error (cell_symbol_system_error, cons (MAKE_STRING0 ("value out of range"), k)); char const *p = CSTRING (str); return MAKE_CHAR (p[i]);