diff options
author | Karl Williamson <khw@cpan.org> | 2019-11-08 10:29:05 -0700 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2019-11-08 10:40:18 -0700 |
commit | bd0e76db93fab334167b9594f98cd1c415275b33 (patch) | |
tree | d3dd836f985c4108f5bff2ab4c4c1b17095987a5 | |
parent | 8c27d1fc595fedb029c0f0eda7c846fe56b1406d (diff) | |
download | perl-bd0e76db93fab334167b9594f98cd1c415275b33.tar.gz |
PATCH: gh#17227 heap-buffer-overflow
There were two problems this uncovered. One was that a floating point
expression with both operands ints truncated before becoming floating.
One operand needs to be floating.
The second is that the expansion of a non-UTF-8 byte needs to be
considered based on non-UTF-8, rather than its UTF-8 representation.
-rw-r--r-- | op.c | 14 | ||||
-rw-r--r-- | t/op/tr_latin1.t | 7 |
2 files changed, 19 insertions, 2 deletions
@@ -7336,7 +7336,19 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl) && r_cp_end != TR_SPECIAL_HANDLING && UVCHR_SKIP(t_cp_end) < UVCHR_SKIP(r_cp_end)) { - NV ratio = UVCHR_SKIP(r_cp_end) / UVCHR_SKIP(t_cp); + /* Consider tr/\xCB/\X{E000}/. The maximum expansion + * factor is 1 byte going to 3 if the lhs is not UTF-8, but + * 2 bytes going to 3 if it is in UTF-8. We could pass two + * different values so doop could choose based on the + * UTF-8ness of the target. But khw thinks (perhaps + * wrongly) that is overkill. It is used only to make sure + * we malloc enough space. If no target string can force + * the result to be UTF-8, then we don't have to worry + * about this */ + NV t_size = (can_force_utf8 && t_cp < 256) + ? 1 + : UVCHR_SKIP(t_cp_end); + NV ratio = UVCHR_SKIP(r_cp_end) / t_size; o->op_private |= OPpTRANS_GROWS; diff --git a/t/op/tr_latin1.t b/t/op/tr_latin1.t index 3cfe6f92a6..9d08652aaf 100644 --- a/t/op/tr_latin1.t +++ b/t/op/tr_latin1.t @@ -7,7 +7,7 @@ BEGIN { set_up_inc('../lib'); } -plan tests => 1; +plan tests => 2; { # This test is malloc senstive. Right now on some platforms anyway, space # for the final \xff needs to be mallocd, and that's what caused the @@ -18,4 +18,9 @@ plan tests => 1; } +{ # gh#17277. This caused errors with valgrind and asan + fresh_perl_is('no warnings qw(void uninitialized); s~~00~-y~Ë0~\x{E00}~', + "", {}, 'gh#17227'); +} + 1; |