From 77c06b8e4672edea0edf1323b3c08a0090e1661d Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Thu, 13 Jul 2023 11:01:46 +1000 Subject: [PATCH] hash keys: validate hash key length at compile time This was new to me, I hadn't encountered this failure while working on the original "other I32 bugs". The original test here was failing with an "Out of memory" error since the long hash key length was overflowing the I32. Once that was fixed the test was failing purely due to the invalid code, once that was fixed the test passed so I removed the TODO. --- op.c | 6 +++++- t/bigmem/hash.t | 9 +++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/op.c b/op.c index df43c2a02d10..d06f54ba9595 100644 --- a/op.c +++ b/op.c @@ -2742,7 +2742,11 @@ Perl_check_hash_fields_and_hekify(pTHX_ UNOP *rop, SVOP *key_op, int real) { SSize_t keylen; const char * const key = SvPV_const(sv, *(STRLEN*)&keylen); - SV *nsv = newSVpvn_share(key, SvUTF8(sv) ? -keylen : keylen, 0); + if (keylen > I32_MAX) { + Perl_croak_nocontext("Sorry, hash keys must be smaller than 2**31 bytes"); + } + + SV *nsv = newSVpvn_share(key, SvUTF8(sv) ? -(I32)keylen : (I32)keylen, 0); SvREFCNT_dec_NN(sv); *svp = nsv; } diff --git a/t/bigmem/hash.t b/t/bigmem/hash.t index e3d2980e0212..c56f34295c60 100644 --- a/t/bigmem/hash.t +++ b/t/bigmem/hash.t @@ -25,9 +25,6 @@ like(exn('my $h = { "x" x 2**31, undef }'), qr/^\QSorry, hash keys must be smaller than 2**31 bytes\E\b/, "hash constructed with huge key"); -TODO: { - local $TODO = "Doesn't yet work with OP_MULTIDEREF"; - like(exn('my %h; %h{ "x" x 2**31 } = undef'), - qr/^\QSorry, hash keys must be smaller than 2**31 bytes\E\b/, - "assign to huge hash key"); -} +like(exn('my %h; $h{ "x" x 2**31 } = undef'), + qr/^\QSorry, hash keys must be smaller than 2**31 bytes\E\b/, + "assign to huge hash key");