mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-28 13:53:10 +00:00
Fix wcstod_l
infinite recursion under FreeBSD
This was the actual issue leading to memory corruption under FreeBSD in issue #5453, worked around by correcting the detection of `wcstod_l` so that our version of the function is not called at all. If we are 100% certain that `wcstod_l` does not exist, then then the existing code is fine. But given that our checks have failed seperately on two different platforms already (FreeBSD and Cygwin/newlib), it's a good precaution to take.
This commit is contained in:
parent
72423c517a
commit
a1df72dbb6
2 changed files with 15 additions and 4 deletions
|
@ -390,9 +390,10 @@ int flock(int fd, int op) {
|
|||
#endif // HAVE_FLOCK
|
||||
|
||||
#ifndef HAVE_WCSTOD_L
|
||||
// musl doesn't feature wcstod_l,
|
||||
// so we just wrap wcstod.
|
||||
double wcstod_l(const wchar_t *enptr, wchar_t **endptr, locale_t loc) {
|
||||
#undef wcstod_l
|
||||
// For platforms without wcstod_l C extension, wrap wcstod after changing the
|
||||
// thread-specific locale.
|
||||
double fish_compat::wcstod_l(const wchar_t *enptr, wchar_t **endptr, locale_t loc) {
|
||||
char *saved_locale = strdup(setlocale(LC_NUMERIC, NULL));
|
||||
// Yes, this is hardcoded to use the "C" locale.
|
||||
// That's the only thing we need, and uselocale(loc) broke in my testing.
|
||||
|
|
|
@ -200,5 +200,15 @@ int flock(int fd, int op);
|
|||
#endif
|
||||
|
||||
#ifndef HAVE_WCSTOD_L
|
||||
double wcstod_l(const wchar_t *enptr, wchar_t **endptr, locale_t loc);
|
||||
// On some platforms if this is incorrectly detected and a system-defined
|
||||
// defined version of `wcstod_l` exists, calling `wcstod` from our own
|
||||
// `wcstod_l` can call back into `wcstod_l` causing infinite recursion.
|
||||
// e.g. FreeBSD defines `wcstod(x, y)` as `wcstod_l(x, y, __get_locale())`.
|
||||
// Solution: namespace our implementation to make sure there is no symbol
|
||||
// duplication.
|
||||
#undef wcstod_l
|
||||
namespace fish_compat {
|
||||
double wcstod_l(const wchar_t *enptr, wchar_t **endptr, locale_t loc);
|
||||
}
|
||||
#define wcstod_l(x, y, z) fish_compat::wcstod_l(x, y, z)
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue