Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GDScript: Fix segfault on invalid script #92035

Merged
merged 1 commit into from
May 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions modules/gdscript/gdscript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ bool GDScript::get_property_default_value(const StringName &p_property, Variant
}

ScriptInstance *GDScript::instance_create(Object *p_this) {
ERR_FAIL_COND_V_MSG(!valid, nullptr, "Script is invalid!");

GDScript *top = this;
while (top->_base) {
top = top->_base;
Expand Down Expand Up @@ -902,6 +904,11 @@ void GDScript::unload_static() const {
}

Variant GDScript::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (unlikely(!valid)) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}

GDScript *top = this;
while (top) {
HashMap<StringName, GDScriptFunction *>::Iterator E = top->member_functions.find(p_method);
Expand All @@ -924,6 +931,10 @@ bool GDScript::_get(const StringName &p_name, Variant &r_ret) const {
return true;
}

if (unlikely(!valid)) {
return false;
}

const GDScript *top = this;
while (top) {
{
Expand Down Expand Up @@ -980,6 +991,10 @@ bool GDScript::_set(const StringName &p_name, const Variant &p_value) {
return true;
}

if (unlikely(!valid)) {
return false;
}

GDScript *top = this;
while (top) {
HashMap<StringName, MemberInfo>::ConstIterator E = top->static_variables_indices.find(p_name);
Expand Down Expand Up @@ -1014,6 +1029,10 @@ bool GDScript::_set(const StringName &p_name, const Variant &p_value) {
void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const {
p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));

if (unlikely(!valid)) {
return;
}

List<const GDScript *> classes;
const GDScript *top = this;
while (top) {
Expand Down Expand Up @@ -1630,6 +1649,10 @@ GDScript::~GDScript() {
//////////////////////////////

bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
if (unlikely(!script->valid)) {
return false;
}

{
HashMap<StringName, GDScript::MemberInfo>::Iterator E = script->member_indices.find(p_name);
if (E) {
Expand Down Expand Up @@ -1703,6 +1726,10 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
}

bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
if (unlikely(!script->valid)) {
return false;
}

{
HashMap<StringName, GDScript::MemberInfo>::ConstIterator E = script->member_indices.find(p_name);
if (E) {
Expand Down Expand Up @@ -1823,6 +1850,10 @@ void GDScriptInstance::validate_property(PropertyInfo &p_property) const {
}

void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
if (unlikely(!script->valid)) {
return;
}

// exported members, not done yet!

const GDScript *sptr = script.ptr();
Expand Down Expand Up @@ -1901,6 +1932,10 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
}

bool GDScriptInstance::property_can_revert(const StringName &p_name) const {
if (unlikely(!script->valid)) {
return false;
}

Variant name = p_name;
const Variant *args[1] = { &name };

Expand All @@ -1921,6 +1956,10 @@ bool GDScriptInstance::property_can_revert(const StringName &p_name) const {
}

bool GDScriptInstance::property_get_revert(const StringName &p_name, Variant &r_ret) const {
if (unlikely(!script->valid)) {
return false;
}

Variant name = p_name;
const Variant *args[1] = { &name };

Expand Down Expand Up @@ -1995,6 +2034,11 @@ void GDScriptInstance::_call_implicit_ready_recursively(GDScript *p_script) {
}

Variant GDScriptInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (unlikely(!script->valid)) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}

GDScript *sptr = script.ptr();
if (unlikely(p_method == SceneStringName(_ready))) {
// Call implicit ready first, including for the super classes recursively.
Expand All @@ -2012,6 +2056,10 @@ Variant GDScriptInstance::callp(const StringName &p_method, const Variant **p_ar
}

void GDScriptInstance::notification(int p_notification, bool p_reversed) {
if (unlikely(!script->valid)) {
return;
}

//notification is not virtual, it gets called at ALL levels just like in C.
Variant value = p_notification;
const Variant *args[1] = { &value };
Expand Down
6 changes: 5 additions & 1 deletion modules/gdscript/gdscript_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3228,7 +3228,11 @@ Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_scri
GDScriptCache::add_static_script(p_script);
}

return GDScriptCache::finish_compiling(main_script->path);
err = GDScriptCache::finish_compiling(main_script->path);
if (err) {
main_script->valid = false;
}
return err;
}

String GDScriptCompiler::get_error() const {
Expand Down
Loading