From 029391b87b8ed135e826a414b01a2d73e99dea1d Mon Sep 17 00:00:00 2001 From: Jonathan <30329245+CookStar@users.noreply.github.com> Date: Sun, 21 May 2023 09:50:29 +0900 Subject: [PATCH 1/5] Fixed set_string_pointer to always create a new string object. --- .../packages/source-python/memory/manager.py | 24 ++++++++++++++++--- src/core/modules/memory/memory_pointer.cpp | 23 ++++++++++++++++++ src/core/modules/memory/memory_pointer.h | 3 +++ src/core/modules/memory/memory_wrap.cpp | 17 +++++++++++-- 4 files changed, 62 insertions(+), 5 deletions(-) mode change 100644 => 100755 src/core/modules/memory/memory_pointer.h diff --git a/addons/source-python/packages/source-python/memory/manager.py b/addons/source-python/packages/source-python/memory/manager.py index b09649420..2f65e8ac2 100755 --- a/addons/source-python/packages/source-python/memory/manager.py +++ b/addons/source-python/packages/source-python/memory/manager.py @@ -467,7 +467,16 @@ def fset(ptr, value): # Handle native type else: - getattr(ptr, 'set_' + type_name)(value, offset) + # Handle string pointer type + if type_name == Type.STRING_POINTER: + string_pointer = ptr.set_string_pointer(value, offset) + string_pointer.auto_dealloc = True + + # Make sure the value will not deallocate as long as it is + # part of this object + ptr._pointer_values[offset] = string_pointer + else: + getattr(ptr, 'set_' + type_name)(value, offset) return property(fget, fset, None, doc) @@ -521,8 +530,17 @@ def fset(ptr, value): # Set the pointer ptr.set_pointer(instance_ptr, offset) - # Set the value - getattr(instance_ptr, 'set_' + type_name)(value) + # Handle string pointer type + if type_name == Type.STRING_POINTER: + string_pointer = instance_ptr.set_string_pointer(value, offset) + string_pointer.auto_dealloc = True + + # Make sure the value will not deallocate as long as it is + # part of this object + ptr._pointer_values[offset] = string_pointer + else: + # Set the value + getattr(instance_ptr, 'set_' + type_name)(value) return property(fget, fset, None, doc) diff --git a/src/core/modules/memory/memory_pointer.cpp b/src/core/modules/memory/memory_pointer.cpp index d8ddc6a8a..d681ad453 100755 --- a/src/core/modules/memory/memory_pointer.cpp +++ b/src/core/modules/memory/memory_pointer.cpp @@ -92,6 +92,29 @@ CPointer::CPointer(unsigned long ulAddr /* = 0 */, bool bAutoDealloc /* false */ m_bAutoDealloc = bAutoDealloc; } +const char * CPointer::GetStringPointer(int iOffset /* = 0 */) +{ + Validate(); + const char * result; + TRY_SEGV() + result = *(const char **) (m_ulAddr + iOffset); + EXCEPT_SEGV() + return result; +} + +CPointer * CPointer::SetStringPointer(str oString, int iOffset /* = 0 */) +{ + Validate(); + unsigned long length = len(oString) + 1; + CPointer * pPtr = new CPointer((unsigned long) UTIL_Alloc(length), false); + char * value = (char *) pPtr->m_ulAddr; + memcpy(value, extract(oString), length); + TRY_SEGV() + *(const char **) (m_ulAddr + iOffset) = value; + EXCEPT_SEGV() + return pPtr; +} + const char * CPointer::GetStringArray(int iOffset /* = 0 */) { Validate(); diff --git a/src/core/modules/memory/memory_pointer.h b/src/core/modules/memory/memory_pointer.h old mode 100644 new mode 100755 index 99d9b26a5..854819fca --- a/src/core/modules/memory/memory_pointer.h +++ b/src/core/modules/memory/memory_pointer.h @@ -136,6 +136,9 @@ class CPointer EXCEPT_SEGV() } + const char * GetStringPointer(int iOffset = 0); + CPointer* SetStringPointer(str oString, int iOffset = 0); + const char * GetStringArray(int iOffset = 0); void SetStringArray(char* szText, int iOffset = 0); diff --git a/src/core/modules/memory/memory_wrap.cpp b/src/core/modules/memory/memory_wrap.cpp index 76d868222..28628e56d 100755 --- a/src/core/modules/memory/memory_wrap.cpp +++ b/src/core/modules/memory/memory_wrap.cpp @@ -201,7 +201,6 @@ void export_pointer(scope _memory) EXPOSE_GET_SET_TYPE(ulong_long, unsigned long long) EXPOSE_GET_SET_TYPE(float, float) EXPOSE_GET_SET_TYPE(double, double) - EXPOSE_GET_SET_TYPE(string_pointer, const char*) .def("get_pointer", &CPointer::GetPtr, @@ -210,6 +209,12 @@ void export_pointer(scope _memory) manage_new_object_policy() ) + .def("get_string_pointer", + &CPointer::GetStringPointer, + "Returns the value at the memory location.", + (arg("offset")=0) + ) + .def("get_string_array", &CPointer::GetStringArray, "Returns the value at the memory location.", @@ -222,10 +227,17 @@ void export_pointer(scope _memory) ("value", arg("offset")=0) ) + .def("set_string_pointer", + &CPointer::SetStringPointer, + "Sets the value at the given memory location. This string object must be deallocated by the user. Returns the string object.", + ("value", arg( "offset")=0), + manage_new_object_policy() + ) + .def("set_string_array", &CPointer::SetStringArray, "Sets the value at the given memory location.", - ("value",arg( "offset")=0) + ("value", arg( "offset")=0) ) // Other methods @@ -1048,6 +1060,7 @@ void export_global_variables(scope _memory) ADD_NATIVE_TYPE_SIZE("DOUBLE", double) ADD_NATIVE_TYPE_SIZE("POINTER", void*) ADD_NATIVE_TYPE_SIZE("STRING", char*) + ADD_NATIVE_TYPE_SIZE("STRING_POINTER", char*) _memory.attr("NULL") = object(CPointer()); From 3a5124dca00d15a337a342c77ca7772749aef1ca Mon Sep 17 00:00:00 2001 From: Jonathan <30329245+CookStar@users.noreply.github.com> Date: Sun, 21 May 2023 17:23:56 +0900 Subject: [PATCH 2/5] Changed instance/pointer_attribute to accept length when using string_array to prevent buffer overrun. --- .../source-python/entities/csgo/CCSPlayer.ini | 1 + .../entities/orangebox/cstrike/CCSPlayer.ini | 2 + .../weapons/scripts/WeaponInfo.ini | 1 + .../weapons/scripts/csgo/WeaponInfo.ini | 21 +++++++++++ .../weapons/scripts/orangebox/WeaponInfo.ini | 21 +++++++++++ .../scripts/orangebox/cstrike/WeaponInfo.ini | 6 +++ .../packages/source-python/memory/helpers.py | 2 +- .../packages/source-python/memory/manager.py | 37 ++++++++++++++++--- 8 files changed, 85 insertions(+), 6 deletions(-) mode change 100644 => 100755 addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini mode change 100644 => 100755 addons/source-python/data/source-python/weapons/scripts/WeaponInfo.ini mode change 100644 => 100755 addons/source-python/data/source-python/weapons/scripts/csgo/WeaponInfo.ini mode change 100644 => 100755 addons/source-python/data/source-python/weapons/scripts/orangebox/WeaponInfo.ini mode change 100644 => 100755 addons/source-python/data/source-python/weapons/scripts/orangebox/cstrike/WeaponInfo.ini diff --git a/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini b/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini index 6737da37d..d2344a47c 100755 --- a/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini +++ b/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini @@ -73,6 +73,7 @@ srv_check = False base = m_flGroundAccelLinearFracLastTime offset = 140 type = STRING_ARRAY + length = 16 [property] diff --git a/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini b/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini old mode 100644 new mode 100755 index 83d0e60cf..f7904215b --- a/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini +++ b/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini @@ -62,6 +62,7 @@ offset_windows = 5628 offset_linux = 5648 type = STRING_ARRAY + length = 16 [based_attribute] @@ -75,6 +76,7 @@ base = m_flFlashDuration offset = -28 type = STRING_ARRAY + length = 16 [property] diff --git a/addons/source-python/data/source-python/weapons/scripts/WeaponInfo.ini b/addons/source-python/data/source-python/weapons/scripts/WeaponInfo.ini old mode 100644 new mode 100755 index f64a9af2f..06096d718 --- a/addons/source-python/data/source-python/weapons/scripts/WeaponInfo.ini +++ b/addons/source-python/data/source-python/weapons/scripts/WeaponInfo.ini @@ -27,3 +27,4 @@ [[class_name]] type = STRING_ARRAY offset = 6 + length = 80 diff --git a/addons/source-python/data/source-python/weapons/scripts/csgo/WeaponInfo.ini b/addons/source-python/data/source-python/weapons/scripts/csgo/WeaponInfo.ini old mode 100644 new mode 100755 index a7d40e6f2..2c7cafe87 --- a/addons/source-python/data/source-python/weapons/scripts/csgo/WeaponInfo.ini +++ b/addons/source-python/data/source-python/weapons/scripts/csgo/WeaponInfo.ini @@ -8,22 +8,27 @@ [[print_name]] type = STRING_ARRAY offset = 86 + length = 80 [[view_model_name]] type = STRING_ARRAY offset = 166 + length = 80 [[world_model_name]] type = STRING_ARRAY offset = 246 + length = 80 [[primary_ammo_type]] type = STRING_ARRAY offset = 326 + length = 32 [[animation_prefix]] type = STRING_ARRAY offset = 438 + length = 16 [[bucket]] type = INT @@ -72,14 +77,17 @@ [[secondary_ammo_type]] type = STRING_ARRAY offset = 496 + length = 32 [[ai_addon_base]] type = STRING_ARRAY offset = 528 + length = 80 [[ai_addon]] type = STRING_ARRAY offset = 608 + length = 80 [[primary_ammo_index]] type = INT @@ -180,6 +188,7 @@ [[heat_effect_name]] type = STRING_ARRAY offset = 2096 + length = 80 [[smoke_color]] type = Vector @@ -188,18 +197,22 @@ [[muzzle_flash_effect_1stperson]] type = STRING_ARRAY offset = 2188 + length = 80 [[muzzle_flash_effect_3rdperson]] type = STRING_ARRAY offset = 2268 + length = 80 [[eject_brass_effect]] type = STRING_ARRAY offset = 2348 + length = 80 [[tracer_effect]] type = STRING_ARRAY offset = 2428 + length = 80 [[tracer_frequency]] type = INT @@ -368,10 +381,12 @@ [[zoom_in_sound_name]] type = STRING_ARRAY offset = 3705 + length = 80 [[zoom_out_sound_name]] type = STRING_ARRAY offset = 3785 + length = 80 [[bot_audible_range]] type = FLOAT @@ -384,26 +399,32 @@ [[wrong_team_message]] type = STRING_ARRAY offset = 3873 + length = 32 [[player_animation_extension]] type = STRING_ARRAY offset = 3905 + length = 16 [[shield_view_model_name]] type = STRING_ARRAY offset = 3921 + length = 64 [[addon_model_name]] type = STRING_ARRAY offset = 3985 + length = 80 [[addon_location_name]] type = STRING_ARRAY offset = 4065 + length = 80 [[silencer_model_name]] type = STRING_ARRAY offset = 4145 + length = 80 [[addon_scale]] type = FLOAT diff --git a/addons/source-python/data/source-python/weapons/scripts/orangebox/WeaponInfo.ini b/addons/source-python/data/source-python/weapons/scripts/orangebox/WeaponInfo.ini old mode 100644 new mode 100755 index 62fa98efa..fd882d800 --- a/addons/source-python/data/source-python/weapons/scripts/orangebox/WeaponInfo.ini +++ b/addons/source-python/data/source-python/weapons/scripts/orangebox/WeaponInfo.ini @@ -8,14 +8,17 @@ [[print_name]] type = STRING_ARRAY offset = 86 + length = 80 [[world_model]] type = STRING_ARRAY offset = 166 + length = 80 [[animation_prefix]] type = STRING_ARRAY offset = 326 + length = 16 [[slot_index]] type = INT @@ -64,70 +67,87 @@ [[primary_ammo_name]] type = STRING_ARRAY offset = 384 + length = 32 [[secondary_ammo_name]] type = STRING_ARRAY offset = 416 + length = 32 [[empty_sound]] type = STRING_ARRAY offset = 448 + length = 80 [[single_sound]] type = STRING_ARRAY offset = 528 + length = 80 [[single_npc_sound]] type = STRING_ARRAY offset = 608 + length = 80 [[double_sound]] type = STRING_ARRAY offset = 688 + length = 80 [[double_npc_sound]] type = STRING_ARRAY offset = 768 + length = 80 [[burst_sound]] type = STRING_ARRAY offset = 848 + length = 80 [[reload_sound]] type = STRING_ARRAY offset = 928 + length = 80 [[reload_npc_sound]] type = STRING_ARRAY offset = 1008 + length = 80 [[melee_miss_sound]] type = STRING_ARRAY offset = 1088 + length = 80 [[melee_hit_sound]] type = STRING_ARRAY offset = 1168 + length = 80 [[melee_hit_world_sound]] type = STRING_ARRAY offset = 1248 + length = 80 [[special_sound_1]] type = STRING_ARRAY offset = 1328 + length = 80 [[special_sound_2]] type = STRING_ARRAY offset = 1408 + length = 80 [[special_sound_3]] type = STRING_ARRAY offset = 1488 + length = 80 [[taunt_sound]] type = STRING_ARRAY offset = 1568 + length = 80 [[primary_ammo_type]] type = INT @@ -196,3 +216,4 @@ [[ai_addon]] type = STRING_ARRAY offset = 1704 + length = 80 diff --git a/addons/source-python/data/source-python/weapons/scripts/orangebox/cstrike/WeaponInfo.ini b/addons/source-python/data/source-python/weapons/scripts/orangebox/cstrike/WeaponInfo.ini old mode 100644 new mode 100755 index 85f94022f..e3acb5d8a --- a/addons/source-python/data/source-python/weapons/scripts/orangebox/cstrike/WeaponInfo.ini +++ b/addons/source-python/data/source-python/weapons/scripts/orangebox/cstrike/WeaponInfo.ini @@ -50,26 +50,32 @@ size = 2320 [[wrong_team_message]] type = STRING_ARRAY offset = 1817 + length = 32 [[player_animation_extension]] type = STRING_ARRAY offset = 1849 + length = 16 [[shield_view_model]] type = STRING_ARRAY offset = 1865 + length = 64 [[addon_model]] type = STRING_ARRAY offset = 1929 + length = 80 [[dropped_model]] type = STRING_ARRAY offset = 2009 + length = 80 [[silencer_model]] type = STRING_ARRAY offset = 2089 + length = 80 [[muzzle_flash_style_index]] type = INT diff --git a/addons/source-python/packages/source-python/memory/helpers.py b/addons/source-python/packages/source-python/memory/helpers.py index 4c0ba2177..d2367d377 100755 --- a/addons/source-python/packages/source-python/memory/helpers.py +++ b/addons/source-python/packages/source-python/memory/helpers.py @@ -79,7 +79,7 @@ class Key(object): # Attribute/array keys TYPE_NAME = 'type' - # Array keys + # Attribute(string length)/Array keys LENGTH = 'length' # Pointer keys diff --git a/addons/source-python/packages/source-python/memory/manager.py b/addons/source-python/packages/source-python/memory/manager.py index 2f65e8ac2..18f34c993 100755 --- a/addons/source-python/packages/source-python/memory/manager.py +++ b/addons/source-python/packages/source-python/memory/manager.py @@ -368,7 +368,8 @@ def create_type_from_dict(self, type_name, raw_data, bases=(CustomType,)): ( (Key.TYPE_NAME, Key.as_attribute_type, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), - (Key.DOC, Key.as_str, None) + (Key.DOC, Key.as_str, None), + (Key.LENGTH, Key.as_int, 0) ) ) @@ -434,7 +435,7 @@ def create_type_from_dict(self, type_name, raw_data, bases=(CustomType,)): # Now create and register the type return self(type_name, bases, cls_dict) - def instance_attribute(self, type_name, offset, doc=None): + def instance_attribute(self, type_name, offset, doc=None, length=0): """Create a wrapper for an instance attribute. Examples: @@ -475,12 +476,22 @@ def fset(ptr, value): # Make sure the value will not deallocate as long as it is # part of this object ptr._pointer_values[offset] = string_pointer + + # Handle string array type + elif type_name == Type.STRING_ARRAY: + if length and len(value) >= length: + raise ValueError( + 'The string length exceeds' + 'the limit "{0}".'.format(length-1)) + + ptr.set_string_array(value, offset) + else: getattr(ptr, 'set_' + type_name)(value, offset) return property(fget, fset, None, doc) - def pointer_attribute(self, type_name, offset, doc=None): + def pointer_attribute(self, type_name, offset, doc=None, length=0): """Create a wrapper for a pointer attribute. Examples: @@ -521,7 +532,12 @@ def fset(ptr, value): # Is there no space allocated? if not instance_ptr: # Allocate space for the value - instance_ptr = alloc(TYPE_SIZES[type_name.upper()]) + if type_name == Type.STRING_ARRAY: + size = length if length else len(value) + 1 + else: + size = TYPE_SIZES[type_name.upper()] + + instance_ptr = alloc(size) # Add the pointer to the set, so there will be a reference # until the instance gets deleted @@ -532,12 +548,23 @@ def fset(ptr, value): # Handle string pointer type if type_name == Type.STRING_POINTER: - string_pointer = instance_ptr.set_string_pointer(value, offset) + string_pointer = instance_ptr.set_string_pointer( + value, offset) string_pointer.auto_dealloc = True # Make sure the value will not deallocate as long as it is # part of this object ptr._pointer_values[offset] = string_pointer + + # Handle string array type + elif type_name == Type.STRING_ARRAY: + if length and len(value) >= length: + raise ValueError( + 'The string length exceeds' + 'the limit "{0}".'.format(length-1)) + + instance_ptr.set_string_array(value, offset) + else: # Set the value getattr(instance_ptr, 'set_' + type_name)(value) From 88f708a37b99e5a6ee61fa461ccad3fd137b7631 Mon Sep 17 00:00:00 2001 From: Jonathan <30329245+CookStar@users.noreply.github.com> Date: Tue, 23 May 2023 12:53:52 +0900 Subject: [PATCH 3/5] Fixed support for UTF8. Fixed missing support for based_attribute. Modified the description of SetStringPointer. --- .../source-python/entities/classes.py | 3 ++- .../packages/source-python/memory/manager.py | 6 +++--- src/core/modules/memory/memory_pointer.cpp | 20 ++++++++++++++----- src/core/modules/memory/memory_wrap.cpp | 2 +- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/addons/source-python/packages/source-python/entities/classes.py b/addons/source-python/packages/source-python/entities/classes.py index a8628a1d8..ef0a0b20b 100755 --- a/addons/source-python/packages/source-python/entities/classes.py +++ b/addons/source-python/packages/source-python/entities/classes.py @@ -359,7 +359,8 @@ def _get_server_class(self, class_name, datamap): attribute = method( Key.as_attribute_type(self, data['type']), offset, - data.get('doc') + data.get('doc'), + Key.as_int(self, data.get('length', 0)), ) # Assign the attribute to the instance diff --git a/addons/source-python/packages/source-python/memory/manager.py b/addons/source-python/packages/source-python/memory/manager.py index 18f34c993..e4503a336 100755 --- a/addons/source-python/packages/source-python/memory/manager.py +++ b/addons/source-python/packages/source-python/memory/manager.py @@ -479,7 +479,7 @@ def fset(ptr, value): # Handle string array type elif type_name == Type.STRING_ARRAY: - if length and len(value) >= length: + if length and len(value.encode()) >= length: raise ValueError( 'The string length exceeds' 'the limit "{0}".'.format(length-1)) @@ -533,7 +533,7 @@ def fset(ptr, value): if not instance_ptr: # Allocate space for the value if type_name == Type.STRING_ARRAY: - size = length if length else len(value) + 1 + size = length if length else len(value.encode()) + 1 else: size = TYPE_SIZES[type_name.upper()] @@ -558,7 +558,7 @@ def fset(ptr, value): # Handle string array type elif type_name == Type.STRING_ARRAY: - if length and len(value) >= length: + if length and len(value.encode()) >= length: raise ValueError( 'The string length exceeds' 'the limit "{0}".'.format(length-1)) diff --git a/src/core/modules/memory/memory_pointer.cpp b/src/core/modules/memory/memory_pointer.cpp index d681ad453..122d275a4 100755 --- a/src/core/modules/memory/memory_pointer.cpp +++ b/src/core/modules/memory/memory_pointer.cpp @@ -105,14 +105,24 @@ const char * CPointer::GetStringPointer(int iOffset /* = 0 */) CPointer * CPointer::SetStringPointer(str oString, int iOffset /* = 0 */) { Validate(); - unsigned long length = len(oString) + 1; - CPointer * pPtr = new CPointer((unsigned long) UTIL_Alloc(length), false); - char * value = (char *) pPtr->m_ulAddr; - memcpy(value, extract(oString), length); + + // Encode Unicode object and extract Python bytes object. + PyObject * pObj = PyUnicode_AsUTF8String(oString.ptr()); + if (!pObj) + BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Invalid UTF-8 string."); + + // Get string and length of bytes. + const char * szString = PyBytes_AS_STRING(pObj); + unsigned long length = PyBytes_GET_SIZE(pObj) + 1; + + char * value = (char *) UTIL_Alloc(length); + memcpy(value, szString, length); + TRY_SEGV() *(const char **) (m_ulAddr + iOffset) = value; EXCEPT_SEGV() - return pPtr; + + return new CPointer((unsigned long) value, false); } const char * CPointer::GetStringArray(int iOffset /* = 0 */) diff --git a/src/core/modules/memory/memory_wrap.cpp b/src/core/modules/memory/memory_wrap.cpp index 28628e56d..be1cd74b5 100755 --- a/src/core/modules/memory/memory_wrap.cpp +++ b/src/core/modules/memory/memory_wrap.cpp @@ -229,7 +229,7 @@ void export_pointer(scope _memory) .def("set_string_pointer", &CPointer::SetStringPointer, - "Sets the value at the given memory location. This string object must be deallocated by the user. Returns the string object.", + "Sets the value at the given memory location. Returns the string object. This string object must be deallocated by the user.", ("value", arg( "offset")=0), manage_new_object_policy() ) From 8d7a3b4c4fb8154ae9fe5c6703e97bb68f3ff8e1 Mon Sep 17 00:00:00 2001 From: Jonathan <30329245+CookStar@users.noreply.github.com> Date: Wed, 24 May 2023 20:22:46 +0900 Subject: [PATCH 4/5] Fixed SetStringPointer unable to accept None. --- .../packages/source-python/memory/manager.py | 18 ++++++++------- src/core/modules/memory/memory_pointer.cpp | 23 +++++++++++-------- src/core/modules/memory/memory_pointer.h | 2 +- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/addons/source-python/packages/source-python/memory/manager.py b/addons/source-python/packages/source-python/memory/manager.py index e4503a336..9b0be02a1 100755 --- a/addons/source-python/packages/source-python/memory/manager.py +++ b/addons/source-python/packages/source-python/memory/manager.py @@ -471,11 +471,12 @@ def fset(ptr, value): # Handle string pointer type if type_name == Type.STRING_POINTER: string_pointer = ptr.set_string_pointer(value, offset) - string_pointer.auto_dealloc = True + if string_pointer: + string_pointer.auto_dealloc = True - # Make sure the value will not deallocate as long as it is - # part of this object - ptr._pointer_values[offset] = string_pointer + # Make sure the value will not deallocate as long as + # it is part of this object + ptr._pointer_values[offset] = string_pointer # Handle string array type elif type_name == Type.STRING_ARRAY: @@ -550,11 +551,12 @@ def fset(ptr, value): if type_name == Type.STRING_POINTER: string_pointer = instance_ptr.set_string_pointer( value, offset) - string_pointer.auto_dealloc = True + if string_pointer: + string_pointer.auto_dealloc = True - # Make sure the value will not deallocate as long as it is - # part of this object - ptr._pointer_values[offset] = string_pointer + # Make sure the value will not deallocate as long as + # it is part of this object + ptr._pointer_values[offset] = string_pointer # Handle string array type elif type_name == Type.STRING_ARRAY: diff --git a/src/core/modules/memory/memory_pointer.cpp b/src/core/modules/memory/memory_pointer.cpp index 122d275a4..d4e36e209 100755 --- a/src/core/modules/memory/memory_pointer.cpp +++ b/src/core/modules/memory/memory_pointer.cpp @@ -102,21 +102,24 @@ const char * CPointer::GetStringPointer(int iOffset /* = 0 */) return result; } -CPointer * CPointer::SetStringPointer(str oString, int iOffset /* = 0 */) +CPointer * CPointer::SetStringPointer(char * szText, int iOffset /* = 0 */) { Validate(); - // Encode Unicode object and extract Python bytes object. - PyObject * pObj = PyUnicode_AsUTF8String(oString.ptr()); - if (!pObj) - BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Invalid UTF-8 string."); + char * value; - // Get string and length of bytes. - const char * szString = PyBytes_AS_STRING(pObj); - unsigned long length = PyBytes_GET_SIZE(pObj) + 1; + if (szText) + { + // Get length of string. + unsigned long length = strlen(szText) + 1; - char * value = (char *) UTIL_Alloc(length); - memcpy(value, szString, length); + value = (char *) UTIL_Alloc(length); + memcpy(value, szText, length); + } + else + { + value = szText; + } TRY_SEGV() *(const char **) (m_ulAddr + iOffset) = value; diff --git a/src/core/modules/memory/memory_pointer.h b/src/core/modules/memory/memory_pointer.h index 854819fca..fd337add6 100755 --- a/src/core/modules/memory/memory_pointer.h +++ b/src/core/modules/memory/memory_pointer.h @@ -137,7 +137,7 @@ class CPointer } const char * GetStringPointer(int iOffset = 0); - CPointer* SetStringPointer(str oString, int iOffset = 0); + CPointer* SetStringPointer(char * szText, int iOffset = 0); const char * GetStringArray(int iOffset = 0); void SetStringArray(char* szText, int iOffset = 0); From 9fefc1eae72c57cbddf5be24e4dd670566da5da9 Mon Sep 17 00:00:00 2001 From: Jonathan <30329245+CookStar@users.noreply.github.com> Date: Sat, 27 May 2023 23:03:05 +0900 Subject: [PATCH 5/5] Fixed an error for MSVC. Added space to error description. --- .../packages/source-python/memory/manager.py | 4 ++-- src/core/modules/memory/memory_pointer.cpp | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/addons/source-python/packages/source-python/memory/manager.py b/addons/source-python/packages/source-python/memory/manager.py index 9b0be02a1..a6d259e6c 100755 --- a/addons/source-python/packages/source-python/memory/manager.py +++ b/addons/source-python/packages/source-python/memory/manager.py @@ -482,7 +482,7 @@ def fset(ptr, value): elif type_name == Type.STRING_ARRAY: if length and len(value.encode()) >= length: raise ValueError( - 'The string length exceeds' + 'The string length exceeds ' 'the limit "{0}".'.format(length-1)) ptr.set_string_array(value, offset) @@ -562,7 +562,7 @@ def fset(ptr, value): elif type_name == Type.STRING_ARRAY: if length and len(value.encode()) >= length: raise ValueError( - 'The string length exceeds' + 'The string length exceeds ' 'the limit "{0}".'.format(length-1)) instance_ptr.set_string_array(value, offset) diff --git a/src/core/modules/memory/memory_pointer.cpp b/src/core/modules/memory/memory_pointer.cpp index d4e36e209..3efa50be1 100755 --- a/src/core/modules/memory/memory_pointer.cpp +++ b/src/core/modules/memory/memory_pointer.cpp @@ -102,6 +102,13 @@ const char * CPointer::GetStringPointer(int iOffset /* = 0 */) return result; } +void SetStringPointerHelper(unsigned long addr, const char * ptr) +{ + TRY_SEGV() + *(const char **) (addr) = ptr; + EXCEPT_SEGV() +} + CPointer * CPointer::SetStringPointer(char * szText, int iOffset /* = 0 */) { Validate(); @@ -121,9 +128,7 @@ CPointer * CPointer::SetStringPointer(char * szText, int iOffset /* = 0 */) value = szText; } - TRY_SEGV() - *(const char **) (m_ulAddr + iOffset) = value; - EXCEPT_SEGV() + SetStringPointerHelper(m_ulAddr + iOffset, value); return new CPointer((unsigned long) value, false); }