Repository: godotengine/godot (language: cpp)

Issue:
Crash after typo in text editor in 4.4 beta3
### Tested versions

Reproducible in 4.4 beta3
Not reproducible in 4.3 stable

### System information

Godot v4.4.beta3 - Windows 10 (build 19045) - Multi-window, 3 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3090 (NVIDIA; 32.0.15.7216) - AMD Ryzen 9 7950X 16-Core Processor (32 threads)

### Issue description

The editor crashes after inputting a misspelled "@export_range" directive after the '(' character is typed.

### Steps to reproduce

-Create new project
-Add Node3D
-Add script to that node 3D

In the second line under 'extends Node3D' line, type "@export_rande(". Any other typo will work.

The editor will crash a moment after the '(' is typed. The bug will not happen if @export_range is properly typed.

### Minimal reproduction project (MRP)

N/A


Discussion / hints:
Confirmed, just typing `@export_a(` triggers the crash.

```
0x0000000006bd6b5b in CowData<char32_t>::_ref (this=0x7fffffffaa28, p_from=...) at ./core/templates/cowdata.h:492
492             if (_ptr == p_from._ptr) {
(gdb) bt
#0  0x0000000006bd6b5b in CowData<char32_t>::_ref (this=0x7fffffffaa28, p_from=...) at ./core/templates/cowdata.h:492
#1  0x0000000006bd68dd in String::String (this=0x7fffffffaa28, p_str=...) at ./core/string/ustring.h:602
#2  0x000000000c51334f in String::operator+ (this=0x18, p_str=...) at ./core/string/ustring.cpp:381
#3  0x0000000007c10cab in _make_arguments_hint (p_info=..., p_arg_idx=0, p_is_annotation=true) at ./modules/gdscript/gdscript_editor.cpp:744
#4  0x0000000007c123a3 in _find_annotation_arguments (p_annotation=0x2e31a3b0, p_argument=0, p_quote_style=..., r_result=..., r_arghint=...) at ./modules/gdscript/gdscript_editor.cpp:892
#5  0x0000000007c21ce5 in GDScriptLanguage::complete_code (this=0xcd3c3b0, p_code=..., p_path=..., p_owner=0x0, r_options=0x7fffffffc298, r_forced=@0x7fffffffc28f: false, r_call_hint=...)
    at ./modules/gdscript/gdscript_editor.cpp:3242
#6  0x000000000989e600 in ScriptTextEditor::_code_complete_script (this=0x2dedfce0, p_code=..., r_options=0x7fffffffc298, r_force=@0x7fffffffc28f: false) at ./editor/plugins/script_text_editor.cpp:883
#7  0x000000000989e4f6 in ScriptTextEditor::_code_complete_scripts (p_ud=0x2dedfce0, p_code=..., r_options=0x7fffffffc298, r_force=@0x7fffffffc28f: false) at ./editor/plugins/script_text_editor.cpp:871
#8  0x0000000008df13e4 in CodeTextEditor::_complete_request (this=0x2dee08d0) at ./editor/code_editor.cpp:1026
#9  0x0000000009063590 in call_with_variant_args_helper<CodeTextEditor>(CodeTextEditor*, void (CodeTextEditor::*)(), Variant const**, Callable::CallError&, IndexSequence<>) (p_instance=0x2dee08d0, 
    p_method=(void (CodeTextEditor::*)(CodeTextEditor * const)) 0x8df132e <CodeTextEditor::_complete_request()>, p_args=0x0, r_error=...) at ./core/variant/binder_common.h:315
#10 0x00000000090512c6 in call_with_variant_args<CodeTextEditor> (p_instance=0x2dee08d0, p_method=(void (CodeTextEditor::*)(CodeTextEditor * const)) 0x8df132e <CodeTextEditor::_complete_request()>, p_args=0x0, 
    p_argcount=0, r_error=...) at ./core/variant/binder_common.h:429
#11 0x000000000903170a in CallableCustomMethodPointer<CodeTextEditor, void>::call (this=0x12af9340, p_arguments=0x0, p_argcount=0, r_return_value=..., r_call_error=...)
    at ./core/object/callable_method_pointer.h:105
#12 0x000000000c151301 in Callable::callp (this=0x7fffffffc560, p_arguments=0x0, p_argcount=0, r_return_value=..., r_call_error=...) at ./core/variant/callable.cpp:57
#13 0x000000000c4a3463 in Object::emit_signalp (this=0x2dee1410, p_name=..., p_args=0x0, p_argcount=0) at ./core/object/object.cpp:1236
#14 0x0000000009ebb946 in Node::emit_signalp (this=0x2dee1410, p_name=..., p_args=0x0, p_argcount=0) at ./scene/main/node.cpp:4021
#15 0x0000000007451759 in Object::emit_signal<>(StringName const&) (this=0x2dee1410, p_name=...) at ./core/object/object.h:933
#16 0x000000000a03c62f in CodeEdit::request_code_completion (this=0x2dee1410, p_force=false) at ./scene/gui/code_edit.cpp:2160
#17 0x0000000008df12bd in CodeTextEditor::_code_complete_timer_timeout (this=0x2dee08d0) at ./editor/code_editor.cpp:1017
#18 0x0000000009063590 in call_with_variant_args_helper<CodeTextEditor>(CodeTextEditor*, void (CodeTextEditor::*)(), Variant const**, Callable::CallError&, IndexSequence<>) (p_instance=0x2dee08d0, 
    p_method=(void (CodeTextEditor::*)(CodeTextEditor * const)) 0x8df1286 <CodeTextEditor::_code_complete_timer_timeout()>, p_args=0x0, r_error=...) at ./core/variant/binder_common.h:315
#19 0x00000000090512c6 in call_with_variant_args<CodeTextEditor> (p_instance=0x2dee08d0, p_method=(void (CodeTextEditor::*)(CodeTextEditor * const)) 0x8df1286 <CodeTextEditor::_code_complete_timer_timeout()>, 
    p_args=0x0, p_argcount=0, r_error=...) at ./core/variant/binder_common.h:429
#20 0x000000000903170a in CallableCustomMethodPointer<CodeTextEditor, void>::call (this=0x2725bbd0, p_arguments=0x0, p_argcount=0, r_return_value=..., r_call_error=...)
    at ./core/object/callable_method_pointer.h:105
#21 0x000000000c151301 in Callable::callp (this=0x7fffffffcac0, p_arguments=0x0, p_argcount=0, r_return_value=..., r_call_error=...) at ./core/variant/callable.cpp:57
#22 0x000000000c4a3463 in Object::emit_signalp (this=0x2c708210, p_name=..., p_args=0x0, p_argcount=0) at ./core/object/object.cpp:1236
#23 0x0000000009ebb946 in Node::emit_signalp (this=0x2c708210, p_name=..., p_args=0x0, p_argcount=0) at ./scene/main/node.cpp:4021
#24 0x0000000007451759 in Object::emit_signal<>(StringName const&) (this=0x2c708210, p_name=...) at ./core/object/object.h:933
#25 0x0000000009ecd4a5 in Timer::_notification (this=0x2c708210, p_what=25) at ./scene/main/timer.cpp:64
#26 0x0000000009f31ca4 in Timer::_notificationv (this=0x2c708210, p_notification=25, p_reversed=false) at ./scene/main/timer.h:37
#27 0x000000000c4a16d4 in Object::notification (this=0x2c708210, p_notification=25, p_reversed=false) at ./core/object/object.cpp:911
#28 0x0000000009ec12d8 in SceneTree::_process_group (this=0xf049770, p_group=0xf049a10, p_physics=false) at ./scene/main/scene_tree.cpp:1057
#29 0x0000000009ec1877 in SceneTree::_process (this=0xf049770, p_physics=false) at ./scene/main/scene_tree.cpp:1137
#30 0x0000000009ebf619 in SceneTree::process (this=0xf049770, p_time=0.0068979999999999996) at ./scene/main/scene_tree.cpp:578
#31 0x0000000006ca5b84 in Main::iteration () at main/main.cpp:4496
#32 0x0000000006bdd5ea in OS_LinuxBSD::run (this=0x7fffffffd160) at platform/linuxbsd/os_linuxbsd.cpp:962
#33 0x0000000006bd5d31 in main (argc=4, argv=0x7fffffffd7c8) at platform/linuxbsd/godot_linuxbsd.cpp:85
```

Regression introduced in 4.4.dev4 by #96693, CC @HolonProduction.
(Didn't do a full bisect, I just made an educated guess from the 4.4.dev4 changelog, and confirmed that a local revert of that PR solves the bug.)

Fix patch:
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 062d522b6818..567c748cd3d5 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -889,7 +889,11 @@ static void _get_directory_contents(EditorFileSystemDirectory *p_dir, HashMap<St
 }
 
 static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_annotation, int p_argument, const String p_quote_style, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, String &r_arghint) {
-	r_arghint = _make_arguments_hint(p_annotation->info->info, p_argument, true);
+	ERR_FAIL_NULL(p_annotation);
+
+	if (p_annotation->info != nullptr) {
+		r_arghint = _make_arguments_hint(p_annotation->info->info, p_argument, true);
+	}
 	if (p_annotation->name == SNAME("@export_range")) {
 		if (p_argument == 3 || p_argument == 4 || p_argument == 5) {
 			// Slider hint.
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 22b14e8bb5c1..5da2bc80207f 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -372,6 +372,7 @@ class GDScriptParser {
 		Vector<ExpressionNode *> arguments;
 		Vector<Variant> resolved_arguments;
 
+		/** Information of the annotation. Might be null for unknown annotations. */
 		AnnotationInfo *info = nullptr;
 		PropertyInfo export_info;
 		bool is_resolved = false;


Test patch: