Forum > FPSpreadsheet

[SOLVED]problems about memory leak

(1/1)

kinlion:
Hi,

I found when using TsWorkbookSource.LoadFromFile or TsWorkbookSource.WorkBook.LoadFromStream, with file format sfOpenDocument or sfOOXml, the application will raise exception of memory leak when it terminated.
Further more, diffrent file format makes different count of memory leak blocks, but diffrent method, LoadFromFile or LoadFromStream, with same file format makes same count of memory leak blocks.
my code:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.loadSpreadSheet;var rs: TResourceStream;begin  rs := TResourceStream.Create(HINSTANCE, 'TEST_FILE', 'FILE');  try    // ws is TsWorkbookSource putted on the form    ws.Workbook.ReadFromStream(rs, sfOpenDocument); // no this line, no memory leak  finally    rs.Free;  end;end; My Enviroment:
  OS: Win10 x64
  Lazarus: 2.0.10 x64
  FPC: 3.2.0 x64
  SVN: 63526
  FPSpreadsheet: 1.14.0.0 installed from "Online Package Manager"

The attachment is the spreadsheet file of OpenDocument format produced by LibreOffice 7.4.2.3(x64).
I'm not sure it is a bug or something I did wrong?

Best regards.

wp:

--- Quote from: kinlion on November 23, 2022, 05:56:14 am ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  rs := TResourceStream.Create(HINSTANCE, 'TEST_FILE', 'FILE');
--- End quote ---
AFAIK, there is no resource type "FILE", I've only seen the RT_XXXX constants as last argument here. And for a file embedded in a resource, I'd expect it to be RT_RCDATA (in unit LCLType). So, the correct call, in my opinion, would be


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  rs := TResourceStream.Create(HINSTANCE, 'TEST_FILE', RT_RCDATA);
And when I embed a file created by myself (using LibreOffice v7.3.7) into the the resources (Project options > Resources > Add), the file can be read correctly without an error, and without leaving a memory leak.

With your file, however, I am getting an arithmetic overflow, and even my LibreOffice Calc complains about too many columns when I try to load it.

According to // http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications, an ods file up to v7.3 can hold at most 1024 columns. And in fact, the "table:table-cell" node of each row in your ods file looks like this:

--- Code: XML  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---<table:table-cell table:number-columns-repeated="16372" />This means that there are at least 16372 columns - way too much. I noticed in above specification link, however, that Calc v7.4 allows up to 16384 columns, but FPSpreadsheet is not yet up-to-date with that new specification.

The ods reader of FPSpreadsheet does detect this error situation and refuses to read cells if they were found beyond the 1024 columns limit. But in this case the method TsSpreadOpenDocReader.ReadCell did return an undefined value in the argument AColsRepeated.

This is fixed now in the svn repository. You can fix your OPM version easily, too: Open file fpsOpenDocument.pas, find the code for this method, and add "AColsRepeated := 0;" as first statement. Then recompile the fpspreadsheet package.

After this modification I could also load your file without error, and without memory leak.

kinlion:
Thanks a lot to wp.  :)

kinlion:

--- Quote from: wp on November 25, 2022, 12:15:59 pm ---AFAIK, there is no resource type "FILE"

--- End quote ---

I'm using resource by add a .rc file to my project, in a .rc file, one can define any resource type instead of system predefined type consts.

for example, add a line in project file:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$R test.rc} 
and write a single line in test.rc file as:

TEST_JPG                IMAGE_FILE         'test.jpg'

in a .rc file, each line describe a resource,
and a line is seperated into 3 parts by blank char(s), both spaces or tabs are OK.
1st part: TEST_JPG is the resource name
2nd part: IMAGE_FILE is the resource type
3rd part: test.jpg is the file of the resource data

if the resource type does not match any system predefined SYMBOL, then it becomes
the customized resource type named by the string, IMAGE_FILE in the above example.

if you want the resource type to be RT_RCDATA, just replace the IMAGE_FILE by RCDATA.

The .rc file format is explained by Microsoft, I don't know if it is OK on other OS

Navigation

[0] Message Index

Go to full version