The documentation of IStream.Read documents what happens if fewer bytes are read than requested:
Return value
Return code
Description
S_OK
All of the requested data was successfully read from the stream object; the number of bytes requested in cb is the same as the number of bytes returned in pcbRead.
S_FALSE
The value returned in pcbRead is less than the number of bytes requested in cb. This indicates the end of the stream has been reached. The number of bytes read indicates how much of the pv buffer has been filled.
(emphasis mine)
The current TStreamAdapter.Read implementation (Delphi 10.3):
function TStreamAdapter.Read(pv: Pointer; cb: FixedUInt; pcbRead: PFixedUInt): HResult;
var
NumRead: LongInt;
begin
try
if pv = nil then
begin
Result := STG_E_INVALIDPOINTER;
Exit;
end;
NumRead := FStream.Read(pv^, cb);
if pcbRead <> nil then pcbRead^ := NumRead;
Result := S_OK; //BUGBUG: Doesn't return S_FALSE if NumRead < cb
except
Result := S_FALSE; //BUGBUG: Returns success (S_FALSE), rather than an error (e.g. E_FAIL) in the case of an error
end;
end;
So the fix would be:
function TStreamAdapter.Read(pv: Pointer; cb: FixedUInt; pcbRead: PFixedUInt): HResult;
var
NumRead: LongInt;
begin
try
if pv = nil then
begin
Result := STG_E_INVALIDPOINTER;
Exit;
end;
NumRead := FStream.Read(pv^, cb);
if pcbRead <> nil then pcbRead^ := NumRead;
//BUGFIX (20220204) - return S_FALSE if not all the requested bytes could be read
if NumRead < cb then
begin
Result := S_FALSE;
Exit;
end;
Result := S_OK;
except
Result := E_FAIL; //BUGFIX (20220204) - Don't return success (S_FALSE) when there's an error. Return an error!
end;
end;
Tested
Background
The documentation of IStream.Read documents what happens if fewer bytes are read than requested:
(emphasis mine)
The current TStreamAdapter.Read implementation (Delphi 10.3):
So the fix would be: