Bug regarding function TBufferedFileStream.ReadPageBeforeWrite
by 'lagprogramming'.
packages/fcl-base/src/bufstream.pp has the following function:
function TBufferedFileStream.ReadPageBeforeWrite: Boolean;
var
j: integer;
pCache: PStreamCacheEntry=nil;
lStreamPosition: int64;
lExpectedBytesToRead: integer;
lEffectiveRead: integer;
begin
// Find free page entry
for j := 0 to Pred(FStreamCachePageMaxCount) do begin
if not Assigned(FCachePages[j]^.Buffer) then begin
pCache:=FCachePages[j];
FCacheLastUsedPage:=j;
break;
end;
end;
if not Assigned(pCache) then begin
// Free last used page
pCache:=FreeOlderInUsePage(false);
end;
if not Assigned(pCache^.Buffer) then begin
Getmem(pCache^.Buffer,FStreamCachePageSize);
end;
lStreamPosition:=(FCacheStreamPosition div FStreamCachePageSize)*FStreamCachePageSize;
inherited Seek(lStreamPosition,soBeginning);
if (lStreamPosition+FStreamCachePageSize) > FCacheStreamSize then begin
lExpectedBytesToRead:=FCacheStreamSize-lStreamPosition;
end else begin
lExpectedBytesToRead:=FStreamCachePageSize;
end;
pCache^.PageBegin:=lStreamPosition;
pCache^.PageRealSize:=inherited Read(pCache^.Buffer^,FStreamCachePageSize);
if pCache^.PageRealSize<>lExpectedBytesToRead then begin
lEffectiveRead:=pCache^.PageRealSize;
pCache^.IsDirty:=false;
pCache^.LastTick:=0;
pCache^.PageBegin:=0;
pCache^.PageRealSize:=0;
Freemem(pCache^.Buffer);
pCache^.Buffer:=nil;
Raise EStreamError.CreateFmt(SErrCacheUnableToReadExpected,[lExpectedBytesToRead,lEffectiveRead]);
end;
pCache^.LastTick:=GetOpCounter;
Result:=true;
end;
The function never returns false. Either it returns true, either it raises an exception. ReadPageBeforeWrite is called by function TBufferedFileStream.DoCacheWrite, which expects boolean results, not exceptions.
This is how DoCacheWrite tries to use the result:
if ReadPageBeforeWrite then begin
Result:=DoCacheWrite(Buffer,Count);
end else begin
Result:=0;
end;