You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ce...@apache.org on 2019/12/31 16:52:55 UTC
svn commit: r1872145 - in /poi/trunk:
src/java/org/apache/poi/ss/formula/functions/
src/testcases/org/apache/poi/hssf/usermodel/
src/testcases/org/apache/poi/ss/formula/functions/ test-data/spreadsheet/
Author: centic
Date: Tue Dec 31 16:52:55 2019
New Revision: 1872145
URL: http://svn.apache.org/viewvc?rev=1872145&view=rev
Log:
Bug 63940: Avoid endless loop/out of memory on string-replace with empty search string
Added:
poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestSubstitute.java
poi/trunk/test-data/spreadsheet/SUBSTITUTE.xls
Modified:
poi/trunk/src/java/org/apache/poi/ss/formula/functions/Substitute.java
poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
Modified: poi/trunk/src/java/org/apache/poi/ss/formula/functions/Substitute.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/functions/Substitute.java?rev=1872145&r1=1872144&r2=1872145&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/functions/Substitute.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/functions/Substitute.java Tue Dec 31 16:52:55 2019
@@ -64,11 +64,15 @@ public final class Substitute extends Va
}
private static String replaceAllOccurrences(String oldStr, String searchStr, String newStr) {
+ // avoid endless loop when searching for nothing
+ if (searchStr.length() < 1) {
+ return oldStr;
+ }
+
StringBuilder sb = new StringBuilder();
int startIndex = 0;
- int nextMatch;
while (true) {
- nextMatch = oldStr.indexOf(searchStr, startIndex);
+ int nextMatch = oldStr.indexOf(searchStr, startIndex);
if (nextMatch < 0) {
// store everything from end of last match to end of string
sb.append(oldStr.substring(startIndex));
@@ -82,25 +86,23 @@ public final class Substitute extends Va
}
private static String replaceOneOccurrence(String oldStr, String searchStr, String newStr, int instanceNumber) {
+ // avoid endless loop when searching for nothing
if (searchStr.length() < 1) {
return oldStr;
}
int startIndex = 0;
- int nextMatch = -1;
int count=0;
while (true) {
- nextMatch = oldStr.indexOf(searchStr, startIndex);
+ int nextMatch = oldStr.indexOf(searchStr, startIndex);
if (nextMatch < 0) {
// not enough occurrences found - leave unchanged
return oldStr;
}
count++;
if (count == instanceNumber) {
- StringBuilder sb = new StringBuilder(oldStr.length() + newStr.length());
- sb.append(oldStr, 0, nextMatch);
- sb.append(newStr);
- sb.append(oldStr.substring(nextMatch + searchStr.length()));
- return sb.toString();
+ return oldStr.substring(0, nextMatch) +
+ newStr +
+ oldStr.substring(nextMatch + searchStr.length());
}
startIndex = nextMatch + searchStr.length();
}
Modified: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java?rev=1872145&r1=1872144&r2=1872145&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java Tue Dec 31 16:52:55 2019
@@ -2879,7 +2879,7 @@ public final class TestBugs extends Base
FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
eval.evaluateAll();
-
+
/*OutputStream out = new FileOutputStream("C:\\temp\\48043.xls");
try {
wb.write(out);
@@ -3119,20 +3119,25 @@ public final class TestBugs extends Base
@Test
public void test60460() throws IOException {
- final Workbook wb = HSSFTestDataSamples.openSampleWorkbook("60460.xls");
-
- assertEquals(2, wb.getAllNames().size());
+ try (final Workbook wb = HSSFTestDataSamples.openSampleWorkbook("60460.xls")) {
+ assertEquals(2, wb.getAllNames().size());
- Name rangedName = wb.getAllNames().get(0);
- assertFalse(rangedName.isFunctionName());
- assertEquals("'[\\\\HEPPC3\\gt$\\Teaching\\Syn\\physyn.xls]#REF'!$AK$70:$AL$70",
- // replace '/' to make test work equally on Windows and Linux
- rangedName.getRefersToFormula().replace("/", "\\"));
-
- rangedName = wb.getAllNames().get(1);
- assertFalse(rangedName.isFunctionName());
- assertEquals("Questionnaire!$A$1:$L$65", rangedName.getRefersToFormula());
+ Name rangedName = wb.getAllNames().get(0);
+ assertFalse(rangedName.isFunctionName());
+ assertEquals("'[\\\\HEPPC3\\gt$\\Teaching\\Syn\\physyn.xls]#REF'!$AK$70:$AL$70",
+ // replace '/' to make test work equally on Windows and Linux
+ rangedName.getRefersToFormula().replace("/", "\\"));
+
+ rangedName = wb.getAllNames().get(1);
+ assertFalse(rangedName.isFunctionName());
+ assertEquals("Questionnaire!$A$1:$L$65", rangedName.getRefersToFormula());
+ }
+ }
- wb.close();
+ @Test
+ public void test63940() throws IOException {
+ try (final Workbook wb = HSSFTestDataSamples.openSampleWorkbook("SUBSTITUTE.xls")) {
+ wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
+ }
}
}
Added: poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestSubstitute.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestSubstitute.java?rev=1872145&view=auto
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestSubstitute.java (added)
+++ poi/trunk/src/testcases/org/apache/poi/ss/formula/functions/TestSubstitute.java Tue Dec 31 16:52:55 2019
@@ -0,0 +1,89 @@
+/* ====================================================================
+ 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.functions;
+
+import org.apache.poi.ss.formula.eval.ErrorEval;
+import org.apache.poi.ss.formula.eval.NumberEval;
+import org.apache.poi.ss.formula.eval.StringEval;
+import org.apache.poi.ss.formula.eval.StringValueEval;
+import org.apache.poi.ss.usermodel.FormulaError;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestSubstitute {
+ @Test
+ public void testSubstitute() {
+ Substitute fun = new Substitute();
+ assertEquals("ADEFC", ((StringValueEval)fun.evaluate(0, 1,
+ new StringEval("ABC"), new StringEval("B"), new StringEval("DEF"))).getStringValue());
+
+ assertEquals("ACDEC", ((StringValueEval)fun.evaluate(0, 1,
+ new StringEval("ABC"), new StringEval("B"), new StringEval("CDE"))).getStringValue());
+
+ assertEquals("ACDECCDEA", ((StringValueEval)fun.evaluate(0, 1,
+ new StringEval("ABCBA"), new StringEval("B"), new StringEval("CDE"))).getStringValue());
+ }
+
+ @Test
+ public void testSubstituteInvalidArg() {
+ Substitute fun = new Substitute();
+ assertEquals(ErrorEval.valueOf(FormulaError.VALUE.getLongCode()),
+ fun.evaluate(0, 1,
+ ErrorEval.valueOf(FormulaError.VALUE.getLongCode()), new StringEval("B"), new StringEval("DEF")));
+
+ assertEquals(ErrorEval.valueOf(FormulaError.VALUE.getLongCode()),
+ fun.evaluate(0, 1,
+ ErrorEval.valueOf(FormulaError.VALUE.getLongCode()), new StringEval("B"), new StringEval("DEF"),
+ new NumberEval(1)));
+
+ // fails on occurrence below 1
+ assertEquals(ErrorEval.valueOf(FormulaError.VALUE.getLongCode()),
+ fun.evaluate(0, 1,
+ new StringEval("ABC"), new StringEval("B"), new StringEval("CDE"), new NumberEval(0)));
+ }
+
+ @Test
+ public void testSubstituteOne() {
+ Substitute fun = new Substitute();
+ assertEquals("ADEFC", ((StringValueEval)fun.evaluate(0, 1,
+ new StringEval("ABC"), new StringEval("B"), new StringEval("DEF"), new NumberEval(1))).getStringValue());
+
+ assertEquals("ACDEC", ((StringValueEval)fun.evaluate(0, 1,
+ new StringEval("ABC"), new StringEval("B"), new StringEval("CDE"), new NumberEval(1))).getStringValue());
+ }
+
+ @Test
+ public void testSubstituteNotFound() {
+ Substitute fun = new Substitute();
+ assertEquals("ABC", ((StringValueEval)fun.evaluate(0, 1,
+ new StringEval("ABC"), new StringEval("B"), new StringEval("DEF"), new NumberEval(12))).getStringValue());
+
+ assertEquals("ABC", ((StringValueEval)fun.evaluate(0, 1,
+ new StringEval("ABC"), new StringEval("B"), new StringEval("CDE"), new NumberEval(2))).getStringValue());
+ }
+
+ @Test
+ public void testSearchEmpty() {
+ Substitute fun = new Substitute();
+ assertEquals("ABC", ((StringValueEval)fun.evaluate(0, 1,
+ new StringEval("ABC"), new StringEval(""), new StringEval("CDE"))).getStringValue());
+ assertEquals("ABC", ((StringValueEval)fun.evaluate(0, 1,
+ new StringEval("ABC"), new StringEval(""), new StringEval("CDE"), new NumberEval(1))).getStringValue());
+ }
+}
\ No newline at end of file
Added: poi/trunk/test-data/spreadsheet/SUBSTITUTE.xls
URL: http://svn.apache.org/viewvc/poi/trunk/test-data/spreadsheet/SUBSTITUTE.xls?rev=1872145&view=auto
==============================================================================
Binary files poi/trunk/test-data/spreadsheet/SUBSTITUTE.xls (added) and poi/trunk/test-data/spreadsheet/SUBSTITUTE.xls Tue Dec 31 16:52:55 2019 differ
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org