mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
Fix buffer overread in string-locale-ci=? and related functions
* libguile/i18n.c (u32_locale_casecoll): Take lengths of incoming strings as parameters rather than assuming "nul" termination. (compare_u32_strings_ci): Pass string lengths as computed from the Scheme strings. * test-suite/tests/i18n.test ("text collation (English)"): Add a test case. Thanks a million to Rob Browning for the report.
This commit is contained in:
parent
5a1a1eee50
commit
d87b57a00b
2 changed files with 18 additions and 12 deletions
|
@ -833,9 +833,8 @@ locale_language ()
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
u32_locale_casecoll (const char *func_name, const uint32_t *c_s1,
|
u32_locale_casecoll (const char *func_name, const uint32_t *c_s1, size_t s1_len,
|
||||||
const uint32_t *c_s2,
|
const uint32_t *c_s2, size_t s2_len, int *result)
|
||||||
int *result)
|
|
||||||
{
|
{
|
||||||
/* Note: Since this is called from `RUN_IN_LOCALE_SECTION', it must note
|
/* Note: Since this is called from `RUN_IN_LOCALE_SECTION', it must note
|
||||||
make any non-local exit. */
|
make any non-local exit. */
|
||||||
|
@ -843,8 +842,8 @@ u32_locale_casecoll (const char *func_name, const uint32_t *c_s1,
|
||||||
int ret;
|
int ret;
|
||||||
const char *loc = locale_language ();
|
const char *loc = locale_language ();
|
||||||
|
|
||||||
ret = u32_casecoll (c_s1, u32_strlen (c_s1),
|
ret = u32_casecoll (c_s1, s1_len,
|
||||||
c_s2, u32_strlen (c_s2),
|
c_s2, s2_len,
|
||||||
loc, UNINORM_NFC, result);
|
loc, UNINORM_NFC, result);
|
||||||
|
|
||||||
return ret == 0 ? ret : errno;
|
return ret == 0 ? ret : errno;
|
||||||
|
@ -860,6 +859,9 @@ compare_u32_strings_ci (SCM s1, SCM s2, SCM locale, const char *func_name)
|
||||||
int c_s1_malloc_p, c_s2_malloc_p;
|
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);
|
||||||
|
|
||||||
|
size_t s1_len = scm_i_string_length (s1);
|
||||||
|
size_t s2_len = scm_i_string_length (s2);
|
||||||
|
|
||||||
SCM_STRING_TO_U32_BUF (s1, c_s1, c_s1_malloc_p);
|
SCM_STRING_TO_U32_BUF (s1, c_s1, c_s1_malloc_p);
|
||||||
SCM_STRING_TO_U32_BUF (s2, c_s2, c_s2_malloc_p);
|
SCM_STRING_TO_U32_BUF (s2, c_s2, c_s2_malloc_p);
|
||||||
|
|
||||||
|
@ -867,13 +869,13 @@ compare_u32_strings_ci (SCM s1, SCM s2, SCM locale, const char *func_name)
|
||||||
RUN_IN_LOCALE_SECTION
|
RUN_IN_LOCALE_SECTION
|
||||||
(c_locale,
|
(c_locale,
|
||||||
ret = u32_locale_casecoll (func_name,
|
ret = u32_locale_casecoll (func_name,
|
||||||
(const uint32_t *) c_s1,
|
(const uint32_t *) c_s1, s1_len,
|
||||||
(const uint32_t *) c_s2,
|
(const uint32_t *) c_s2, s2_len,
|
||||||
&result));
|
&result));
|
||||||
else
|
else
|
||||||
ret = u32_locale_casecoll (func_name,
|
ret = u32_locale_casecoll (func_name,
|
||||||
(const uint32_t *) c_s1,
|
(const uint32_t *) c_s1, s1_len,
|
||||||
(const uint32_t *) c_s2,
|
(const uint32_t *) c_s2, s2_len,
|
||||||
&result);
|
&result);
|
||||||
|
|
||||||
SCM_CLEANUP_U32_BUF(c_s1, c_s1_malloc_p);
|
SCM_CLEANUP_U32_BUF(c_s1, c_s1_malloc_p);
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
;;;; i18n.test --- Exercise the i18n API. -*- coding: utf-8; mode: scheme; -*-
|
;;;; i18n.test --- Exercise the i18n API. -*- coding: utf-8; mode: scheme; -*-
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012,
|
;;;; Copyright (C) 2006-2007,2009-2019,2021 Free Software Foundation, Inc.
|
||||||
;;;; 2013, 2014, 2015, 2016, 2017, 2018 Free Software Foundation, Inc.
|
;;;; Author: Ludovic Courtès
|
||||||
;;;; Ludovic Courtès
|
|
||||||
;;;;
|
;;;;
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -75,6 +74,11 @@
|
||||||
(string-locale-ci=? "Hello" "HELLO"
|
(string-locale-ci=? "Hello" "HELLO"
|
||||||
(make-locale (list LC_COLLATE) "C"))))
|
(make-locale (list LC_COLLATE) "C"))))
|
||||||
|
|
||||||
|
(pass-if "string-locale-ci=?, bis"
|
||||||
|
(let* ((strings (list "⇒a" "⇒b"))
|
||||||
|
(heads (map (lambda (s) (substring/shared s 0 1)) strings)))
|
||||||
|
(apply string-locale-ci=? heads)))
|
||||||
|
|
||||||
(pass-if "string-locale-ci<?"
|
(pass-if "string-locale-ci<?"
|
||||||
(and (string-locale-ci<? "hello" "WORLD")
|
(and (string-locale-ci<? "hello" "WORLD")
|
||||||
(string-locale-ci<? "hello" "WORLD"
|
(string-locale-ci<? "hello" "WORLD"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue