In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/fdc080f3f22884c216544189aa3e6d2881d62aca?hp=c195f169da68a3e2a2b2222e9d4e910afde61fb2>
- Log ----------------------------------------------------------------- commit fdc080f3f22884c216544189aa3e6d2881d62aca Author: Karl Williamson <k...@cpan.org> Date: Tue Aug 23 13:32:05 2016 -0600 locale.c: Use my_strlcat() strcat() is safe in this context, but some compilers were optimizing this to strcpy() causing a porting test to fail that looks for unsafe code. Rather than fighting this, just use my_strlcat(). The code is rarely executed. But at the same time, I used the return value of that function to know where to start the next cat in the next loop iteration without having to have the cat code search for the trailing NUL. M locale.c M t/porting/libperl.t commit 6ade12daa2cd5173688ad25a93d2770398349059 Author: Karl Williamson <k...@cpan.org> Date: Tue Aug 23 13:30:45 2016 -0600 perlapi: Document returns from my_strlcat, my_strlcpy M util.c ----------------------------------------------------------------------- Summary of changes: locale.c | 22 +++++++++++++--------- t/porting/libperl.t | 7 ------- util.c | 7 +++++++ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/locale.c b/locale.c index 9f64d80..779324e 100644 --- a/locale.c +++ b/locale.c @@ -1462,15 +1462,13 @@ Perl__mem_collxfrm(pTHX_ const char *input_string, * This will give as good as possible results on strings that don't * otherwise contain that character, but otherwise there may be * less-than-perfect results with that character and NUL. This is - * unavoidable unless we replace strxfrm with our own implementation. - * - * This is one of the few places in the perl core, where we can use - * standard functions like strlen() and strcat(). It's because we're - * looking for NULs. */ + * unavoidable unless we replace strxfrm with our own implementation. */ if (s_strlen < len) { char * e = s + len; char * sans_nuls; STRLEN cur_min_char_len; + STRLEN sans_nuls_len; + STRLEN sans_nuls_pos; int try_non_controls; /* If we don't know what control character sorts lowest for this @@ -1576,16 +1574,22 @@ Perl__mem_collxfrm(pTHX_ const char *input_string, * character in it is NUL. Multiply that by the length of each * replacement, and allow for a trailing NUL */ cur_min_char_len = strlen(PL_strxfrm_min_char); - Newx(sans_nuls, (len * cur_min_char_len) + 1, char); + sans_nuls_len = (len * cur_min_char_len) + 1; + Newx(sans_nuls, sans_nuls_len, char); *sans_nuls = '\0'; + sans_nuls_pos = 0; /* Replace each NUL with the lowest collating control. Loop until have * exhausted all the NULs */ while (s + s_strlen < e) { - strcat(sans_nuls, s); + sans_nuls_pos = my_strlcat(sans_nuls + sans_nuls_pos, + s, + sans_nuls_len); /* Do the actual replacement */ - strcat(sans_nuls, PL_strxfrm_min_char); + sans_nuls_pos = my_strlcat(sans_nuls + sans_nuls_pos, + PL_strxfrm_min_char, + sans_nuls_len); /* Move past the input NUL */ s += s_strlen + 1; @@ -1593,7 +1597,7 @@ Perl__mem_collxfrm(pTHX_ const char *input_string, } /* And add anything that trails the final NUL */ - strcat(sans_nuls, s); + my_strlcat(sans_nuls + sans_nuls_pos, s, sans_nuls_len); /* Switch so below we transform this modified string */ s = sans_nuls; diff --git a/t/porting/libperl.t b/t/porting/libperl.t index 21e7edb..4a3e568 100644 --- a/t/porting/libperl.t +++ b/t/porting/libperl.t @@ -540,13 +540,6 @@ for my $symbol (sort keys %unexpected) { SKIP: { skip("uses sprintf for Gconvert in sv.o"); } - } - elsif ( $symbol eq 'strcat' - && @o == 1 && $o[0] eq 'locale.o') - { - SKIP: { - skip("locale.o legitimately uses strcat"); - } } else { is(@o, 0, "uses no $symbol (@o)"); } diff --git a/util.c b/util.c index 7748c6c..069aca3 100644 --- a/util.c +++ b/util.c @@ -5704,6 +5704,10 @@ Note that C<size> is the full size of the destination buffer and the result is guaranteed to be C<NUL>-terminated if there is room. Note that room for the C<NUL> should be included in C<size>. +The return value is the total length that C<dst> would have if C<size> is +sufficiently large. Thus it is the initial length of C<dst> plus the length of +C<src>. If C<size> is smaller than the return, the excess was not appended. + =cut Description stolen from http://www.openbsd.org/cgi-bin/man.cgi?query=strlcat @@ -5735,6 +5739,9 @@ This operates on C C<NUL>-terminated strings. C<my_strlcpy()> copies up to S<C<size - 1>> characters from the string C<src> to C<dst>, C<NUL>-terminating the result if C<size> is not 0. +The return value is the total length C<src> would be if the copy completely +succeeded. If it is larger than C<size>, the excess was not copied. + =cut Description stolen from http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy -- Perl5 Master Repository