david_navigator 12 Posted March 30, 2021 The following code (which has been in my 32 bit app for about 10 years) has just started to throw a range check error for one tester. All I can think of is that the cast of TObject to an Integer is the issue, but in that case why would it only affect one user ? The only difference between this user and others is that he's running under WINE, but I don't know why that would make a difference ? procedure TEqlistFrm.VenueEditMainKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin PostMessage(Handle, CM_SEARCH, Integer(Sender), Key); end; Share this post Link to post
Vandrovnik 214 Posted March 30, 2021 In Windows.pas: type WPARAM = UINT_PTR; Then: UINT_PTR = System.UIntPtr; // NativeUInt; UIntPtr = NativeUInt; So just change the typecast to WPARAM should be enough. Now it probably would not work fine in 64 bits? Share this post Link to post
Remy Lebeau 1393 Posted March 30, 2021 1 hour ago, david_navigator said: All I can think of is that the cast of TObject to an Integer is the issue, but in that case why would it only affect one user ? 32bit vs 64bit? You really should not be casting to Integer at all. Cast to WPARAM instead, which is what PostMessage() is expecting procedure TEqlistFrm.VenueEditMainKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin PostMessage(Handle, CM_SEARCH, WPARAM(Sender), LPARAM(Key)); end; 1 Share this post Link to post
david_navigator 12 Posted March 30, 2021 2 minutes ago, Remy Lebeau said: 32bit vs 64bit? 32bit Quote You really should not be casting to Integer at all. Cast to WPARAM instead, which is what PostMessage() is expecting It's a colleagues code who's currently on furlough so I'm a bit hesitant to change the code, especially as 1. there are 44 instances where Sender is cast as an Integer and I don't know if they'll be any "gotchas" ? 2. I don't even know if this is the reason for the ERangeCheck as I can't reproduce. Share this post Link to post
Stefan Glienke 2002 Posted March 30, 2021 (edited) Don't blame the developer - blame the poor hints - taken from Delphi XE and 10.4: Before anyone tells me to report it - been there, done it! https://quality.embarcadero.com/browse/RSP-17110 The cast to Integer is indeed wrong - see the assembly code with Bounds checking enabled: Unit2.pas.31: PostMessage(Handle, CM_SEARCH, Integer(Sender), Key); 0060F70F 8B45F4 mov eax,[ebp-$0c] 0060F712 0FB700 movzx eax,[eax] 0060F715 50 push eax 0060F716 8B45F8 mov eax,[ebp-$08] 0060F719 85C0 test eax,eax 0060F71B 7905 jns $0060f722 0060F71D E80686DFFF call @BoundErr 0060F722 50 push eax 0060F723 6800CA9A3B push $3b9aca00 0060F728 8B45FC mov eax,[ebp-$04] 0060F72B E8406EF4FF call TWinControl.GetHandle 0060F730 50 push eax 0060F731 E82A67E0FF call PostMessage With cast to WPARAM: Unit2.pas.31: PostMessage(Handle, CM_SEARCH, WPARAM(Sender), Key); 0060F70F 8B45F4 mov eax,[ebp-$0c] 0060F712 0FB700 movzx eax,[eax] 0060F715 50 push eax 0060F716 8B45F8 mov eax,[ebp-$08] 0060F719 50 push eax 0060F71A 6800CA9A3B push $3b9aca00 0060F71F 8B45FC mov eax,[ebp-$04] 0060F722 E8496EF4FF call TWinControl.GetHandle 0060F727 50 push eax 0060F728 E83367E0FF call PostMessage To reproduce try enabling top down memory allocation in your windows which will cause the Sender pointer to be large enough that it will be negative when cast to Integer Edited March 30, 2021 by Stefan Glienke 2 Share this post Link to post
david_navigator 12 Posted March 30, 2021 1 minute ago, Attila Kovacs said: then why are you asking? If I was 100% certain that this was the reason for the RangeCheck error, then obviously I'd update the code and spend a load of time testing there were no side effects, but is it ? As I said the code's been like this for 10 years, it's code that executes around the world 1000's of times a day and I've only had a report from one user. Share this post Link to post
Attila Kovacs 629 Posted March 30, 2021 (edited) This is the very same analogy as 10 billion flies can't be wrong. You should really go like @Remy Lebeau suggested. Optionally you could read up signed and unsigned data. Edited March 30, 2021 by Attila Kovacs Share this post Link to post
david_navigator 12 Posted March 30, 2021 5 minutes ago, Stefan Glienke said: Don't blame the developer - blame the poor hints - taken from Delphi XE and 10.4: The cast to Integer is indeed wrong - see the assembly code with Bounds checking enabled: With cast to WPARAM: Thanks. That makes sense. So now I need to update all of his code 🙂 Share this post Link to post
Attila Kovacs 629 Posted March 30, 2021 (edited) @Stefan Glienke I can't reproduce the yellow one in Berlin. Strange. Edit: ahhhh, it was XE. Okay. Sorry. Edited March 30, 2021 by Attila Kovacs Share this post Link to post
Stefan Glienke 2002 Posted March 30, 2021 (edited) 5 minutes ago, Attila Kovacs said: @Stefan Glienke I can't reproduce the yellow one in Berlin. Strange. What exactly is strange about it? They changed WPARAM from INT_PTR to UINT_PTR in XE2. The point is that the hint still does not show the actual alias name being used in the declaration of the routine but the actual type it aliases. And that is wrong because that causes these kinds of defects when the alias changes because people of course did a cast to the type being shown in code insight. Edited March 30, 2021 by Stefan Glienke Share this post Link to post
Guest Posted March 30, 2021 33 minutes ago, david_navigator said: So now I need to update all of his code 🙂 Before updating anything try to reproduce the error first. 43 minutes ago, david_navigator said: 1. there are 44 instances where Sender is cast as an Integer and I don't know if they'll be any "gotchas" ? 2. I don't even know if this is the reason for the ERangeCheck as I can't reproduce. It is way easier than you think to reproduce, all what you need is to make sure the address are higher than MaxInt, so use FastMM4 from here https://github.com/pleriche/FastMM4 and notice this option AlwaysAllocateTopDown here https://github.com/pleriche/FastMM4/blob/ca64b52ac6d918f4dbd06c20c28e8f961a7e450f/FastMM4Options.inc#L178 leave it on, and you will catch them all red handed. Share this post Link to post
Fr0sT.Brutal 900 Posted March 31, 2021 This is exactly the case when devs do things wrong, not following OS vendor's recommended way, and it kinda works for years but then BADABOOM happens. All external functions must use their own typedefs. If WinAPI header says it wants DWORD and WPARAM, don't try using Cardinal/Integer Share this post Link to post
luebbe 26 Posted March 31, 2021 This Discussion made me run a grep for this construct across code that we use and I found that some of the ICS demos are using an integer cast in PostMessage() instead of WPARAM. Maybe @Remy Lebeau wants to take a look? :) 1 Share this post Link to post
Attila Kovacs 629 Posted March 31, 2021 (edited) I've found some cardinal() casts in some legacy code for pointers 😉 @luebbe are those casts in ICS Demo also for pointers or for integer numbers? Edited March 31, 2021 by Attila Kovacs Share this post Link to post
luebbe 26 Posted March 31, 2021 I didn't look at the code in the IDE, just what grepwin spat out, but I'd say: smtpQuit : PostMessage(Form1.Handle, WM_REMOVEOBJ, Integer(Sender), 0); probably casts a pointer to integer. And there are more of these. 1 Share this post Link to post
Fr0sT.Brutal 900 Posted March 31, 2021 3 hours ago, luebbe said: This Discussion made me run a grep for this construct across code that we use and I found that some of the ICS demos are using an integer cast in PostMessage() instead of WPARAM. Maybe @Remy Lebeau wants to take a look? 🙂 Remy maintains Indy, ICS is maintained by Francois and Angus. Anyway, all sources should be examined for such casts Share this post Link to post
luebbe 26 Posted March 31, 2021 Oops, sorry, so let's ping @FPiette instead Share this post Link to post
david_navigator 12 Posted March 31, 2021 21 hours ago, Kas Ob. said: Before updating anything try to reproduce the error first. It is way easier than you think to reproduce, all what you need is to make sure the address are higher than MaxInt, so use FastMM4 from here https://github.com/pleriche/FastMM4 and notice this option AlwaysAllocateTopDown here https://github.com/pleriche/FastMM4/blob/ca64b52ac6d918f4dbd06c20c28e8f961a7e450f/FastMM4Options.inc#L178 leave it on, and you will catch them all red handed. Thanks. That did indeed reproduce the error and also proved that the fix worked. Many thanks Share this post Link to post