diff options
author | Yves Orton <demerphq@gmail.com> | 2020-07-11 09:26:21 +0200 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2021-02-12 19:21:28 +0100 |
commit | aae087f7cec022be14a17deb95cb2208e16b7891 (patch) | |
tree | 00c8f01294cb90d0b7a6a888617f0ad89d6af41c /hv.c | |
parent | d18575f18c6ee61ce80492e82cae7361358d570a (diff) | |
download | perl-aae087f7cec022be14a17deb95cb2208e16b7891.tar.gz |
hv.c: add a guard clause to prevent the number of buckets in a hash from getting too large
This caps it at 1<<28 buckets, eg, ~268M. In theory without a guard clause like
this we could grow to the point of possibly wrapping around in terms of size,
not to mention being ridiculously wasteful of memory at larger sizes.
Even this cap is probably too high. It should probably be something like 1<<24.
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 10 |
1 files changed, 9 insertions, 1 deletions
@@ -38,7 +38,13 @@ holds the key and hash value. * NOTE if you change this formula so we split earlier than previously * you MUST change the logic in hv_ksplit() */ -#define DO_HSPLIT(xhv) ( ((xhv)->xhv_keys + ((xhv)->xhv_keys >> 1)) > (xhv)->xhv_max ) + +/* MAX_BUCKET_MAX is the maximum max bucket index, at which point we stop growing the + * number of buckets, + */ +#define MAX_BUCKET_MAX ((1<<26)-1) +#define DO_HSPLIT(xhv) ( ( ((xhv)->xhv_keys + ((xhv)->xhv_keys >> 1)) > (xhv)->xhv_max ) && \ + ((xhv)->xhv_max < MAX_BUCKET_MAX) ) static const char S_strtab_error[] = "Cannot modify shared string table in hv_%s"; @@ -1424,6 +1430,8 @@ S_hsplit(pTHX_ HV *hv, STRLEN const oldsize, STRLEN newsize) ); PERL_ARGS_ASSERT_HSPLIT; + if (newsize > MAX_BUCKET_MAX+1) + return; PL_nomemok = TRUE; Renew(a, PERL_HV_ARRAY_ALLOC_BYTES(newsize) |