mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
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.
This commit is contained in:
parent
8a8727db5c
commit
72bf9d93ca
2 changed files with 25 additions and 23 deletions
|
@ -788,34 +788,29 @@ SCM_DEFINE (scm_locale_p, "locale?", 1, 0, 0,
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
/* Compare UTF-32 strings according to LOCALE. Returns a negative value if
|
/* Compare strings according to LOCALE. Returns a negative value if S1
|
||||||
S1 compares smaller than S2, a positive value if S1 compares larger than
|
compares smaller than S2, a positive value if S1 compares larger than
|
||||||
S2, or 0 if they compare equal. */
|
S2, or 0 if they compare equal. */
|
||||||
static inline int
|
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
|
#define FUNC_NAME func_name
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
scm_t_locale c_locale;
|
scm_t_locale c_locale;
|
||||||
scm_t_wchar *c_s1, *c_s2;
|
uint8_t *c_s1, *c_s2;
|
||||||
int c_s1_malloc_p, c_s2_malloc_p;
|
|
||||||
SCM_VALIDATE_OPTIONAL_LOCALE_COPY (3, locale, c_locale);
|
SCM_VALIDATE_OPTIONAL_LOCALE_COPY (3, locale, c_locale);
|
||||||
|
|
||||||
SCM_STRING_TO_U32_BUF (s1, c_s1, c_s1_malloc_p);
|
c_s1 = (uint8_t *) scm_to_utf8_string (s1);
|
||||||
SCM_STRING_TO_U32_BUF (s2, c_s2, c_s2_malloc_p);
|
c_s2 = (uint8_t *) scm_to_utf8_string (s2);
|
||||||
|
|
||||||
if (c_locale)
|
if (c_locale)
|
||||||
RUN_IN_LOCALE_SECTION (c_locale,
|
RUN_IN_LOCALE_SECTION (c_locale, result = u8_strcoll (c_s1, c_s2));
|
||||||
result = u32_strcoll ((const uint32_t *) c_s1,
|
|
||||||
(const uint32_t *) c_s2));
|
|
||||||
else
|
else
|
||||||
result = u32_strcoll ((const uint32_t *) c_s1,
|
result = u8_strcoll (c_s1, c_s2);
|
||||||
(const uint32_t *) c_s2);
|
|
||||||
|
|
||||||
SCM_CLEANUP_U32_BUF(c_s1, c_s1_malloc_p);
|
free (c_s1);
|
||||||
SCM_CLEANUP_U32_BUF(c_s2, c_s2_malloc_p);
|
free (c_s2);
|
||||||
|
|
||||||
scm_remember_upto_here_2 (s1, s2);
|
|
||||||
scm_remember_upto_here (locale);
|
scm_remember_upto_here (locale);
|
||||||
return result;
|
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 (1, s1);
|
||||||
SCM_VALIDATE_STRING (2, s2);
|
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);
|
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 (1, s1);
|
||||||
SCM_VALIDATE_STRING (2, s2);
|
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);
|
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 (1, c1);
|
||||||
SCM_VALIDATE_CHAR (2, c2);
|
SCM_VALIDATE_CHAR (2, c2);
|
||||||
|
|
||||||
result = compare_u32_strings (scm_string (scm_list_1 (c1)),
|
result = compare_strings (scm_string (scm_list_1 (c1)),
|
||||||
scm_string (scm_list_1 (c2)),
|
scm_string (scm_list_1 (c2)),
|
||||||
locale, FUNC_NAME);
|
locale, FUNC_NAME);
|
||||||
|
|
||||||
return scm_from_bool (result < 0);
|
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 (1, c1);
|
||||||
SCM_VALIDATE_CHAR (2, c2);
|
SCM_VALIDATE_CHAR (2, c2);
|
||||||
|
|
||||||
result = compare_u32_strings (scm_string (scm_list_1 (c1)),
|
result = compare_strings (scm_string (scm_list_1 (c1)),
|
||||||
scm_string (scm_list_1 (c2)),
|
scm_string (scm_list_1 (c2)),
|
||||||
locale, FUNC_NAME);
|
locale, FUNC_NAME);
|
||||||
|
|
||||||
return scm_from_bool (result > 0);
|
return scm_from_bool (result > 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,6 +221,13 @@
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(setlocale LC_ALL "C"))))))
|
(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"
|
(pass-if "string-locale-ci=?, bis"
|
||||||
(under-french-utf8-locale-or-unresolved
|
(under-french-utf8-locale-or-unresolved
|
||||||
(lambda ()
|
(lambda ()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue