From c9b8fb8ab30cd509f064ab9e05d03c54998b093f Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Mon, 3 Apr 2023 09:20:43 +0800 Subject: [PATCH] Fix ref.func forward-declared function check --- core/iwasm/interpreter/wasm_loader.c | 16 ++++++++++++++-- core/iwasm/interpreter/wasm_mini_loader.c | 18 +++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index d3128dbd02..a3c4f42249 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -8222,12 +8222,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, goto fail; } - if (func_idx == cur_func_idx + module->import_function_count) { + /* Refer to a forward-declared function */ + if (func_idx >= cur_func_idx + module->import_function_count) { WASMTableSeg *table_seg = module->table_segments; bool func_declared = false; uint32 j; - /* Check whether current function is declared */ + /* Check whether the function is declared in table segs */ for (i = 0; i < module->table_seg_count; i++, table_seg++) { if (table_seg->elem_type == VALUE_TYPE_FUNCREF && wasm_elem_is_declarative(table_seg->mode)) { @@ -8239,6 +8240,17 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } } } + if (!func_declared) { + /* Check whether the function is exported */ + for (i = 0; i < module->export_count; i++) { + if (module->exports[i].kind == EXPORT_KIND_FUNC + && module->exports[i].index == func_idx) { + func_declared = true; + break; + } + } + } + if (!func_declared) { set_error_buf(error_buf, error_buf_size, "undeclared function reference"); diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index 3a983b2939..aa5e18f6a8 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -6384,12 +6384,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, goto fail; } - if (func_idx == cur_func_idx + module->import_function_count) { + /* Refer to a forward-declared function */ + if (func_idx >= cur_func_idx + module->import_function_count) { WASMTableSeg *table_seg = module->table_segments; bool func_declared = false; uint32 j; - /* Check whether current function is declared */ + /* Check whether the function is declared in table segs */ for (i = 0; i < module->table_seg_count; i++, table_seg++) { if (table_seg->elem_type == VALUE_TYPE_FUNCREF && wasm_elem_is_declarative(table_seg->mode)) { @@ -6402,10 +6403,17 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } } if (!func_declared) { - set_error_buf(error_buf, error_buf_size, - "undeclared function reference"); - goto fail; + /* Check whether the function is exported */ + for (i = 0; i < module->export_count; i++) { + if (module->exports[i].kind == EXPORT_KIND_FUNC + && module->exports[i].index == func_idx) { + func_declared = true; + break; + } + } } + bh_assert(func_declared); + (void)func_declared; } #if WASM_ENABLE_FAST_INTERP != 0