From 024cd9ef0d2e71888b068398656405f0c3388845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= Date: Fri, 5 Apr 2019 16:24:28 +0200 Subject: [PATCH] Fix mbstate_t initialization in POSIX::mblen --- ...mbstate_t-initialization-on-threaded.patch | 138 ++++++++++++++++++ perl.spec | 7 + 2 files changed, 145 insertions(+) create mode 100644 perl-5.28.1-Fix-POSIX-mblen-mbstate_t-initialization-on-threaded.patch diff --git a/perl-5.28.1-Fix-POSIX-mblen-mbstate_t-initialization-on-threaded.patch b/perl-5.28.1-Fix-POSIX-mblen-mbstate_t-initialization-on-threaded.patch new file mode 100644 index 0000000..24245fd --- /dev/null +++ b/perl-5.28.1-Fix-POSIX-mblen-mbstate_t-initialization-on-threaded.patch @@ -0,0 +1,138 @@ +From 37f30deca415d6c2606bf088e09f978134b9e2e1 Mon Sep 17 00:00:00 2001 +From: Niko Tyni +Date: Sun, 10 Mar 2019 19:40:42 +0200 +Subject: [PATCH] Fix POSIX::mblen mbstate_t initialization on threaded perls + with glibc +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As reported in https://bugs.launchpad.net/bugs/1818953 POSIX::mblen() +is broken on threaded perls with glibc. + + % perl -MPOSIX=mblen -e 'mblen("a", 1)' + perl: mbrtowc.c:105: __mbrtowc: Assertion `__mbsinit (data.__statep)' failed. + zsh: abort (core dumped) perl -MPOSIX=mblen -e 'mblen("a", 1)' + +This broke in v5.27.8-134-g6c9ff7e96e which made the function +use mbrlen(3) under the hood on threaded perls. + +The problem is initialization of the shift state with + + mbrlen(NULL, 0, &ps)); + +The glibc documentation for mbrlen(3) at + + https://www.gnu.org/software/libc/manual/html_node/Converting-a-Character.html#Converting-a-Character + +does not mention initialization by passing in a null pointer for the +string, only a pointer to a NUL wide character. + + If the next multibyte character corresponds to the NUL wide character, + the return value is 0. If the next n bytes form a valid multibyte + character, the number of bytes belonging to this multibyte character + byte sequence is returned. + +Use memset(3) instead for mbstate_t initialization, as suggested in + + https://www.gnu.org/software/libc/manual/html_node/Keeping-the-state.html + +with the hope that this is more portable. + +While at it, add a few basic test cases. These are in a new file because +they need fresh_perl_is() from test.pl while the existing ones use +Test::More (and conversion of at least posix.t looks way too involved.) + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1818953 +Petr Písař: Ported to 5.28.1 from +25d7b7aa379d33ce2e8fe3e2bef4206b35739bc5. + +Signed-off-by: Petr Písař +--- + MANIFEST | 1 + + ext/POSIX/POSIX.xs | 2 +- + ext/POSIX/t/mb.t | 47 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 49 insertions(+), 1 deletion(-) + create mode 100644 ext/POSIX/t/mb.t + +diff --git a/MANIFEST b/MANIFEST +index 9fbbe9a..e4e63c3 100644 +--- a/MANIFEST ++++ b/MANIFEST +@@ -4204,6 +4204,7 @@ ext/POSIX/POSIX.xs POSIX extension external subroutines + ext/POSIX/t/export.t Test @EXPORT and @EXPORT_OK + ext/POSIX/t/iscrash See if POSIX isxxx() crashes with threads on Win32 + ext/POSIX/t/math.t Basic math tests for POSIX ++ext/POSIX/t/mb.t Multibyte function tests for POSIX + ext/POSIX/t/posix.t See if POSIX works + ext/POSIX/t/sigaction.t See if POSIX::sigaction works + ext/POSIX/t/sigset.t See if POSIX::SigSet works +diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs +index 7497305..395025a 100644 +--- a/ext/POSIX/POSIX.xs ++++ b/ext/POSIX/POSIX.xs +@@ -3318,7 +3318,7 @@ mblen(s, n) + #endif + CODE: + #if defined(USE_ITHREADS) && defined(HAS_MBRLEN) +- PERL_UNUSED_RESULT(mbrlen(NULL, 0, &ps)); /* Initialize state */ ++ memset(&ps, 0, sizeof(ps)); /* Initialize state */ + RETVAL = mbrlen(s, n, &ps); /* Prefer reentrant version */ + #else + RETVAL = mblen(s, n); +diff --git a/ext/POSIX/t/mb.t b/ext/POSIX/t/mb.t +new file mode 100644 +index 0000000..961edf6 +--- /dev/null ++++ b/ext/POSIX/t/mb.t +@@ -0,0 +1,47 @@ ++#!./perl ++ ++# These tests are in a separate file, because they use fresh_perl_is() ++# from test.pl. ++ ++# The mb* functions use the "underlying locale" that is not affected by ++# the Perl one. So we run the tests in a separate "fresh_perl" process ++# with the correct LC_CTYPE set in the environment. ++ ++BEGIN { ++ require Config; import Config; ++ if ($^O ne 'VMS' and $Config{'extensions'} !~ /\bPOSIX\b/) { ++ print "1..0\n"; ++ exit 0; ++ } ++ unshift @INC, "../../t"; ++ require 'loc_tools.pl'; ++ require 'test.pl'; ++} ++ ++plan tests => 3; ++ ++use POSIX qw(); ++ ++SKIP: { ++ skip("mblen() not present", 3) unless $Config{d_mblen}; ++ ++ is(&POSIX::mblen("a", &POSIX::MB_CUR_MAX), 1, 'mblen() basically works'); ++ ++ skip("LC_CTYPE locale support not available", 2) ++ unless locales_enabled('LC_CTYPE'); ++ ++ my $utf8_locale = find_utf8_ctype_locale(); ++ skip("no utf8 locale available", 2) unless $utf8_locale; ++ ++ local $ENV{LC_CTYPE} = $utf8_locale; ++ local $ENV{LC_ALL}; ++ delete $ENV{LC_ALL}; ++ ++ fresh_perl_is( ++ 'use POSIX; print &POSIX::mblen("\x{c3}\x{28}", &POSIX::MB_CUR_MAX)', ++ -1, {}, 'mblen() recognizes invalid multibyte characters'); ++ ++ fresh_perl_is( ++ 'use POSIX; print &POSIX::mblen("\N{GREEK SMALL LETTER SIGMA}", &POSIX::MB_CUR_MAX)', ++ 2, {}, 'mblen() works on UTF-8 characters'); ++} +-- +2.20.1 + diff --git a/perl.spec b/perl.spec index b72e84f..fdb8e83 100644 --- a/perl.spec +++ b/perl.spec @@ -272,6 +272,10 @@ Patch58: perl-5.29.8-handle-scope-error-in-qr.patch # character name, RT#133880, in upstream after 5.29.9 Patch59: perl-5.28.1-PATCH-perl-133880-assertion-failure.patch +# Fix mbstate_t initialization in POSIX::mblen, RT#133928, +# in upstream after 5.29.9 +Patch60: perl-5.28.1-Fix-POSIX-mblen-mbstate_t-initialization-on-threaded.patch + # Link XS modules to libperl.so with EU::CBuilder on Linux, bug #960048 Patch200: perl-5.16.3-Link-XS-modules-to-libperl.so-with-EU-CBuilder-on-Li.patch @@ -2887,6 +2891,7 @@ Perl extension for Version Objects %patch57 -p1 %patch58 -p1 %patch59 -p1 +%patch60 -p1 %patch200 -p1 %patch201 -p1 @@ -2938,6 +2943,7 @@ perl -x patchlevel.h \ 'Fedora Patch56: Fix a leak when compiling a typed hash dereference' \ 'Fedora Patch58: Fix a buffer overread when handling a scope error in qr/\(?{/ (RT#133879)' \ 'Fedora Patch59: Fix a buffer overread when parsing a regular expression with an unknown character name (RT#133880)' \ + 'Fedora Patch60: Fix mbstate_t initialization in POSIX::mblen (RT#133928)' \ 'Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux' \ 'Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux' \ %{nil} @@ -5231,6 +5237,7 @@ popd - Fix a buffer overread when handling a scope error in qr/\(?{/ (RT#133879) - Fix a buffer overread when parsing a regular expression with an unknown character name (RT#133880) +- Fix mbstate_t initialization in POSIX::mblen (RT#133928) * Tue Mar 05 2019 Björn Esser - 4:5.28.1-434 - Add explicit Requires: libxcrypt-devel to devel sub-package (bug #1666098)