diff options
author | Ludovic Courtès <ludo@gnu.org> | 2008-12-02 19:42:39 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2008-12-02 19:52:13 +0100 |
commit | 3ae3166b2307ee8588aa9b422764b486ed02ad09 (patch) | |
tree | 70092c15a1ebe07932c7a41f2bee0ccfdf35a5be /libguile/strings.c | |
parent | 691343ead288625816175574d629f8b5c925fbab (diff) | |
download | guile-3ae3166b2307ee8588aa9b422764b486ed02ad09.tar.gz |
Fix sloppy bound checking in `string-{ref,set!}' with the empty string.
* libguile/strings.c (scm_string_ref): Add proper range checking for the
empty string.
(scm_string_set_x): Likewise.
Reported by Bill Schottstaedt <bil@ccrma.Stanford.EDU>.
* test-suite/tests/strings.test ("string-ref"): New test prefix.
("string-set!")["empty string", "empty string and non-zero index",
"out of range", "negative index", "regular string"]: New tests.
* NEWS: Update.
Diffstat (limited to 'libguile/strings.c')
-rw-r--r-- | libguile/strings.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/libguile/strings.c b/libguile/strings.c index 7399d8831..c13802664 100644 --- a/libguile/strings.c +++ b/libguile/strings.c @@ -670,10 +670,17 @@ SCM_DEFINE (scm_string_ref, "string-ref", 2, 0, 0, "indexing. @var{k} must be a valid index of @var{str}.") #define FUNC_NAME s_scm_string_ref { + size_t len; unsigned long idx; SCM_VALIDATE_STRING (1, str); - idx = scm_to_unsigned_integer (k, 0, scm_i_string_length (str)-1); + + len = scm_i_string_length (str); + if (SCM_LIKELY (len > 0)) + idx = scm_to_unsigned_integer (k, 0, len - 1); + else + scm_out_of_range (NULL, k); + return SCM_MAKE_CHAR (scm_i_string_chars (str)[idx]); } #undef FUNC_NAME @@ -693,10 +700,17 @@ SCM_DEFINE (scm_string_set_x, "string-set!", 3, 0, 0, "@var{str}.") #define FUNC_NAME s_scm_string_set_x { + size_t len; unsigned long idx; SCM_VALIDATE_STRING (1, str); - idx = scm_to_unsigned_integer (k, 0, scm_i_string_length(str)-1); + + len = scm_i_string_length (str); + if (SCM_LIKELY (len > 0)) + idx = scm_to_unsigned_integer (k, 0, len - 1); + else + scm_out_of_range (NULL, k); + SCM_VALIDATE_CHAR (3, chr); { char *dst = scm_i_string_writable_chars (str); |