TStringList.SetCapacity bug
Original Reporter info from Mantis: SergeAnvarov @SergeAnvarov
-
Reporter name: Serge Anvarov
Original Reporter info from Mantis: SergeAnvarov @SergeAnvarov
- Reporter name: Serge Anvarov
Description:
TStringList.SetCapacity don't check the FCount field. So, when the Capacity set to a value less then Count, then Destroy method call InternalClear, that try to free not existing items in memory (access memory or other error).
As a result, in case of the NewCapacity less then the existing FCapacity and a new list allocated, all old items with less capacity moved to it, but all old items above new size not freed (memory leak).
Steps to reproduce:
L := TStringList.Create;
try
L.Capacity := 2;
L.Add('1');
L.Add(StringOfChar('2', 2048));
L.Capacity := 1;
finally
L.Free;
end;
Additional information:
Source: ./fpc/2.6.2/source/rtl/objpas/classes/stringl.inc
Solution. If NewCapacity less then count:
- Raise error
or
- Decrease count and done accurate strings finalization and memory free. For example:
2a. Add method "procedure TStringList.ClearFrom(FromIndex: Integer);"
2b. Copy to it code from InternalClear and change it from "for I:=0..." to "for I:=FromIndex..."
2c. Last two lines of copied code replace with "FCount := FromIndex;"
2d. Rewrite InternalClear as "begin ClearFrom(0); SetCapacity(0); end;"
2e. Add to SetCapacity at top of branch "...if NewCapacity&LtPos;FCapacity then..." code "ClearFrom(NewCapacity);"
Mantis conversion info:
- Mantis ID: 24943
- OS: any
- OS Build: any
- Platform: any
- Version: 2.6.2
- Fixed in version: 2.6.4
- Fixed in revision: 25928 (#e3f7d612)
- Target version: 3.0.0