summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2019-11-08 10:29:05 -0700
committerKarl Williamson <khw@cpan.org>2019-11-08 10:40:18 -0700
commitbd0e76db93fab334167b9594f98cd1c415275b33 (patch)
treed3dd836f985c4108f5bff2ab4c4c1b17095987a5
parent8c27d1fc595fedb029c0f0eda7c846fe56b1406d (diff)
downloadperl-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.c14
-rw-r--r--t/op/tr_latin1.t7
2 files changed, 19 insertions, 2 deletions
diff --git a/op.c b/op.c
index 593b88aa83..41824a43a8 100644
--- a/op.c
+++ b/op.c
@@ -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;