GetPropertyText fails beyond 1024+x chars

Discussions about Coding and Scripting

GetPropertyText fails beyond 1024+x chars

Postby Barbie » Wed Oct 10, 2018 4:23 am

GetPropertyText() causes an UT crash if the text exceeds 1024+some more. Is there a possibility to clamp the text at - lets say 1023 characters?

Core of my test code (there is a SpecialEvent with a text of a length of 1030):
Code: Select all
if (FindActorByName('SpecialEvent0', SE)) {
   // this works:
   //TextLen = Len(SpecialEvent(SE).Message);
   // but this not:
   TextLen = Len(SE.GetPropertyText("Message"));
   BroadcastMessage(SE @ "text lenght is" @ TextLen);
}

Test map is attached (beware - it will crash your UT if you touch the Trigger.)
Attachments
TestTextLenBeyound1024.unr
It will crash your UT if you touch the Trigger.
(8.1 KiB) Downloaded 9 times
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
Barbie
Godlike
 
Posts: 1545
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: GetPropertyText fails beyond 1024+x chars

Postby Chris » Wed Oct 10, 2018 5:16 am

The native side of UT sometimes relies on the function

Code: Select all
GetStaticString1024();


This is intended to interface a static string stack for temporary strings to avoid allocating/deallocating strings heavily due to the cost of malloc/dealloc.
It's very useful in that it saves a lot of processor time. The downside is that the blocksize is limited. Thus each string is limited to 1024 (1023 + nullterminator). In most cases it doesn't hurt to use more than 1023 in terms of risking
heap corruption because, if I recall, the stack is [512][1024], so there are 512 x 1024 * sizeof(wchar_t) (which is 2 on MSVC). So unless you're on the last row in the stack, it wont go out of bounds completely. Of course, when the function is called next time it will overwrite anything beyond 1024 and destroy the null-terminator, thus causing havoc in other ways.

Conclusion? Don't ever use strings larger than 1023, Ever!
A string that large is very rare, and would most often never be seen other than during testing. It also takes forever to process for obvious reasons.

You can clamp the text using Str = Left(Str, 1023);
It may or may not help, depends on GetPropertyText and how it handles the result.
The string itself isn't limited, but the static string stack is, thus any function that uses it together with a string larger than 1023 will cause corruption.
So don't use GetPropertyText here, use the member access operator and then clamp the message using Left().

P.S That special event should be thrown away and tucked under something that will never see daylight again. :loool:
Chris
Experienced
 
Posts: 113
Joined: Mon Nov 24, 2014 9:27 am

Re: GetPropertyText fails beyond 1024+x chars

Postby Higor » Wed Oct 10, 2018 7:23 am

It uses a local stack buffer, and they knew exactly what they were doing (check the //!! comment)

Code: Select all
void UObject::execGetPropertyText( FFrame& Stack, RESULT_DECL )
{
   P_GET_STR(PropName);
   P_FINISH;

   UProperty* Property=FindField<UProperty>( Class, *PropName );
   if( Property && (Property->GetFlags() & RF_Public) )
   {
      TCHAR Temp[1024]=TEXT("");//!!
      Property->ExportText( 0, Temp, (BYTE*)this, (BYTE*)this, PPF_Localized );
      *(FString*)Result = Temp;
   }
   else *(FString*)Result = TEXT("");
}
Higor
Godlike
 
Posts: 1643
Joined: Sun Mar 04, 2012 6:47 pm

Re: GetPropertyText fails beyond 1024+x chars

Postby Barbie » Wed Oct 10, 2018 4:23 pm

I run into this on the attempt to patch a map on loading: Because the Translator does not work in UT I wanted to add a Trigger/SpecialEvent at every TranslatorEvent, copy the properties, and display the message if a player touches the Trigger. Unfortunately the mapper has used a custom version of TranslatorEvent and did it not as a sub class of TranslatorEvent. So I had to read the message via "GetPropertyText()".

It seems there will be no way to do that via UScript...
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
Barbie
Godlike
 
Posts: 1545
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: GetPropertyText fails beyond 1024+x chars

Postby Chris » Wed Oct 10, 2018 6:39 pm

Higor wrote:It uses a local stack buffer, and they knew exactly what they were doing (check the //!! comment)

Code: Select all
void UObject::execGetPropertyText( FFrame& Stack, RESULT_DECL )
{
   P_GET_STR(PropName);
   P_FINISH;

   UProperty* Property=FindField<UProperty>( Class, *PropName );
   if( Property && (Property->GetFlags() & RF_Public) )
   {
      TCHAR Temp[1024]=TEXT("");//!!
      Property->ExportText( 0, Temp, (BYTE*)this, (BYTE*)this, PPF_Localized );
      *(FString*)Result = Temp;
   }
   else *(FString*)Result = TEXT("");
}


They may have known what they were doing, yet they failed to make sure a stack corruption would never occur. It could easily have been avoided by not writing outside the buffer.
Chris
Experienced
 
Posts: 113
Joined: Mon Nov 24, 2014 9:27 am


Return to Coding, Scripting

Who is online

Users browsing this forum: No registered users and 1 guest

cron