guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 02/02: scm_seed_to_random_state: Support wide string arg


From: Mark H. Weaver
Subject: [Guile-commits] 02/02: scm_seed_to_random_state: Support wide string arguments.
Date: Fri, 19 Oct 2018 22:20:53 -0400 (EDT)

mhw pushed a commit to branch stable-2.2
in repository guile.

commit fbdcf6358519c415bd2041ca09bee9b16e9d528a
Author: Mark H Weaver <address@hidden>
Date:   Fri Oct 19 21:54:34 2018 -0400

    scm_seed_to_random_state: Support wide string arguments.
    
    Partially fixes <https://bugs.gnu.org/33044>.
    Reported by Tom de Vries <address@hidden>.
    
    * libguile/random.c (scm_seed_to_random_state): Use 'scm_to_utf8_string'
    (or 'scm_to_latin1_string' for a narrow string, for compatibility) to
    convert the string into raw bytes for use by 'scm_c_make_rstate'.  Make
    sure the length in bytes fits within an 'int'.
---
 libguile/random.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/libguile/random.c b/libguile/random.c
index 05147ed..7590dcb 100644
--- a/libguile/random.c
+++ b/libguile/random.c
@@ -441,11 +441,33 @@ SCM_DEFINE (scm_seed_to_random_state, 
"seed->random-state", 1, 0, 0,
 #define FUNC_NAME s_scm_seed_to_random_state
 {
   SCM res;
+  char *c_str;
+  size_t len;
+
   if (SCM_NUMBERP (seed))
     seed = scm_number_to_string (seed, SCM_UNDEFINED);
   SCM_VALIDATE_STRING (1, seed);
-  res = make_rstate (scm_c_make_rstate (scm_i_string_chars (seed),
-                                       scm_i_string_length (seed)));
+
+  if (scm_i_is_narrow_string (seed))
+    /* This special case of a narrow string, where latin1 is used, is
+       for backward compatibility during the 2.2 stable series.  In
+       future major releases, we should use UTF-8 uniformly. */
+    c_str = scm_to_latin1_stringn (seed, &len);
+  else
+    c_str = scm_to_utf8_stringn (seed, &len);
+
+  /* 'scm_to_*_stringn' returns a 'size_t' for the length in bytes, but
+     'scm_c_make_rstate' accepts an 'int'.  Make sure the length fits in
+     an 'int'. */
+  if (len > INT_MAX)
+    {
+      free (c_str);
+      SCM_OUT_OF_RANGE (1, seed);
+    }
+
+  res = make_rstate (scm_c_make_rstate (c_str, len));
+  free (c_str);
+
   scm_remember_upto_here_1 (seed);
   return res;
   



reply via email to

[Prev in Thread] Current Thread [Next in Thread]