From 8dded3ab60267161cfaa1c2147e3f402f7e8138a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 23 Feb 2024 11:48:14 -0800 Subject: [PATCH] Fix crash when attempting to load ancient languages via wasm --- lib/binding_rust/wasm_language.rs | 2 +- lib/src/language.h | 5 ++++- lib/src/wasm.c | 9 ++++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/binding_rust/wasm_language.rs b/lib/binding_rust/wasm_language.rs index a67cb58f..2d8a32d2 100644 --- a/lib/binding_rust/wasm_language.rs +++ b/lib/binding_rust/wasm_language.rs @@ -134,7 +134,7 @@ impl fmt::Display for WasmError { WasmErrorKind::Instantiate => "Failed to instantiate wasm module", WasmErrorKind::Other => "Unknown error", }; - write!(f, "{kind} {}", self.message) + write!(f, "{kind}: {}", self.message) } } diff --git a/lib/src/language.h b/lib/src/language.h index c89dc739..4e2769b4 100644 --- a/lib/src/language.h +++ b/lib/src/language.h @@ -10,6 +10,9 @@ extern "C" { #define ts_builtin_sym_error_repeat (ts_builtin_sym_error - 1) +#define LANGUAGE_VERSION_WITH_PRIMARY_STATES 14 +#define LANGUAGE_VERSION_USABLE_VIA_WASM 13 + typedef struct { const TSParseAction *actions; uint32_t action_count; @@ -186,7 +189,7 @@ static inline bool ts_language_state_is_primary( const TSLanguage *self, TSStateId state ) { - if (self->version >= 14) { + if (self->version >= LANGUAGE_VERSION_WITH_PRIMARY_STATES) { return state == self->primary_state_ids[state]; } else { return true; diff --git a/lib/src/wasm.c b/lib/src/wasm.c index 23d24eb2..3ebbcf22 100644 --- a/lib/src/wasm.c +++ b/lib/src/wasm.c @@ -10,6 +10,7 @@ #include "./alloc.h" #include "./array.h" #include "./atomic.h" +#include "./language.h" #include "./lexer.h" #include "./wasm.h" #include "./wasm/wasm-stdlib.h" @@ -1057,6 +1058,12 @@ const TSLanguage *ts_wasm_store_load_language( const uint8_t *memory = wasmtime_memory_data(context, &self->memory); memcpy(&wasm_language, &memory[language_address], sizeof(LanguageInWasmMemory)); + if (wasm_language.version < LANGUAGE_VERSION_USABLE_VIA_WASM) { + wasm_error->kind = TSWasmErrorKindInstantiate; + format(&wasm_error->message, "language version %u is too old for wasm", wasm_language.version); + goto error; + } + int32_t addresses[] = { wasm_language.alias_map, wasm_language.alias_sequences, @@ -1188,7 +1195,7 @@ const TSLanguage *ts_wasm_store_load_language( ); } - if (language->version >= 14) { + if (language->version >= LANGUAGE_VERSION_WITH_PRIMARY_STATES) { language->primary_state_ids = copy( &memory[wasm_language.primary_state_ids], wasm_language.state_count * sizeof(TSStateId)