|
|
3f1b01 |
From c5eed6e541fe27d9e9dfd31f42c43f4dfa1f486b Mon Sep 17 00:00:00 2001
|
|
|
3f1b01 |
From: Yves Orton <demerphq@gmail.com>
|
|
|
3f1b01 |
Date: Sat, 11 Jul 2020 09:26:21 +0200
|
|
|
3f1b01 |
Subject: [PATCH] hv.c: add a guard clause to prevent the number of buckets in
|
|
|
3f1b01 |
a hash from getting too large
|
|
|
3f1b01 |
MIME-Version: 1.0
|
|
|
3f1b01 |
Content-Type: text/plain; charset=UTF-8
|
|
|
3f1b01 |
Content-Transfer-Encoding: 8bit
|
|
|
3f1b01 |
|
|
|
3f1b01 |
This caps it at 1<<28 buckets, eg, ~268M. In theory without a guard clause like
|
|
|
3f1b01 |
this we could grow to the point of possibly wrapping around in terms of size,
|
|
|
3f1b01 |
not to mention being ridiculously wasteful of memory at larger sizes.
|
|
|
3f1b01 |
Even this cap is probably too high. It should probably be something like 1<<24.
|
|
|
3f1b01 |
|
|
|
3f1b01 |
Petr Písař: Ported to 5.32.1 from
|
|
|
3f1b01 |
aae087f7cec022be14a17deb95cb2208e16b7891.
|
|
|
3f1b01 |
|
|
|
3f1b01 |
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
|
|
3f1b01 |
---
|
|
|
3f1b01 |
hv.c | 10 +++++++++-
|
|
|
3f1b01 |
1 file changed, 9 insertions(+), 1 deletion(-)
|
|
|
3f1b01 |
|
|
|
3f1b01 |
diff --git a/hv.c b/hv.c
|
|
|
3f1b01 |
index eccae62..32dbd19 100644
|
|
|
3f1b01 |
--- a/hv.c
|
|
|
3f1b01 |
+++ b/hv.c
|
|
|
3f1b01 |
@@ -38,7 +38,13 @@ holds the key and hash value.
|
|
|
3f1b01 |
* NOTE if you change this formula so we split earlier than previously
|
|
|
3f1b01 |
* you MUST change the logic in hv_ksplit()
|
|
|
3f1b01 |
*/
|
|
|
3f1b01 |
-#define DO_HSPLIT(xhv) ( ((xhv)->xhv_keys + ((xhv)->xhv_keys >> 1)) > (xhv)->xhv_max )
|
|
|
3f1b01 |
+
|
|
|
3f1b01 |
+/* MAX_BUCKET_MAX is the maximum max bucket index, at which point we stop growing the
|
|
|
3f1b01 |
+ * number of buckets,
|
|
|
3f1b01 |
+ */
|
|
|
3f1b01 |
+#define MAX_BUCKET_MAX ((1<<26)-1)
|
|
|
3f1b01 |
+#define DO_HSPLIT(xhv) ( ( ((xhv)->xhv_keys + ((xhv)->xhv_keys >> 1)) > (xhv)->xhv_max ) && \
|
|
|
3f1b01 |
+ ((xhv)->xhv_max < MAX_BUCKET_MAX) )
|
|
|
3f1b01 |
#define HV_FILL_THRESHOLD 31
|
|
|
3f1b01 |
|
|
|
3f1b01 |
static const char S_strtab_error[]
|
|
|
3f1b01 |
@@ -1426,6 +1432,8 @@ S_hsplit(pTHX_ HV *hv, STRLEN const oldsize, STRLEN newsize)
|
|
|
3f1b01 |
);
|
|
|
3f1b01 |
|
|
|
3f1b01 |
PERL_ARGS_ASSERT_HSPLIT;
|
|
|
3f1b01 |
+ if (newsize > MAX_BUCKET_MAX+1)
|
|
|
3f1b01 |
+ return;
|
|
|
3f1b01 |
|
|
|
3f1b01 |
PL_nomemok = TRUE;
|
|
|
3f1b01 |
Renew(a, PERL_HV_ARRAY_ALLOC_BYTES(newsize)
|
|
|
3f1b01 |
--
|
|
|
3f1b01 |
2.26.2
|
|
|
3f1b01 |
|