fpspreadsheet: Fix range overflow if formula contains integers > 65535

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4619 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-04-13 10:03:47 +00:00
parent 68466d4ade
commit 2a25a3e64c
4 changed files with 19 additions and 14 deletions

View File

@ -1601,12 +1601,10 @@ begin
if TryStrToInt64(CurrentToken, I) then
Result := TsConstExprNode.CreateInteger(self, I)
else
begin
if TryStrToFloat(CurrentToken, X, FFormatSettings) then
Result := TsConstExprNode.CreateFloat(self, X)
else
ParserError(Format(rsInvalidFloat, [CurrentToken]));
end;
if TryStrToFloat(CurrentToken, X, FFormatSettings) then
Result := TsConstExprNode.CreateFloat(self, X)
else
ParserError(Format(rsInvalidFloat, [CurrentToken]));
end
else if (TokenType = ttTrue) then
Result := TsConstExprNode.CreateBoolean(self, true)

View File

@ -56,7 +56,7 @@ function RPNCellRef3D(ASheet, ARow, ACol: Integer; AFlags: TsRelFlags;
function RPNCellRange3D(ASheet1, ARow1, ACol1, ASheet2, ARow2, ACol2: Integer;
AFlags: TsRelFlags; ANext: PRPNItem): PRPNItem;
function RPNErr(AErrCode: TsErrorValue; ANext: PRPNItem): PRPNItem;
function RPNInteger(AValue: Word; ANext: PRPNItem): PRPNItem;
function RPNInteger(AValue: Int64; ANext: PRPNItem): PRPNItem;
function RPNMissingArg(ANext: PRPNItem): PRPNItem;
function RPNNumber(AValue: Double; ANext: PRPNItem): PRPNItem;
function RPNParenthesis(ANext: PRPNItem): PRPNItem;
@ -299,12 +299,12 @@ begin
end;
{@@ ----------------------------------------------------------------------------
Creates an entry in the RPN array for a 2-byte unsigned integer
Creates an entry in the RPN array for an integer value
@param AValue Integer value to be inserted into the formula
@param ANext Pointer to the next RPN item in the list
-------------------------------------------------------------------------------}
function RPNInteger(AValue: Word; ANext: PRPNItem): PRPNItem;
function RPNInteger(AValue: Int64; ANext: PRPNItem): PRPNItem;
begin
Result := NewRPNItem;
Result^.FE.ElementKind := fekInteger;

View File

@ -202,7 +202,7 @@ type
Sheet, Sheet2: Integer; // zero-based
SheetNames: String; // both sheet names separated by a TAB character (intermediate use only)
DoubleValue: double;
IntValue: Word;
IntValue: Int64;
StringValue: String;
RelFlags: TsRelFlags; // info on relative/absolute addresses
FuncName: String;

View File

@ -585,10 +585,6 @@ type
const AFormula: TsRPNFormula; ACell: PCell); virtual;
function WriteRPNFunc(AStream: TStream; AIdentifier: Word): Word; virtual;
procedure WriteRPNResult(AStream: TStream; ACell: PCell);
{
procedure WriteRPNSharedFormulaLink(AStream: TStream; ACell: PCell;
var RPNLength: Word); virtual;
}
procedure WriteRPNTokenArray(AStream: TStream; ACell: PCell;
const AFormula: TsRPNFormula; UseRelAddr, IsSupported: Boolean; var RPNLength: Word);
procedure WriteRPNTokenArraySize(AStream: TStream; ASize: Word); virtual;
@ -4110,6 +4106,17 @@ begin
INT_EXCEL_TOKEN_TAREA_A : primaryExcelCode := INT_EXCEL_TOKEN_TAREAN_A;
end;
// Excel BIFF uses only 2-byte integers.
// --> Convert larger values to float.
// Note: only positive values have to be considered because negative values
// have an additional unary minus token.
if (primaryExcelCode = INT_EXCEL_TOKEN_TINT) and
(AFormula[i].IntValue > word($FFFF)) then
begin
primaryExcelCode := INT_EXCEL_TOKEN_TNUM;
AFormula[i].DoubleValue := 1.0*AFormula[i].IntValue;
end;
AStream.WriteByte(primaryExcelCode);
inc(RPNLength);