You've already forked lazarus-ccr
fpspreadsheet: Fix crash when reading a BIFF5 file written by Excel97 (it has data (the directory) beyound the workbook stream which is not expected by the BIFF5/8 readers).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3897 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -67,7 +67,7 @@
|
||||
<Unit1>
|
||||
<Filename Value="main.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="Form1"/>
|
||||
<ComponentName Value="MainForm"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="main"/>
|
||||
|
@ -15,7 +15,7 @@ uses
|
||||
begin
|
||||
RequireDerivedFormResource := True;
|
||||
Application.Initialize;
|
||||
Application.CreateForm(TForm1, Form1);
|
||||
Application.CreateForm(TMainForm, MainForm);
|
||||
Application.Run;
|
||||
end.
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
object Form1: TForm1
|
||||
object MainForm: TMainForm
|
||||
Left = 495
|
||||
Height = 600
|
||||
Top = 132
|
||||
Width = 929
|
||||
Caption = 'Form1'
|
||||
Caption = 'demo_ctrls'
|
||||
ClientHeight = 580
|
||||
ClientWidth = 929
|
||||
Menu = MainMenu
|
||||
|
@ -11,9 +11,9 @@ uses
|
||||
|
||||
type
|
||||
|
||||
{ TForm1 }
|
||||
{ TMainForm }
|
||||
|
||||
TForm1 = class(TForm)
|
||||
TMainForm = class(TForm)
|
||||
AcRowDelete: TAction;
|
||||
AcColDelete: TAction;
|
||||
AcRowAdd: TAction;
|
||||
@ -286,21 +286,22 @@ type
|
||||
procedure InspectorTabControlChange(Sender: TObject);
|
||||
private
|
||||
{ private declarations }
|
||||
procedure UpdateCaption;
|
||||
public
|
||||
{ public declarations }
|
||||
end;
|
||||
|
||||
var
|
||||
Form1: TForm1;
|
||||
MainForm: TMainForm;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
{ TForm1 }
|
||||
{ TMainForm }
|
||||
|
||||
{ Loads the spreadsheet file selected by the AcFileOpen action }
|
||||
procedure TForm1.AcFileOpenAccept(Sender: TObject);
|
||||
procedure TMainForm.AcFileOpenAccept(Sender: TObject);
|
||||
begin
|
||||
WorkbookSource.AutodetectFormat := false;
|
||||
case AcFileOpen.Dialog.FilterIndex of
|
||||
@ -314,10 +315,11 @@ begin
|
||||
8: WorkbookSource.FileFormat := sfCSV; // Text files
|
||||
end;
|
||||
WorkbookSource.FileName := AcFileOpen.Dialog.FileName; // this loads the file
|
||||
UpdateCaption;
|
||||
end;
|
||||
|
||||
{ Saves the spreadsheet to the file selected by the AcFileSaveAs action }
|
||||
procedure TForm1.AcFileSaveAsAccept(Sender: TObject);
|
||||
procedure TMainForm.AcFileSaveAsAccept(Sender: TObject);
|
||||
var
|
||||
fmt: TsSpreadsheetFormat;
|
||||
begin
|
||||
@ -333,20 +335,21 @@ begin
|
||||
7: fmt := sfWikiTable_WikiMedia;
|
||||
end;
|
||||
WorkbookSource.SaveToSpreadsheetFile(AcFileSaveAs.Dialog.FileName, fmt);
|
||||
UpdateCaption;
|
||||
finally
|
||||
Screen.Cursor := crDefault;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Adds a column before the active cell }
|
||||
procedure TForm1.AcColAddExecute(Sender: TObject);
|
||||
procedure TMainForm.AcColAddExecute(Sender: TObject);
|
||||
begin
|
||||
WorksheetGrid.InsertCol(WorksheetGrid.Col);
|
||||
WorksheetGrid.Col := WorksheetGrid.Col + 1;
|
||||
end;
|
||||
|
||||
{ Deletes the column with the active cell }
|
||||
procedure TForm1.AcColDeleteExecute(Sender: TObject);
|
||||
procedure TMainForm.AcColDeleteExecute(Sender: TObject);
|
||||
var
|
||||
c: Integer;
|
||||
begin
|
||||
@ -356,14 +359,14 @@ begin
|
||||
end;
|
||||
|
||||
{ Adds a row before the active cell }
|
||||
procedure TForm1.AcRowAddExecute(Sender: TObject);
|
||||
procedure TMainForm.AcRowAddExecute(Sender: TObject);
|
||||
begin
|
||||
WorksheetGrid.InsertRow(WorksheetGrid.Row);
|
||||
WorksheetGrid.Row := WorksheetGrid.Row + 1;
|
||||
end;
|
||||
|
||||
{ Deletes the row with the active cell }
|
||||
procedure TForm1.AcRowDeleteExecute(Sender: TObject);
|
||||
procedure TMainForm.AcRowDeleteExecute(Sender: TObject);
|
||||
var
|
||||
r: Integer;
|
||||
begin
|
||||
@ -373,17 +376,28 @@ begin
|
||||
end;
|
||||
|
||||
{ Toggles the spreadsheet inspector on and off }
|
||||
procedure TForm1.AcViewInspectorExecute(Sender: TObject);
|
||||
procedure TMainForm.AcViewInspectorExecute(Sender: TObject);
|
||||
begin
|
||||
InspectorTabControl.Visible := AcViewInspector.Checked;
|
||||
end;
|
||||
|
||||
{ Event handler to synchronize the mode of the spreadsheet inspector with the
|
||||
selected tab of the TabControl }
|
||||
procedure TForm1.InspectorTabControlChange(Sender: TObject);
|
||||
procedure TMainForm.InspectorTabControlChange(Sender: TObject);
|
||||
begin
|
||||
Inspector.Mode := TsInspectorMode(InspectorTabControl.TabIndex);
|
||||
end;
|
||||
|
||||
procedure TMainForm.UpdateCaption;
|
||||
begin
|
||||
if WorkbookSource = nil then
|
||||
Caption := 'demo_ctrls'
|
||||
else
|
||||
Caption := Format('demo_ctrls - "%s" [%s]', [
|
||||
WorkbookSource.Filename,
|
||||
GetFileFormatName(WorkbookSource.Workbook.FileFormat)
|
||||
]);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -6399,8 +6399,8 @@ class function TsWorkbook.GetFormatFromFileHeader(const AFileName: TFileName;
|
||||
const
|
||||
BIFF2_HEADER: array[0..15] of byte = (
|
||||
$09,$00, $04,$00, $00,$00, $10,$00, $31,$00, $0A,$00, $C8,$00, $00,$00);
|
||||
BIFF58_HEADER: array[0..15] of byte = (
|
||||
$D0,$CF, $11,$E0, $A1,$B1, $1A,$E1, $00,$00, $00,$00, $00,$00, $00,$00);
|
||||
BIFF58_HEADER: array[0..7] of byte = (
|
||||
$D0,$CF, $11,$E0, $A1,$B1, $1A,$E1);
|
||||
BIFF5_MARKER: array[0..7] of widechar = (
|
||||
'B', 'o', 'o', 'k', #0, #0, #0, #0);
|
||||
BIFF8_MARKER:array[0..7] of widechar = (
|
||||
@ -6419,7 +6419,7 @@ begin
|
||||
// Read first 16 bytes
|
||||
stream.ReadBuffer(buf, 16);
|
||||
|
||||
// Check for Excel 2#
|
||||
// Check for Excel 2
|
||||
ok := true;
|
||||
for i:=0 to 15 do
|
||||
if buf[i] <> BIFF2_HEADER[i] then
|
||||
@ -6434,7 +6434,7 @@ begin
|
||||
end;
|
||||
|
||||
// Check for Excel 5 or 8
|
||||
for i:=0 to 15 do
|
||||
for i:=0 to 7 do
|
||||
if buf[i] <> BIFF58_HEADER[i] then
|
||||
exit;
|
||||
|
||||
|
@ -387,7 +387,6 @@ begin
|
||||
CurStreamPos := AStream.Position;
|
||||
|
||||
case RecordType of
|
||||
|
||||
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
||||
INT_EXCEL_ID_BOOLERROR : ReadBool(AStream);
|
||||
INT_EXCEL_ID_MULBLANK : ReadMulBlank(AStream);
|
||||
@ -720,6 +719,7 @@ end;
|
||||
procedure TsSpreadBIFF5Reader.ReadFromStream(AStream: TStream; AData: TsWorkbook);
|
||||
var
|
||||
BIFF5EOF: Boolean;
|
||||
p,s: Int64;
|
||||
begin
|
||||
{ Initializations }
|
||||
|
||||
@ -742,10 +742,15 @@ begin
|
||||
ReadWorksheet(AStream, AData);
|
||||
|
||||
// Check for the end of the file
|
||||
p := AStream.Position;
|
||||
s := AStream.Size;
|
||||
if AStream.Position >= AStream.Size then BIFF5EOF := True;
|
||||
|
||||
// Final preparations
|
||||
Inc(FCurrentWorksheet);
|
||||
if FCurrentWorksheet = FWorksheetNames.Count then BIFF5EOF := True;
|
||||
// It can happen in files written by Office97 that the OLE directory is
|
||||
// at the end of the file.
|
||||
end;
|
||||
|
||||
if not FPaletteFound then
|
||||
|
@ -638,6 +638,9 @@ begin
|
||||
|
||||
// Final preparations
|
||||
Inc(FCurrentWorksheet);
|
||||
if FCurrentWorksheet = FWorksheetNames.Count then BIFF8EOF := True;
|
||||
// It can happen in files written by Office97 that the OLE directory is
|
||||
// at the end of the file.
|
||||
end;
|
||||
|
||||
if not FPaletteFound then
|
||||
|
Reference in New Issue
Block a user