Recent

Author Topic: Bug regarding function TBufferedFileStream.ReadPageBeforeWrite  (Read 847 times)

lagprogramming

  • Sr. Member
  • ****
  • Posts: 407
packages/fcl-base/src/bufstream.pp has the following function:
Code: Pascal  [Select][+][-]
  1. function TBufferedFileStream.ReadPageBeforeWrite: Boolean;
  2. var
  3.   j: integer;
  4.   pCache: PStreamCacheEntry=nil;
  5.   lStreamPosition: int64;
  6.   lExpectedBytesToRead: integer;
  7.   lEffectiveRead: integer;
  8. begin
  9.   // Find free page entry
  10.   for j := 0 to Pred(FStreamCachePageMaxCount) do begin
  11.     if not Assigned(FCachePages[j]^.Buffer) then begin
  12.       pCache:=FCachePages[j];
  13.       FCacheLastUsedPage:=j;
  14.       break;
  15.     end;
  16.   end;
  17.   if not Assigned(pCache) then begin
  18.     // Free last used page
  19.     pCache:=FreeOlderInUsePage(false);
  20.   end;
  21.   if not Assigned(pCache^.Buffer) then begin
  22.     Getmem(pCache^.Buffer,FStreamCachePageSize);
  23.   end;
  24.   lStreamPosition:=(FCacheStreamPosition div FStreamCachePageSize)*FStreamCachePageSize;
  25.   inherited Seek(lStreamPosition,soBeginning);
  26.   if (lStreamPosition+FStreamCachePageSize) > FCacheStreamSize then begin
  27.     lExpectedBytesToRead:=FCacheStreamSize-lStreamPosition;
  28.   end else begin
  29.     lExpectedBytesToRead:=FStreamCachePageSize;
  30.   end;
  31.   pCache^.PageBegin:=lStreamPosition;
  32.   pCache^.PageRealSize:=inherited Read(pCache^.Buffer^,FStreamCachePageSize);
  33.   if pCache^.PageRealSize<>lExpectedBytesToRead then begin
  34.     lEffectiveRead:=pCache^.PageRealSize;
  35.     pCache^.IsDirty:=false;
  36.     pCache^.LastTick:=0;
  37.     pCache^.PageBegin:=0;
  38.     pCache^.PageRealSize:=0;
  39.     Freemem(pCache^.Buffer);
  40.     pCache^.Buffer:=nil;
  41.     Raise EStreamError.CreateFmt(SErrCacheUnableToReadExpected,[lExpectedBytesToRead,lEffectiveRead]);
  42.   end;
  43.   pCache^.LastTick:=GetOpCounter;
  44.   Result:=true;
  45. 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:
Code: Pascal  [Select][+][-]
  1. if ReadPageBeforeWrite then begin
  2.   Result:=DoCacheWrite(Buffer,Count);
  3. end else begin
  4.   Result:=0;
  5. end;


 

TinyPortal © 2005-2018