summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2020-06-05 14:38:56 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2020-06-05 14:40:07 +0900
commitf1523d24042ca3416dc5b9be7b3fc220ddaed896 (patch)
treecedcb588a159379b76bd81efdbbc59ec40af3c4f /include
parent00f6271e3b0fa51daad6a3a14758a361a2ba604d (diff)
downloadmruby-f1523d24042ca3416dc5b9be7b3fc220ddaed896.tar.gz
mruby-f1523d24042ca3416dc5b9be7b3fc220ddaed896.zip
Squashed commit of the following:
commit 2d7d545c4c4bfce7fdcbcbe9baaeb437915742f0 Merge: 625a1249 b178914b Author: Yukihiro "Matz" Matsumoto <[email protected]> Date: Fri Jun 5 14:35:13 2020 +0900 Merge branch 'fix-mrb_open-with-nomem' of https://github.com/dearblue/mruby into dearblue-fix-mrb_open-with-nomem commit b178914b111dda79a8f36ec4eb3e9d37b76f982e Author: dearblue <[email protected]> Date: Sat Jan 19 22:22:44 2019 +0900 Fix invalid pointer free inside other heap's block 1. `e = mrb_obj_alloc(...)` 2. `e->stack = mrb->c->stack` (`mrb->c->stack` is anywhere in the range `stbase...stend`) 3. And raised exception by `mrb_malloc()`! 4. `mrb_free(e->stack)` by GC part (wrong free) commit 52e3d5d8585daf86af3ed12db5ab0efefbc9b956 Author: dearblue <[email protected]> Date: Sat Jan 19 21:55:36 2019 +0900 Fix memory leak for temporary symbols when out of memory commit 4c5499b88e47cc6012ad7d7379cb6bc74c6a0b60 Author: dearblue <[email protected]> Date: Sun Jan 20 11:42:07 2019 +0900 Fix uninitialized pointer dereference for debug section commit 8e993167dec62a9709d6faacd517729ddcedf4f9 Author: dearblue <[email protected]> Date: Sun Jan 20 11:41:09 2019 +0900 Fix memory leak for temporary filenames when out of memory commit 8b422577e6eae68a28121b88421d937e8707b487 Author: dearblue <[email protected]> Date: Sun Jan 20 10:57:51 2019 +0900 Fix memory leak for irep when out of memory commit 6b35ebf49a0aa3edb6bbda770ed58681e9c2e6af Author: dearblue <[email protected]> Date: Sun Jan 20 10:55:50 2019 +0900 Fix uninitialized pointer dereference when do not finished initializing irep commit 2531f2631e67e0462749618e2344c733a29238f0 Author: dearblue <[email protected]> Date: Sun Jan 20 10:48:15 2019 +0900 Fix NULL pointer dereference when do not finished initializing irep commit e2d6896ebad13694800af49c2625e106b8440ddf Author: dearblue <[email protected]> Date: Sat Jan 19 12:54:19 2019 +0900 Fix memory leak for irep when out of memory by `mrb_proc_new()` commit b6214ff8a0a1c73bc9554e39053878ac50bb683f Author: dearblue <[email protected]> Date: Sat Jan 19 12:53:07 2019 +0900 Fix memory leak for `khash_t` in `kh_init_size()` when out of memory by `kh_alloc()` commit 19162dd6c11f0093d0011e7cab83b8f9e84c2c07 Author: dearblue <[email protected]> Date: Sun Jan 20 02:15:07 2019 +0900 Fix memory leak for symbol string when out of memory in `kh_put()` commit 15e67297ff54bc14ef359d6d1e745d760a4a255a Author: dearblue <[email protected]> Date: Sun Jan 20 02:12:24 2019 +0900 Fix keep wrong symbol index when out of memory commit 3f8e2b375244f5441e8d62efa13c6e6a9afecb14 Author: dearblue <[email protected]> Date: Sun Jan 20 02:08:13 2019 +0900 Fix keep wrong symbol capacity when out of memory commit a3cfe755ab3e758046c3f4e30938ac8d567ed046 Author: dearblue <[email protected]> Date: Sat Jan 19 10:11:37 2019 +0900 Fix NULL pointer dereference `mrb->c` by `mark_context()` commit d9c7b6be6eb54630b64eea5c35be241e551676e5 Author: dearblue <[email protected]> Date: Sun Jan 20 15:25:09 2019 +0900 Fix protect exception for print error message commit 100642750e4d549f2e8050f8d6cabdf8825d4495 Author: dearblue <[email protected]> Date: Sun Jan 20 11:59:02 2019 +0900 Protect exception for mruby core initialization commit 7a0418304ec70764fa215bef3599f5f735222075 Author: dearblue <[email protected]> Date: Fri Jan 18 20:38:27 2019 +0900 Fix memory leak for string object when out of memory The `mrb_str_pool()` function has a path to call `malloc()` twice. If occurs `NoMemoryError` exception in second `malloc()`, first `malloc()` pointer is not freed. commit fef1c152ce4e52b9e4a34dc23aca5b02907ac639 Author: dearblue <[email protected]> Date: Sat Jan 19 13:05:09 2019 +0900 Fix stack overflow when out of memory As a result of this change, no backtrace information is set for NoMemoryError (`mrb->nomem_err`). Detailes: When generating a backtrace, called `mrb_intern_lit()`, `mrb_str_new_cstr()` and `mrb_obj_iv_set()` function with `exc_debug_info()` function in `src/error.c`. If a `NoMemoryError` exception occurs at this time, the `exc_debug_info()` function will be called again, and in the same way `NoMemoryError` exception raised will result in an infinite loop to occurs stack overflow (and SIGSEGV). commit da7d7f881bbbad9988a3a2b7bad8f2b72ff06bc6 Author: dearblue <[email protected]> Date: Sun Jan 20 12:00:38 2019 +0900 Fix NULL pointer dereference `mrb->nomem_err` when not initialized Add internal functions (not `static`): * `mrb_raise_nomemory()` * `mrb_core_init_abort()`
Diffstat (limited to 'include')
-rw-r--r--include/mruby/khash.h28
1 files changed, 23 insertions, 5 deletions
diff --git a/include/mruby/khash.h b/include/mruby/khash.h
index c00357061..9f3f1a2cc 100644
--- a/include/mruby/khash.h
+++ b/include/mruby/khash.h
@@ -73,6 +73,7 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h); \
khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key); \
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret); \
+ void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h); \
void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets); \
void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x); \
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h);
@@ -95,16 +96,25 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
__hash_equal: hash comparation function
*/
#define KHASH_DEFINE(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
- void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h) \
+ mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb); \
+ int kh_alloc_simple_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
khint_t sz = h->n_buckets; \
size_t len = sizeof(khkey_t) + (kh_is_map ? sizeof(khval_t) : 0); \
- uint8_t *p = (uint8_t*)mrb_malloc(mrb, sizeof(uint8_t)*sz/4+len*sz); \
+ uint8_t *p = (uint8_t*)mrb_malloc_simple(mrb, sizeof(uint8_t)*sz/4+len*sz); \
+ if (!p) { return 1; } \
h->size = h->n_occupied = 0; \
h->keys = (khkey_t *)p; \
h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL; \
h->ed_flags = p+len*sz; \
kh_fill_flags(h->ed_flags, 0xaa, sz/4); \
+ return 0; \
+ } \
+ void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h) \
+ { \
+ if (kh_alloc_simple_##name(mrb, h)) { \
+ mrb_raise_nomemory(mrb); \
+ } \
} \
kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size) { \
kh_##name##_t *h = (kh_##name##_t*)mrb_calloc(mrb, 1, sizeof(kh_##name##_t)); \
@@ -112,7 +122,10 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
size = KHASH_MIN_SIZE; \
khash_power2(size); \
h->n_buckets = size; \
- kh_alloc_##name(mrb, h); \
+ if (kh_alloc_simple_##name(mrb, h)) { \
+ mrb_free(mrb, h); \
+ mrb_raise_nomemory(mrb); \
+ } \
return h; \
} \
kh_##name##_t *kh_init_##name(mrb_state *mrb) { \
@@ -171,12 +184,16 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
mrb_free(mrb, old_keys); \
} \
} \
- khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
+ void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
- khint_t k, del_k, step = 0; \
if (h->n_occupied >= khash_upper_bound(h)) { \
kh_resize_##name(mrb, h, h->n_buckets*2); \
} \
+ } \
+ khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
+ { \
+ khint_t k, del_k, step = 0; \
+ kh_put_prepare_##name(mrb, h); \
k = __hash_func(mrb,key) & khash_mask(h); \
del_k = kh_end(h); \
while (!__ac_isempty(h->ed_flags, k)) { \
@@ -239,6 +256,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
#define kh_destroy(name, mrb, h) kh_destroy_##name(mrb, h)
#define kh_clear(name, mrb, h) kh_clear_##name(mrb, h)
#define kh_resize(name, mrb, h, s) kh_resize_##name(mrb, h, s)
+#define kh_put_prepare(name, mrb, h) kh_put_prepare_##name(mrb, h)
#define kh_put(name, mrb, h, k) kh_put_##name(mrb, h, k, NULL)
#define kh_put2(name, mrb, h, k, r) kh_put_##name(mrb, h, k, r)
#define kh_get(name, mrb, h, k) kh_get_##name(mrb, h, k)