Skip to content

Commit c527204

Browse files
committed
improved valid object detection
1 parent 0a5e7a9 commit c527204

File tree

1 file changed

+14
-19
lines changed

1 file changed

+14
-19
lines changed

Source/Base/Spring.Events.Base.pas

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,13 @@ implementation
9595
{$ENDIF}
9696
TypInfo;
9797

98-
function IsValidObj(p: PPointer): Boolean;
98+
function IsValidObject(p: PPointer): Boolean;
9999
{$IFDEF MSWINDOWS}
100100
var
101101
memInfo: TMemoryBasicInformation;
102102
{$ENDIF}
103103

104-
function IsValidPtr(address: Pointer): Boolean;
104+
function IsValidAddress(address: Pointer): Boolean;
105105
begin
106106
// Must be above 64k and 4 byte aligned
107107
if (UIntPtr(address) > $FFFF) and (UIntPtr(address) and 3 = 0) then
@@ -116,18 +116,16 @@ function IsValidObj(p: PPointer): Boolean;
116116
VirtualQuery(address, memInfo, SizeOf(memInfo));
117117
end;
118118
// check the readability of the memory address
119-
Result := (memInfo.RegionSize >= SizeOf(Pointer))
119+
if (memInfo.RegionSize >= SizeOf(Pointer))
120120
and (memInfo.State = MEM_COMMIT)
121121
and (memInfo.Protect and (PAGE_READONLY or PAGE_READWRITE
122122
or PAGE_WRITECOPY or PAGE_EXECUTE or PAGE_EXECUTE_READ
123123
or PAGE_EXECUTE_READWRITE or PAGE_EXECUTE_WRITECOPY) <> 0)
124-
and (memInfo.Protect and PAGE_GUARD = 0);
125-
{$ELSE}
126-
Result := True;
124+
and (memInfo.Protect and PAGE_GUARD = 0) then
127125
{$ENDIF}
128-
end
129-
else
130-
Result := False;
126+
Exit(True);
127+
end;
128+
Result := False;
131129
end;
132130

133131
begin
@@ -137,22 +135,18 @@ function IsValidObj(p: PPointer): Boolean;
137135
{$IFDEF MSWINDOWS}
138136
memInfo.RegionSize := 0;
139137
{$ENDIF}
140-
if IsValidPtr(PByte(p) + vmtSelfPtr)
138+
if IsValidAddress(p)
141139
// not a class pointer - they point to themselves in the vmtSelfPtr slot
142-
and (p <> PPointer(PByte(p) + vmtSelfPtr)^) then
143-
if IsValidPtr(p) and IsValidPtr(PByte(p^) + vmtSelfPtr)
140+
and not (IsValidAddress(PByte(p) + vmtSelfPtr)
141+
and (p = PPointer(PByte(p) + vmtSelfPtr)^)) then
142+
if IsValidAddress(p^) and IsValidAddress(PByte(p^) + vmtSelfPtr)
144143
// looks to be an object, it points to a valid class pointer
145144
and (p^ = PPointer(PByte(p^) + vmtSelfPtr)^) then
146145
Result := True;
147146
except
148147
end; //FI:W501
149148
end;
150149

151-
function SafeIsClass(p: Pointer; cls: TClass): Boolean; inline;
152-
begin
153-
Result := IsValidObj(p) and (TObject(p) is cls);
154-
end;
155-
156150

157151
{$REGION 'TEventBase'}
158152

@@ -276,7 +270,8 @@ procedure TEventBase.Notify(sender: TObject; const item: TMethod;
276270
data: Pointer;
277271
begin
278272
data := item.Data;
279-
if UseFreeNotification and SafeIsClass(data, TComponent) then
273+
if UseFreeNotification
274+
and IsValidObject(data) and TObject(data).InheritsFrom(TComponent) then
280275
case action of //FI:W535
281276
cnAdded:
282277
begin
@@ -411,7 +406,7 @@ procedure TEventBase.SetUseFreeNotification(const value: Boolean);
411406
if Assigned(handler) and Assigned(handler.Code) then
412407
repeat
413408
data := handler.Data;
414-
if SafeIsClass(data, TComponent) then
409+
if IsValidObject(data) and TObject(data).InheritsFrom(TComponent) then
415410
begin
416411
EnsureNotificationHandler;
417412
fNotificationHandler.FreeNotification(TComponent(data));

0 commit comments

Comments
 (0)