mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-08 23:58:31 +08:00
test: Fix and stabilize tst-wcsmbs-clone-overflow test
The test tst-wcsmbs-clone-overflow was initially added to tests-static. However, this causes the test to be unstable because gconv modules dynamically load libc.so. Any discrepancy between the statically linked version and the dynamically loaded one can lead to a crash. By removing the test from tests-static, it relies on dynamic linking, safely bypassing the dlopen crash. Since the test is now dynamically linked, it cannot use the internal thread-local symbol _NL_CURRENT_DATA(LC_CTYPE) because _nl_current_LC_CTYPE is hidden in libc.so, leading to undefined references. Thus, the test now uses newlocale and uselocale, safely extracting the locale data from the returned locale_t object. Furthermore, using newlocale requires the gconv-modules configuration to be built and available so that the ISO8859-1.so module can be dynamically loaded. Otherwise, glibc falls back to the built-in C locale conversions, leaving __shlib_handle as NULL and silently bypassing the reference counter increment. A new Makefile fragment, gen-gconv-modules.mk, is introduced to ensure the gconv-modules are built before the test runs, and an explicit check for __shlib_handle != NULL is added to the test. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
# defines target $(gen-gconv-modules) that ensures gconv-modules are available
|
||||
|
||||
gen-gconv-modules := $(common-objpfx)iconvdata/gconv-modules
|
||||
|
||||
$(gen-gconv-modules):
|
||||
$(MAKE) -C ../iconvdata subdir=iconvdata $@
|
||||
+2
-4
@@ -287,7 +287,7 @@ install-others := $(addprefix $(inst_i18ndir)/, \
|
||||
$(locales))
|
||||
endif
|
||||
|
||||
tests: $(objdir)/iconvdata/gconv-modules
|
||||
tests: $(gen-gconv-modules)
|
||||
|
||||
tests-static += \
|
||||
tst-langinfo-newlocale-static \
|
||||
@@ -412,6 +412,7 @@ LOCALES := \
|
||||
# LOCALES
|
||||
|
||||
include ../gen-locales.mk
|
||||
include ../gen-gconv-modules.mk
|
||||
|
||||
$(objpfx)tst-iconv-emojis-trans.out: $(gen-locales)
|
||||
|
||||
@@ -587,6 +588,3 @@ $(objpfx)mtrace-tst-leaks.out: $(objpfx)tst-leaks.out
|
||||
|
||||
bug-setlocale1-ENV-only = LOCPATH=$(objpfx) LC_CTYPE=de_DE.UTF-8
|
||||
bug-setlocale1-static-ENV-only = $(bug-setlocale1-ENV-only)
|
||||
|
||||
$(objdir)/iconvdata/gconv-modules:
|
||||
$(MAKE) -C ../iconvdata subdir=iconvdata $@
|
||||
|
||||
+2
-5
@@ -213,10 +213,6 @@ xtests += test-wcsncmp-nonarray
|
||||
tests-internal += \
|
||||
tst-wcsmbs-clone-overflow
|
||||
|
||||
tests-static += \
|
||||
tst-wcsmbs-clone-overflow
|
||||
|
||||
|
||||
include ../Rules
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
@@ -233,6 +229,7 @@ LOCALES := \
|
||||
zh_TW.EUC-TW \
|
||||
# LOCALES
|
||||
include ../gen-locales.mk
|
||||
include ../gen-gconv-modules.mk
|
||||
|
||||
$(objpfx)tst-btowc.out: $(gen-locales)
|
||||
$(objpfx)tst-c16c32-1.out: $(gen-locales)
|
||||
@@ -247,7 +244,7 @@ $(objpfx)tst-c32-state.out: $(gen-locales)
|
||||
$(objpfx)test-c8rtomb.out: $(gen-locales)
|
||||
$(objpfx)test-mbrtoc8.out: $(gen-locales)
|
||||
$(objpfx)tst-wscanf-to_inpunct.out: $(gen-locales)
|
||||
$(objpfx)tst-wcsmbs-clone-overflow.out: $(gen-locales)
|
||||
$(objpfx)tst-wcsmbs-clone-overflow.out: $(gen-locales) $(gen-gconv-modules)
|
||||
endif
|
||||
|
||||
$(objpfx)tst-wcstod-round: $(libm)
|
||||
|
||||
@@ -30,8 +30,11 @@
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
if (setlocale (LC_ALL, "de_DE.ISO-8859-1") == NULL)
|
||||
FAIL_EXIT1 ("setlocale failed, check if de_DE.ISO-8859-1 is generated");
|
||||
locale_t loc_obj = newlocale (LC_ALL_MASK, "de_DE.ISO-8859-1", NULL);
|
||||
if (loc_obj == NULL)
|
||||
FAIL_EXIT1 ("newlocale failed, check if de_DE.ISO-8859-1 is generated");
|
||||
|
||||
uselocale (loc_obj);
|
||||
|
||||
wchar_t buf[32] = L"123";
|
||||
int j;
|
||||
@@ -41,7 +44,7 @@ do_test (void)
|
||||
FAIL_EXIT1 ("swscanf failed");
|
||||
|
||||
/* Retrieve the current gconv_fcts from the LC_CTYPE locale data. */
|
||||
struct __locale_data *loc = _NL_CURRENT_DATA (LC_CTYPE);
|
||||
struct __locale_data *loc = loc_obj->__locales[LC_CTYPE];
|
||||
struct lc_ctype_data *ctype = loc->private;
|
||||
const struct gconv_fcts *fcts = ctype->fcts;
|
||||
|
||||
@@ -51,6 +54,9 @@ do_test (void)
|
||||
/* Capture the reference counter. */
|
||||
int initial_counter = fcts->towc->__counter;
|
||||
|
||||
if (fcts->towc->__shlib_handle == NULL)
|
||||
FAIL_EXIT1 ("__shlib_handle is NULL!");
|
||||
|
||||
/* Perform a second iteration of swscanf. If the stack-allocated FILE
|
||||
leaks the gconv reference, the counter will increment. */
|
||||
if (swscanf (buf, L"%d", &j) < 1)
|
||||
|
||||
Reference in New Issue
Block a user