diff options
author | Ludovic Courtès <ludo@gnu.org> | 2010-09-15 23:32:28 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2010-09-15 23:32:28 +0200 |
commit | f1ee6d54d219056c62d87a8e4a6b199162c946e8 (patch) | |
tree | 2ccec5ae9d5c772111d8b1b48569c8b751d5257a /libguile/print.c | |
parent | fd5eec2b6e113f6d13028215a738417607432a2d (diff) | |
download | guile-f1ee6d54d219056c62d87a8e4a6b199162c946e8.tar.gz |
Fix write-beyond-end-of-string error in the conversion to R6RS string escapes.
Reported by Mike Gran <spk121@yahoo.com>.
* libguile/strings.c (scm_i_unistring_escapes_to_guile_escapes,
scm_i_unistring_escapes_to_r6rs_escapes): Augment comments.
(scm_to_stringn): When `handler ==
SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE && SCM_R6RS_ESCAPES_P', realloc
BUF so that it's large enough for the worst case.
* libguile/print.c (display_character): When `result != NULL && strategy
== SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE && SCM_R6RS_ESCAPES_P', make
LOCALE_ENCODED large enough to hold an R6RS escape.
Diffstat (limited to 'libguile/print.c')
-rw-r--r-- | libguile/print.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/libguile/print.c b/libguile/print.c index 2ffe70ec0..bdc6c9f20 100644 --- a/libguile/print.c +++ b/libguile/print.c @@ -768,7 +768,7 @@ display_character (scm_t_wchar ch, SCM port, else { size_t len; - char locale_encoded[sizeof (ch)], *result; + char locale_encoded[8 * sizeof (ch)], *result; len = sizeof (locale_encoded); result = u32_conv_to_encoding (encoding, strategy, @@ -782,7 +782,16 @@ display_character (scm_t_wchar ch, SCM port, { /* Apply the same escaping syntax as in `write_character'. */ if (SCM_R6RS_ESCAPES_P) - scm_i_unistring_escapes_to_r6rs_escapes (result, &len); + { + /* LOCALE_ENCODED is large enough to store an R6RS + `\xNNNN;' escape sequence. However, libunistring + up to 0.9.3 (included) always returns a + heap-allocated RESULT. */ + if (SCM_UNLIKELY (result != locale_encoded)) + result = scm_realloc (result, len * 7); + + scm_i_unistring_escapes_to_r6rs_escapes (result, &len); + } else scm_i_unistring_escapes_to_guile_escapes (result, &len); } |