diff options
author | Karl Williamson <khw@cpan.org> | 2016-07-26 14:09:46 -0600 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2016-08-02 19:31:07 -0600 |
commit | 1adab0a73adeec06e0378323cb104a410fd4cc1b (patch) | |
tree | f536f8f0c8fd494e90173615ae725d708429cfec /locale.c | |
parent | d4ff958684aa549b9e8db9c80ac5dc2b08461e38 (diff) | |
download | perl-1adab0a73adeec06e0378323cb104a410fd4cc1b.tar.gz |
locale.c: Some systems include NUL in strxfrm() return
strxfrm() is supposed to not include the trailing NUL in the length
returned, but we have run into a Windows system that does include it
(some Windows ones don't), so test for and compensate for this
possibility.
Diffstat (limited to 'locale.c')
-rw-r--r-- | locale.c | 16 |
1 files changed, 13 insertions, 3 deletions
@@ -1758,6 +1758,7 @@ Perl__mem_collxfrm(pTHX_ const char *input_string, /* Then the transformation of the input. We loop until successful, or we * give up */ for (;;) { + *xlen = strxfrm(xbuf + COLLXFRM_HDR_LEN, s, xAlloc - COLLXFRM_HDR_LEN); /* If the transformed string occupies less space than we told strxfrm() @@ -1765,6 +1766,15 @@ Perl__mem_collxfrm(pTHX_ const char *input_string, * string. */ if (*xlen < xAlloc - COLLXFRM_HDR_LEN) { + /* Some systems include a trailing NUL in the returned length. + * Ignore it, using a loop in case multiple trailing NULs are + * returned. */ + while ( (*xlen) > 0 + && *(xbuf + COLLXFRM_HDR_LEN + (*xlen) - 1) == '\0') + { + (*xlen)--; + } + /* If the first try didn't get it, it means our prediction was low. * Modify the coefficients so that we predict a larger value in any * future transformations */ @@ -1827,9 +1837,9 @@ Perl__mem_collxfrm(pTHX_ const char *input_string, goto bad; /* A well-behaved strxfrm() returns exactly how much space it needs - * (not including the trailing NUL) when it fails due to not enough - * space being provided. Assume that this is the case unless it's been - * proven otherwise */ + * (usually not including the trailing NUL) when it fails due to not + * enough space being provided. Assume that this is the case unless + * it's been proven otherwise */ if (LIKELY(PL_strxfrm_is_behaved) && first_time) { xAlloc = *xlen + COLLXFRM_HDR_LEN + 1; } |