From 0461c897fe42be5069d540007ca63499451452ca Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 30 Sep 2025 13:19:23 +0200 Subject: [PATCH 1/9] Sanitize Variant values on Android --- src/sentry/android/android_event.cpp | 6 +- src/sentry/android/android_sdk.cpp | 3 +- src/sentry/android/android_util.cpp | 89 ++++++++++++++++++++++++++++ src/sentry/android/android_util.h | 9 +++ 4 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 src/sentry/android/android_util.cpp create mode 100644 src/sentry/android/android_util.h diff --git a/src/sentry/android/android_event.cpp b/src/sentry/android/android_event.cpp index 730e3950..2a012fd1 100644 --- a/src/sentry/android/android_event.cpp +++ b/src/sentry/android/android_event.cpp @@ -1,6 +1,7 @@ #include "android_event.h" #include "android_string_names.h" +#include "android_util.h" namespace sentry::android { @@ -104,7 +105,8 @@ String AndroidEvent::get_tag(const String &p_key) { void AndroidEvent::merge_context(const String &p_key, const Dictionary &p_value) { ERR_FAIL_COND_MSG(p_key.is_empty(), "Sentry: Can't merge context with an empty key."); - android_plugin->call(ANDROID_SN(eventMergeContext), event_handle, p_key, p_value); + android_plugin->call(ANDROID_SN(eventMergeContext), + event_handle, p_key, sanitize_variant(p_value)); } void AndroidEvent::add_exception(const Exception &p_exception) { @@ -128,7 +130,7 @@ void AndroidEvent::add_exception(const Exception &p_exception) { if (!frame.vars.is_empty()) { Dictionary variables; for (auto var : frame.vars) { - variables[var.first] = var.second; + variables[var.first] = sanitize_variant(var.second); } data["vars"] = variables; } diff --git a/src/sentry/android/android_sdk.cpp b/src/sentry/android/android_sdk.cpp index 2ce805d7..29897fb4 100644 --- a/src/sentry/android/android_sdk.cpp +++ b/src/sentry/android/android_sdk.cpp @@ -3,6 +3,7 @@ #include "android_breadcrumb.h" #include "android_event.h" #include "android_string_names.h" +#include "android_util.h" #include "sentry/common_defs.h" #include "sentry/processing/process_event.h" #include "sentry/sentry_attachment.h" @@ -40,7 +41,7 @@ void SentryAndroidBeforeSendHandler::_bind_methods() { void AndroidSDK::set_context(const String &p_key, const Dictionary &p_value) { ERR_FAIL_NULL(android_plugin); - android_plugin->call(ANDROID_SN(setContext), p_key, p_value); + android_plugin->call(ANDROID_SN(setContext), p_key, sanitize_variant(p_value)); } void AndroidSDK::remove_context(const String &p_key) { diff --git a/src/sentry/android/android_util.cpp b/src/sentry/android/android_util.cpp new file mode 100644 index 00000000..50b3b7e6 --- /dev/null +++ b/src/sentry/android/android_util.cpp @@ -0,0 +1,89 @@ +#include "android_util.h" + +#include "sentry/common_defs.h" + +using namespace godot; + +namespace sentry::android { + +Variant sanitize_variant(const Variant &p_value, int p_depth) { + switch (p_value.get_type()) { + case Variant::DICTIONARY: { + if (p_depth > VARIANT_CONVERSION_MAX_DEPTH) { + ERR_PRINT_ONCE("Sentry: Maximum Variant depth reached!"); + return Variant(); + } + + Dictionary old_dict = p_value; + Dictionary new_dict; + + const Array &keys = old_dict.keys(); + for (int i = 0; i < keys.size(); i++) { + const String &key = keys[i]; + new_dict[key] = sanitize_variant(old_dict[key]); + } + + return new_dict; + } break; + case Variant::ARRAY: + case Variant::PACKED_BYTE_ARRAY: + case Variant::PACKED_INT32_ARRAY: + case Variant::PACKED_INT64_ARRAY: + case Variant::PACKED_FLOAT32_ARRAY: + case Variant::PACKED_FLOAT64_ARRAY: + case Variant::PACKED_STRING_ARRAY: + case Variant::PACKED_VECTOR2_ARRAY: + case Variant::PACKED_VECTOR3_ARRAY: + case Variant::PACKED_COLOR_ARRAY: + case Variant::PACKED_VECTOR4_ARRAY: { + if (p_depth > VARIANT_CONVERSION_MAX_DEPTH) { + ERR_PRINT_ONCE("Sentry: Maximum Variant depth reached!"); + return Variant(); + } + + Array arr; + bool oob = false; + bool valid = true; + int i = 0; + + do { + Variant item = p_value.get_indexed(i++, valid, oob); + if (valid) { + arr.append(sanitize_variant(item, p_depth + 1)); + } + } while (!oob); + + return arr; + } break; + case Variant::NIL: + case Variant::VECTOR2: + case Variant::VECTOR2I: + case Variant::RECT2: + case Variant::RECT2I: + case Variant::VECTOR3: + case Variant::VECTOR3I: + case Variant::TRANSFORM2D: + case Variant::VECTOR4: + case Variant::VECTOR4I: + case Variant::PLANE: + case Variant::QUATERNION: + case Variant::AABB: + case Variant::BASIS: + case Variant::TRANSFORM3D: + case Variant::PROJECTION: + case Variant::COLOR: + case Variant::STRING_NAME: + case Variant::NODE_PATH: + case Variant::RID: + case Variant::OBJECT: + case Variant::CALLABLE: + case Variant::SIGNAL: { + return p_value.stringify(); + } break; + default: { + return p_value; + } break; + } +} + +} //namespace sentry::android diff --git a/src/sentry/android/android_util.h b/src/sentry/android/android_util.h new file mode 100644 index 00000000..e426090c --- /dev/null +++ b/src/sentry/android/android_util.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace sentry::android { + +godot::Variant sanitize_variant(const godot::Variant &p_value, int p_depth = 0); + +} From 650f87688cfb78a6e45b683007440e28eb50e08a Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 30 Sep 2025 13:20:19 +0200 Subject: [PATCH 2/9] Add "Test diverse context" tool in project --- project/mobile.gd | 50 +++++++++++++++++++++++++++++++++++++++++++-- project/mobile.tscn | 16 ++++++++++----- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/project/mobile.gd b/project/mobile.gd index ef29efc2..610ea373 100644 --- a/project/mobile.gd +++ b/project/mobile.gd @@ -9,10 +9,56 @@ func _ready() -> void: get_viewport().get_window().content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS get_viewport().get_window().content_scale_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND - # Show tests only if the test file is available - %Tests.visible = FileAccess.file_exists(MOBILE_TESTS_FILE) + %RunTestsButton.visible = FileAccess.file_exists(MOBILE_TESTS_FILE) func _on_run_tests_button_pressed() -> void: var tests = load(MOBILE_TESTS_FILE).new() tests.run_tests() + + +func _on_test_diverse_context_button_pressed() -> void: + var context := { + "null": null, + "bool": true, + "int": 42, + "float": 42.42, + "string": "hello, world!", + "Vector2": Vector2(123.45, 67.89), + "Vector2i": Vector2i(123, 45), + "Rect2": Rect2(123.45, 67.89, 98.76, 54.32), + "Rect2i": Rect2i(12, 34, 56, 78), + "Vector3": Vector3(12.34, 56.78, 90.12), + "Vector3i": Vector3i(12, 34, 56), + "Transform2D": Transform2D().translated(Vector2(12.34, 56.78)), + "Vector4": Vector4(12.34, 56.78, 90.12, 34.56), + "Vector4i": Vector4i(12, 34, 56, 78), + "Plane": Plane(Vector3(1, 2, 3), 4), + "Quaternion": Quaternion(Vector3(0, 1, 0), 4), + "AABB": AABB(Vector3(1, 2, 3), Vector3(4, 5, 6)), + "Basis": Basis(Vector3(1, 2, 3), Vector3(4, 5, 6), Vector3(7, 8, 9)), + "Transform3D": Transform3D().translated(Vector3(12.34, 56.78, 90.12)), + "Projection": Projection(Vector4(73.21, 19.47, 85.63, 73.02), Vector4(41.92, 67.38, 22.14, 59.81), Vector4(93.76, 15.49, 38.72, 84.25), Vector4(26.58, 71.93, 47.16, 62.84)), + "Color": Color(12.34, 56.78, 90.12, 34.56), + "StringName": StringName("hello, world!"), + "NodePath": NodePath("/root"), + "RID": RID(), + "Object": self, + "Callable": _on_test_diverse_context_button_pressed, + "Signal": get_tree().process_frame, + "Dictionary": {"key1": "value1", "key2": 42, "key3": self}, + "Array": [1, self, {"hello": "world"}], + "PackedByteArray": PackedByteArray([1, 2, 3, 4, 5]), + "PackedInt32Array": PackedInt32Array([1, 2, 3, 4, 5]), + "PackedInt64Array": PackedInt64Array([1, 2, 3, 4, 5]), + "PackedFloat32Array": PackedFloat32Array([1.23, 4.56, 7.89]), + "PackedFloat64Array": PackedFloat64Array([1.23, 4.56, 7.89]), + "PackedStringArray": PackedStringArray(["hello", "world"]), + "PackedVector2Array": PackedVector2Array([Vector2(1, 2), Vector2(3, 4)]), + "PackedVector3Array": PackedVector3Array([Vector3(1, 2, 3), Vector3(4, 5, 6)]), + "PackedColorArray": PackedColorArray([Color(1, 2, 3, 4), Color(5, 6, 7, 8)]), + "PackedVector4Array": PackedVector4Array([Vector4(1, 2, 3, 4), Vector4(5, 6, 7, 8)]), + } + SentrySDK.set_context("diverse_context", context) + DemoOutput.print_info("Added context with diverse values.") + SentrySDK.capture_message("Test diverse context") diff --git a/project/mobile.tscn b/project/mobile.tscn index 39c4332b..012dd888 100644 --- a/project/mobile.tscn +++ b/project/mobile.tscn @@ -49,24 +49,29 @@ metadata/_tab_index = 0 layout_mode = 2 metadata/_tab_index = 1 -[node name="Tests" type="VBoxContainer" parent="VBoxContainer/VBoxContainer/TabContainer"] +[node name="Tools" type="VBoxContainer" parent="VBoxContainer/VBoxContainer/TabContainer"] unique_name_in_owner = true visible = false layout_mode = 2 metadata/_tab_index = 2 -[node name="Header - Mobile Tests" type="Label" parent="VBoxContainer/VBoxContainer/TabContainer/Tests"] +[node name="Header - Actions" type="Label" parent="VBoxContainer/VBoxContainer/TabContainer/Tools"] custom_minimum_size = Vector2(0, 40.505) layout_mode = 2 -text = "MOBILE TESTS" +text = "Actions" horizontal_alignment = 1 vertical_alignment = 2 -[node name="RunTestsButton" type="Button" parent="VBoxContainer/VBoxContainer/TabContainer/Tests"] +[node name="RunTestsButton" type="Button" parent="VBoxContainer/VBoxContainer/TabContainer/Tools"] unique_name_in_owner = true layout_mode = 2 text = "Run mobile tests" +[node name="TestDiverseContextButton" type="Button" parent="VBoxContainer/VBoxContainer/TabContainer/Tools"] +unique_name_in_owner = true +layout_mode = 2 +text = "Test diverse context" + [node name="OutputPane" parent="VBoxContainer/VBoxContainer" instance=ExtResource("4_xux57")] layout_mode = 2 @@ -74,4 +79,5 @@ layout_mode = 2 custom_minimum_size = Vector2(0, 20) layout_mode = 2 -[connection signal="pressed" from="VBoxContainer/VBoxContainer/TabContainer/Tests/RunTestsButton" to="." method="_on_run_tests_button_pressed"] +[connection signal="pressed" from="VBoxContainer/VBoxContainer/TabContainer/Tools/RunTestsButton" to="." method="_on_run_tests_button_pressed"] +[connection signal="pressed" from="VBoxContainer/VBoxContainer/TabContainer/Tools/TestDiverseContextButton" to="." method="_on_test_diverse_context_button_pressed"] From 7738eb6a35d567b83e95f792cbb60ec23517f75d Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 30 Sep 2025 13:30:53 +0200 Subject: [PATCH 3/9] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 370b9193..31b19c6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Fixed setting `throttle_window_ms` to 0 should disable it ([#382](https://github.com/getsentry/sentry-godot/pull/382)) - Fixed failing to set initial user on Apple platforms ([#390](https://github.com/getsentry/sentry-godot/pull/390)) - Added missing `crashpad_wer.dll` to Windows builds and export dependencies ([#396](https://github.com/getsentry/sentry-godot/pull/396)) +- Sanitize Variant values on Android ([#397](https://github.com/getsentry/sentry-godot/pull/397)) ### Other changes From d9dfdcb58df9cef1c6f2a4504ba3fd11950c6fe9 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 30 Sep 2025 13:33:00 +0200 Subject: [PATCH 4/9] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31b19c6e..ee415762 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ - Fixed setting `throttle_window_ms` to 0 should disable it ([#382](https://github.com/getsentry/sentry-godot/pull/382)) - Fixed failing to set initial user on Apple platforms ([#390](https://github.com/getsentry/sentry-godot/pull/390)) - Added missing `crashpad_wer.dll` to Windows builds and export dependencies ([#396](https://github.com/getsentry/sentry-godot/pull/396)) -- Sanitize Variant values on Android ([#397](https://github.com/getsentry/sentry-godot/pull/397)) +- Sanitize Variant values on Android, and fix custom context and local variables missing or null on Android ([#397](https://github.com/getsentry/sentry-godot/pull/397)) ### Other changes From 7959ccb7238a2bbcffc05c01b5d8d0c33bd2bc67 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 30 Sep 2025 13:38:15 +0200 Subject: [PATCH 5/9] Fix depth bump --- src/sentry/android/android_util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/android/android_util.cpp b/src/sentry/android/android_util.cpp index 50b3b7e6..d73ef577 100644 --- a/src/sentry/android/android_util.cpp +++ b/src/sentry/android/android_util.cpp @@ -20,7 +20,7 @@ Variant sanitize_variant(const Variant &p_value, int p_depth) { const Array &keys = old_dict.keys(); for (int i = 0; i < keys.size(); i++) { const String &key = keys[i]; - new_dict[key] = sanitize_variant(old_dict[key]); + new_dict[key] = sanitize_variant(old_dict[key], p_depth + 1); } return new_dict; From 421b73f2db63b97abcf3a1e4f60443306c4f0d40 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 30 Sep 2025 13:53:48 +0200 Subject: [PATCH 6/9] Handle non-string keys --- src/sentry/android/android_util.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sentry/android/android_util.cpp b/src/sentry/android/android_util.cpp index d73ef577..6a6b61a7 100644 --- a/src/sentry/android/android_util.cpp +++ b/src/sentry/android/android_util.cpp @@ -19,8 +19,8 @@ Variant sanitize_variant(const Variant &p_value, int p_depth) { const Array &keys = old_dict.keys(); for (int i = 0; i < keys.size(); i++) { - const String &key = keys[i]; - new_dict[key] = sanitize_variant(old_dict[key], p_depth + 1); + const Variant &key = keys[i]; + new_dict[key.stringify()] = sanitize_variant(old_dict[key], p_depth + 1); } return new_dict; From 09e57d39a01410daa33c4e8421251492ce778e4b Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 30 Sep 2025 14:15:57 +0200 Subject: [PATCH 7/9] Capitalize and whitespace --- project/mobile.tscn | 2 +- project/views/capture_events.gd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/mobile.tscn b/project/mobile.tscn index 012dd888..a32316e2 100644 --- a/project/mobile.tscn +++ b/project/mobile.tscn @@ -58,7 +58,7 @@ metadata/_tab_index = 2 [node name="Header - Actions" type="Label" parent="VBoxContainer/VBoxContainer/TabContainer/Tools"] custom_minimum_size = Vector2(0, 40.505) layout_mode = 2 -text = "Actions" +text = "ACTIONS" horizontal_alignment = 1 vertical_alignment = 2 diff --git a/project/views/capture_events.gd b/project/views/capture_events.gd index 0b5184df..cc7cefef 100644 --- a/project/views/capture_events.gd +++ b/project/views/capture_events.gd @@ -30,7 +30,7 @@ func _init_level_choice_popup() -> void: func _init_user_info() -> void: var user := SentryUser.create_default() SentrySDK.set_user(user) - + username.text = user.username email.text = user.email user_id.text = user.id From 685c35ec037644f3b17c6f2bac3fc51bc117fb51 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 30 Sep 2025 14:30:31 +0200 Subject: [PATCH 8/9] Dont stringify nulls --- src/sentry/android/android_util.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sentry/android/android_util.cpp b/src/sentry/android/android_util.cpp index 6a6b61a7..79ff9b9e 100644 --- a/src/sentry/android/android_util.cpp +++ b/src/sentry/android/android_util.cpp @@ -55,7 +55,6 @@ Variant sanitize_variant(const Variant &p_value, int p_depth) { return arr; } break; - case Variant::NIL: case Variant::VECTOR2: case Variant::VECTOR2I: case Variant::RECT2: From 861e2a4bf699f6cfb9d982f5d78f0266c2fbf939 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Wed, 1 Oct 2025 10:41:10 +0200 Subject: [PATCH 9/9] Fix namespace closing comment style --- src/sentry/android/android_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/android/android_util.h b/src/sentry/android/android_util.h index e426090c..10d8ff64 100644 --- a/src/sentry/android/android_util.h +++ b/src/sentry/android/android_util.h @@ -6,4 +6,4 @@ namespace sentry::android { godot::Variant sanitize_variant(const godot::Variant &p_value, int p_depth = 0); -} +} // namespace sentry::android