Skip to content

Commit ead1b88

Browse files
authored
Fixed segfault when component creation(mount) throws an error (#13)
1 parent 8f8c940 commit ead1b88

File tree

5 files changed

+57
-8
lines changed

5 files changed

+57
-8
lines changed

src/imvue.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,13 +371,18 @@ namespace ImVue {
371371
void Component::configure(rapidxml::xml_node<>* node, Context* ctx, ScriptState::Context* sctx, Element* parent)
372372
{
373373
Context* child = newChildContext(ctx);
374-
child->root = this;
375-
if(child->script) {
376-
child->script->initialize(mData);
377-
child->script->lifecycleCallback(ScriptState::BEFORE_CREATE);
378-
}
374+
try {
375+
child->root = this;
376+
if(child->script) {
377+
child->script->initialize(mData);
378+
child->script->lifecycleCallback(ScriptState::BEFORE_CREATE);
379+
}
379380

380-
mScriptState = ctx->script;
381+
mScriptState = ctx->script;
382+
} catch(...) {
383+
delete child;
384+
throw;
385+
}
381386
Element::configure(node, child, sctx, parent);
382387
if(mConfigured) {
383388
fireCallback(ScriptState::CREATED);

src/imvue_element.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ namespace ImVue {
516516

517517
void Element::fireCallback(ScriptState::LifecycleCallbackType cb, bool schedule)
518518
{
519-
if(!mCtx->script) {
519+
if(!mCtx || !mCtx->script) {
520520
return;
521521
}
522522

tests/resources/bad.imv

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<template>
2+
</template>
3+
4+
<script>
5+
return {
6+
props = {
7+
['value-test'] = {
8+
type = ImVue_String,
9+
default = 'kek'
10+
}
11+
},
12+
mounted = function()
13+
self.crash()
14+
end,
15+
data = function()
16+
end
17+
}
18+
</script>

tests/resources/components.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
<button v-on:click="self.count = self.count + 1">increase counter</button>
44
<text-unformatted>current count {{ self.count }}</text-unformatted>
55
</window>
6-
<template v-if="widget == 'basic'">
6+
<template v-if="widget == 'bad'">
7+
<bad/>
8+
</template>
9+
<template v-else-if="widget == 'basic'">
710
<widget :count="self.count"/>
811
</template>
912
<template v-else-if="widget == 'lifecycle'">

tests/unit/state.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,29 @@ TEST_F(LuaScriptStateTest, TestComponentReactivity)
679679
EXPECT_STREQ(local[0]->text, "updated");
680680
}
681681

682+
TEST_F(LuaScriptStateTest, TestComponentCreationError)
683+
{
684+
ImVue::LuaScriptState* state = new ImVue::LuaScriptState(L);
685+
ImVue::Context* ctx = ImVue::createContext(
686+
ImVue::createElementFactory(),
687+
state
688+
);
689+
luaL_dostring(L, "widget = 'bad'");
690+
ImVue::Document document(ctx);
691+
char* data = ctx->fs->load("components.xml");
692+
ASSERT_NE((size_t)data, 0);
693+
EXPECT_THROW({
694+
try{
695+
document.parse(data);
696+
renderDocument(document);
697+
} catch(ImVue::ElementError e) {
698+
std::cout << e.what() << "\n";
699+
throw;
700+
}
701+
}, ImVue::ScriptError);
702+
ImGui::MemFree(data);
703+
}
704+
682705
TEST_F(LuaScriptStateTest, TestComponentLifecycle)
683706
{
684707
ImVue::LuaScriptState* state = new ImVue::LuaScriptState(L);

0 commit comments

Comments
 (0)