Fix unintentional locale dependency (#3358)
Avoid unintentional locale dependency hb_variation_to_string uses sprintf with %g, which will produce a locale-dependent decimal point, which is not desired here. The output is supposed to be compatible with CSS syntax, and that always uses '.' for the decimal point. Fix this by changing the per-thread locale to "C" around sprintf call. Fixes https://github.com/harfbuzz/harfbuzz/issues/3355 Fixes https://github.com/harfbuzz/harfbuzz/pull/3357 Fixes https://github.com/harfbuzz/harfbuzz/pull/3358 Co-authored-by: Matthias Clasen <mclasen@redhat.com>
This commit is contained in:
parent
d70825a6d1
commit
a45a630539
|
@ -68,8 +68,8 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
|
|||
])
|
||||
|
||||
# Functions and headers
|
||||
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty)
|
||||
AC_CHECK_HEADERS(unistd.h sys/mman.h stdbool.h)
|
||||
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale uselocale)
|
||||
AC_CHECK_HEADERS(unistd.h sys/mman.h stdbool.h xlocale.h)
|
||||
|
||||
# Compiler flags
|
||||
AC_CANONICAL_HOST
|
||||
|
|
|
@ -61,6 +61,7 @@ check_headers = [
|
|||
['unistd.h'],
|
||||
['sys/mman.h'],
|
||||
['stdbool.h'],
|
||||
['xlocale.h'],
|
||||
]
|
||||
|
||||
check_funcs = [
|
||||
|
@ -70,6 +71,8 @@ check_funcs = [
|
|||
['getpagesize'],
|
||||
['mmap'],
|
||||
['isatty'],
|
||||
['uselocale'],
|
||||
['newlocale'],
|
||||
]
|
||||
|
||||
m_dep = cpp.find_library('m', required: false)
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
#include <locale.h>
|
||||
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
#include <xlocale.h> // Needed on BSD/OS X for uselocale
|
||||
#endif
|
||||
|
||||
#ifdef HB_NO_SETLOCALE
|
||||
#define setlocale(Category, Locale) "C"
|
||||
#endif
|
||||
|
@ -122,7 +126,7 @@ hb_tag_from_string (const char *str, int len)
|
|||
* @tag: #hb_tag_t to convert
|
||||
* @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): Converted string
|
||||
*
|
||||
* Converts an #hb_tag_t to a string and returns it in @buf.
|
||||
* Converts an #hb_tag_t to a string and returns it in @buf.
|
||||
* Strings will be four characters long.
|
||||
*
|
||||
* Since: 0.9.5
|
||||
|
@ -151,13 +155,13 @@ const char direction_strings[][4] = {
|
|||
* @str: (array length=len) (element-type uint8_t): String to convert
|
||||
* @len: Length of @str, or -1 if it is %NULL-terminated
|
||||
*
|
||||
* Converts a string to an #hb_direction_t.
|
||||
* Converts a string to an #hb_direction_t.
|
||||
*
|
||||
* Matching is loose and applies only to the first letter. For
|
||||
* examples, "LTR" and "left-to-right" will both return #HB_DIRECTION_LTR.
|
||||
*
|
||||
* Unmatched strings will return #HB_DIRECTION_INVALID.
|
||||
*
|
||||
*
|
||||
* Return value: The #hb_direction_t matching @str
|
||||
*
|
||||
* Since: 0.9.2
|
||||
|
@ -1039,6 +1043,56 @@ hb_variation_from_string (const char *str, int len,
|
|||
return false;
|
||||
}
|
||||
|
||||
#if !defined(HARFBUZZ_NO_SETLOCALE) && defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE)
|
||||
|
||||
#ifdef WIN32
|
||||
using locale_t = _locale_t;
|
||||
#endif
|
||||
|
||||
static inline void free_static_C_locale ();
|
||||
|
||||
static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<locale_t>,
|
||||
hb_C_locale_lazy_loader_t>
|
||||
{
|
||||
static locale_t create ()
|
||||
{
|
||||
locale_t l = newlocale (LC_ALL_MASK, "C", NULL);
|
||||
if (!l)
|
||||
return l;
|
||||
|
||||
hb_atexit (free_static_C_locale);
|
||||
|
||||
return l;
|
||||
}
|
||||
static void destroy (locale_t l)
|
||||
{
|
||||
freelocale (l);
|
||||
}
|
||||
static locale_t get_null ()
|
||||
{
|
||||
return (locale_t) 0;
|
||||
}
|
||||
} static_C_locale;
|
||||
|
||||
static inline
|
||||
void free_static_C_locale ()
|
||||
{
|
||||
static_C_locale.free_instance ();
|
||||
}
|
||||
|
||||
static locale_t
|
||||
get_C_locale ()
|
||||
{
|
||||
return static_C_locale.get_unconst ();
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef WIN32
|
||||
#define locale_t void *
|
||||
#endif
|
||||
#define uselocale(Locale) ((locale_t) 0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hb_variation_to_string:
|
||||
* @variation: an #hb_variation_t to convert
|
||||
|
@ -1064,7 +1118,11 @@ hb_variation_to_string (hb_variation_t *variation,
|
|||
while (len && s[len - 1] == ' ')
|
||||
len--;
|
||||
s[len++] = '=';
|
||||
|
||||
locale_t oldlocale HB_UNUSED;
|
||||
oldlocale = uselocale (get_C_locale ());
|
||||
len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
|
||||
(void) uselocale (oldlocale);
|
||||
|
||||
assert (len < ARRAY_LENGTH (s));
|
||||
len = hb_min (len, size - 1);
|
||||
|
|
Loading…
Reference in New Issue