summaryrefslogtreecommitdiff
path: root/libguile/print.c
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2010-09-15 23:32:28 +0200
committerLudovic Courtès <ludo@gnu.org>2010-09-15 23:32:28 +0200
commitf1ee6d54d219056c62d87a8e4a6b199162c946e8 (patch)
tree2ccec5ae9d5c772111d8b1b48569c8b751d5257a /libguile/print.c
parentfd5eec2b6e113f6d13028215a738417607432a2d (diff)
downloadguile-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.c13
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);
}