JackTrapper / DelphiBugs

Bug tracker for Delphi
7 stars 2 forks source link

TStreamAdapter.Read returns S_OK rather than S_FALSE is number of bytes read was less than requested #27

Open JackTrapper opened 2 years ago

JackTrapper commented 2 years ago

Tested

Background

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;
JackTrapper commented 2 years ago

Demo output

image