Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2017-10

Fpsreadsheet bug?

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Malcolm Buckingham

I've run into a problem using fpsreadseet. I'm getting the following exception:-

Project ezcel raised exception class 'EListError' with message: List index (0) out of bounds.

I'm using Lazarus v1.2.6 and fpspreadsheet 1.8.4. The problem occurs under Windows 7 and 10.

The location of the error is Line 1246 in xlscommon.pas, function TsSpreadBIFFReader.FixFontIndex :-

  fnt := TsFont(FFontList[AFontIndex]);

My "ezcel" program reads spreadsheets from a number of different sources and allows the user to automatically extract data for adding into a database. Most spreadsheets work OK but the ones that cause the problem are BIFF8 files that have no FONT records in the workbook globals. The comments at the start of xlsbiff8.pas state that there should be FONT records, and the OpenOffice.org's documentation says the same thing.

However both Excel and LibreOffice read the files OK, and when re-saved ezcel opens them correctly because the FONT records have been added.

After more debugging I discoved that when loading a .xls file procedure TsWorkbook.InitFonts; is called ( twice ) presumably to handle cases where FONT records are missing. The procedure sets 4 default fonts.

At line 8099 in fpspreadsheet.pas I evaluated FFontList. The code and result were:-

AReader.ReadFromFile(AFileName, AParams);
<TFPLIST> = {
<TOBJECT> = {
_vptr$ = {
0x63bf34,
0x314a3f0}},
FLIST = $314a3f0,
FCOUNT = 4,
FCAPACITY = 4}

I then single stepped to the next line of code, which was line 466 in fpsReaderWriter. This was the start of procedure
TsCustomSpreadReader.ReadFromFile

<TFPLIST> = {
<TOBJECT> = {
_vptr$ = {
0x63bf34,
0x0}},
FLIST = $0,
FCOUNT = 0,
FCAPACITY = 0}

I don't really understand how objects are stored but it seems they consist of two pointers; one for the code and one for the data. In this case the data pointer is being trashed which leads to an empty fonts list.

So, is this a bug or a case of there simpy being a problem with the excel file? I should point out that the software can read BIFF2 files even with no font information. With the BIFF8 files there are INT_EXCEL_ID_XF records in Workbook Globals and these record need to access he fonts.

I hope someone can help.

Malcolm

Reply by email

Werner Pamler
to Werner Pamler

Thanks for sharing the file and for your pre-analysis which helped me to find the bug quickly. It is fixed in fpspreadsheet r6047. If you want to stick to your currently installed version 1.8.4 you must patch the function TsSpreadBiffReader.Fixfont in unit xlscommon by adding these lines immediately after the "begin":

function TsSpreadBIFFReader.FixFontIndex(AFontIndex: Integer): Integer;
var
   fnt: TsFont;
begin
   // --- begin insert ---
   if FFontList.Count = 0 then
   begin
     Result := 0;
     exit;
   end;
   // --- end insert ---
   fnt := TsFont(FFontList[AFontIndex]);
   [...]

Reply by email

Malcolm Buckingham
to Werner Pamler

Thanks for the very quick response. I've patched my copy of the file and everything now works. I think I'll stick with this patched version until the next release.

Malcolm

Show quoted text 36 lines
-----Original Message----- From: Lazarus [mailto:] On Behalf Of Werner Pamler via Lazarus Sent: 30 October 2017 13:18 To: Cc: Werner Pamler Subject: Re: [Lazarus] Fpsreadsheet bug? Thanks for sharing the file and for your pre-analysis which helped me to find the bug quickly. It is fixed in fpspreadsheet r6047. If you want to stick to your currently installed version 1.8.4 you must patch the function TsSpreadBiffReader.Fixfont in unit xlscommon by adding these lines immediately after the "begin": function TsSpreadBIFFReader.FixFontIndex(AFontIndex: Integer): Integer; var   fnt: TsFont; begin   // --- begin insert ---   if FFontList.Count = 0 then   begin     Result := 0;     exit;   end;   // --- end insert ---   fnt := TsFont(FFontList[AFontIndex]);   [...] -- _______________________________________________ Lazarus mailing list https://lists.lazarus-ide.org/listinfo/lazarus

Reply by email