guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 02/02: Fix buffer overread in string-locale<?


From: Andy Wingo
Subject: [Guile-commits] 02/02: Fix buffer overread in string-locale<?
Date: Mon, 15 Mar 2021 17:03:59 -0400 (EDT)

wingo pushed a commit to branch master
in repository guile.

commit 72bf9d93ca63d8866cd7f4167469c2d5a5c91c2b
Author: Andy Wingo <wingo@pobox.com>
AuthorDate: Mon Mar 15 22:02:12 2021 +0100

    Fix buffer overread in string-locale<?
    
    * libguile/i18n.c (compare_strings): In all cases, convert to a
    null-terminated string.  While we're doing that, might as well use
    utf-8.
    * test-suite/tests/i18n.test ("text collation (French)"): Add test.
    
    Thanks again to Rob Browning for the report.
---
 libguile/i18n.c            | 41 ++++++++++++++++++-----------------------
 test-suite/tests/i18n.test |  7 +++++++
 2 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/libguile/i18n.c b/libguile/i18n.c
index cc4ef73..52a8080 100644
--- a/libguile/i18n.c
+++ b/libguile/i18n.c
@@ -788,34 +788,29 @@ SCM_DEFINE (scm_locale_p, "locale?", 1, 0, 0,
     } while (0)
 
 
-/* Compare UTF-32 strings according to LOCALE.  Returns a negative value if
-   S1 compares smaller than S2, a positive value if S1 compares larger than
+/* Compare strings according to LOCALE.  Returns a negative value if S1
+   compares smaller than S2, a positive value if S1 compares larger than
    S2, or 0 if they compare equal.  */
 static inline int
-compare_u32_strings (SCM s1, SCM s2, SCM locale, const char *func_name) 
+compare_strings (SCM s1, SCM s2, SCM locale, const char *func_name)
 #define FUNC_NAME func_name
 {
   int result;
   scm_t_locale c_locale;
-  scm_t_wchar *c_s1, *c_s2;
-  int c_s1_malloc_p, c_s2_malloc_p;
+  uint8_t *c_s1, *c_s2;
   SCM_VALIDATE_OPTIONAL_LOCALE_COPY (3, locale, c_locale);
 
-  SCM_STRING_TO_U32_BUF (s1, c_s1, c_s1_malloc_p);
-  SCM_STRING_TO_U32_BUF (s2, c_s2, c_s2_malloc_p);
+  c_s1 = (uint8_t *) scm_to_utf8_string (s1);
+  c_s2 = (uint8_t *) scm_to_utf8_string (s2);
 
   if (c_locale)
-    RUN_IN_LOCALE_SECTION (c_locale, 
-                           result = u32_strcoll ((const uint32_t *) c_s1, 
-                                                 (const uint32_t *) c_s2));
+    RUN_IN_LOCALE_SECTION (c_locale, result = u8_strcoll (c_s1, c_s2));
   else
-    result = u32_strcoll ((const uint32_t *) c_s1,
-                         (const uint32_t *) c_s2);
+    result = u8_strcoll (c_s1, c_s2);
 
-  SCM_CLEANUP_U32_BUF(c_s1, c_s1_malloc_p);
-  SCM_CLEANUP_U32_BUF(c_s2, c_s2_malloc_p);
+  free (c_s1);
+  free (c_s2);
 
-  scm_remember_upto_here_2 (s1, s2);
   scm_remember_upto_here (locale);
   return result;
 }
@@ -907,7 +902,7 @@ SCM_DEFINE (scm_string_locale_lt, "string-locale<?", 2, 1, 
0,
   SCM_VALIDATE_STRING (1, s1);
   SCM_VALIDATE_STRING (2, s2);
 
-  result = compare_u32_strings (s1, s2, locale, FUNC_NAME);
+  result = compare_strings (s1, s2, locale, FUNC_NAME);
 
   return scm_from_bool (result < 0);
 }
@@ -926,7 +921,7 @@ SCM_DEFINE (scm_string_locale_gt, "string-locale>?", 2, 1, 
0,
   SCM_VALIDATE_STRING (1, s1);
   SCM_VALIDATE_STRING (2, s2);
 
-  result = compare_u32_strings (s1, s2, locale, FUNC_NAME);
+  result = compare_strings (s1, s2, locale, FUNC_NAME);
 
   return scm_from_bool (result > 0);
 }
@@ -1004,9 +999,9 @@ SCM_DEFINE (scm_char_locale_lt, "char-locale<?", 2, 1, 0,
   SCM_VALIDATE_CHAR (1, c1);
   SCM_VALIDATE_CHAR (2, c2);
 
-  result = compare_u32_strings (scm_string (scm_list_1 (c1)), 
-                                scm_string (scm_list_1 (c2)), 
-                                locale, FUNC_NAME);
+  result = compare_strings (scm_string (scm_list_1 (c1)),
+                            scm_string (scm_list_1 (c2)),
+                            locale, FUNC_NAME);
 
   return scm_from_bool (result < 0);
 }
@@ -1023,9 +1018,9 @@ SCM_DEFINE (scm_char_locale_gt, "char-locale>?", 2, 1, 0,
   SCM_VALIDATE_CHAR (1, c1);
   SCM_VALIDATE_CHAR (2, c2);
 
-  result = compare_u32_strings (scm_string (scm_list_1 (c1)), 
-                                scm_string (scm_list_1 (c2)), 
-                                locale, FUNC_NAME);
+  result = compare_strings (scm_string (scm_list_1 (c1)),
+                            scm_string (scm_list_1 (c2)),
+                            locale, FUNC_NAME);
 
   return scm_from_bool (result > 0);
 }
diff --git a/test-suite/tests/i18n.test b/test-suite/tests/i18n.test
index 6abd00f..a19b963 100644
--- a/test-suite/tests/i18n.test
+++ b/test-suite/tests/i18n.test
@@ -221,6 +221,13 @@
           (lambda ()
             (setlocale LC_ALL "C"))))))
 
+  (pass-if "string-locale<?, bis"
+    (under-french-utf8-locale-or-unresolved
+     (lambda ()
+       (let* ((strings (list "œa" "œb"))
+              (heads (map (lambda (s) (substring/shared s 0 1)) strings)))
+         (not (apply string-locale<? heads))))))
+
   (pass-if "string-locale-ci=?, bis"
     (under-french-utf8-locale-or-unresolved
      (lambda ()



reply via email to

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