From a0aa8807b5fea0a01de1ca553d60e05dacef7cda Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Wed, 5 Jul 2017 22:56:32 +0000 Subject: [PATCH] [Bug 58975] do not cast numberOfOperands to byte in AbstractFunctionPtg git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1800949 13f79535-47bb-0310-9956-ffa450edef68 --- .../MultiOperandNumericFunction.java | 3 +- .../ss/formula/ptg/AbstractFunctionPtg.java | 8 ++- .../formula/ptg/TestAbstractFunctionPtg.java | 60 +++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 src/testcases/org/apache/poi/ss/formula/ptg/TestAbstractFunctionPtg.java diff --git a/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java b/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java index 6e0f364f1..7f07d7e79 100644 --- a/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java +++ b/src/java/org/apache/poi/ss/formula/functions/MultiOperandNumericFunction.java @@ -17,6 +17,7 @@ package org.apache.poi.ss.formula.functions; +import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.formula.ThreeDEval; import org.apache.poi.ss.formula.TwoDEval; import org.apache.poi.ss.formula.eval.BlankEval; @@ -81,7 +82,7 @@ public abstract class MultiOperandNumericFunction implements Function { } } - private static final int DEFAULT_MAX_NUM_OPERANDS = 30; + private static final int DEFAULT_MAX_NUM_OPERANDS = SpreadsheetVersion.EXCEL2007.getMaxFunctionArgs(); public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) { diff --git a/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java b/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java index c3ae44487..1823698cd 100644 --- a/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java +++ b/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java @@ -41,12 +41,16 @@ public abstract class AbstractFunctionPtg extends OperationPtg { private final byte returnClass; private final byte[] paramClass; - private final byte _numberOfArgs; + private final int _numberOfArgs; private final short _functionIndex; protected AbstractFunctionPtg(int functionIndex, int pReturnClass, byte[] paramTypes, int nParams) { - _numberOfArgs = (byte) nParams; + _numberOfArgs = nParams; + if (functionIndex < Short.MIN_VALUE || functionIndex > Short.MAX_VALUE) + throw new RuntimeException("functionIndex " + functionIndex + " cannot be cast to short"); _functionIndex = (short) functionIndex; + if (pReturnClass < Byte.MIN_VALUE || pReturnClass > Byte.MAX_VALUE) + throw new RuntimeException("pReturnClass " + pReturnClass + " cannot be cast to byte"); returnClass = (byte) pReturnClass; paramClass = paramTypes; } diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestAbstractFunctionPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestAbstractFunctionPtg.java new file mode 100644 index 000000000..bf17bca54 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestAbstractFunctionPtg.java @@ -0,0 +1,60 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.ss.formula.ptg; + +import static org.junit.Assert.assertEquals; + +import org.apache.poi.util.LittleEndianOutput; +import org.junit.Test; + +public class TestAbstractFunctionPtg { + + @Test + public void testConstructor() { + FunctionPtg ptg = new FunctionPtg(1, 2, null, 255); + assertEquals(1, ptg.getFunctionIndex()); + assertEquals(2, ptg.getDefaultOperandClass()); + assertEquals(255, ptg.getNumberOfOperands()); + } + + @Test(expected=RuntimeException.class) + public void testInvalidFunctionIndex() { + new FunctionPtg(40000, 2, null, 255); + } + + @Test(expected=RuntimeException.class) + public void testInvalidRuntimeClass() { + new FunctionPtg(1, 300, null, 255); + } + + private static class FunctionPtg extends AbstractFunctionPtg { + + protected FunctionPtg(int functionIndex, int pReturnClass, + byte[] paramTypes, int nParams) { + super(functionIndex, pReturnClass, paramTypes, nParams); + } + + public int getSize() { + return 0; + } + + public void write(LittleEndianOutput out) { + + } + } +}