From b4c0a91af85c5d0a4bd63105e7ed7d8daefeb2d4 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Wed, 14 Oct 2015 14:31:04 +0000 Subject: [PATCH] Bug 58341: fix some edge cases in the DStar function git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1708606 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ss/formula/functions/DStarRunner.java | 142 ++++++++++++------ test-data/spreadsheet/DGet.xls | Bin 39936 -> 51712 bytes 2 files changed, 97 insertions(+), 45 deletions(-) diff --git a/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java b/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java index c5fffbda3a..2fa27c84ae 100644 --- a/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java +++ b/src/java/org/apache/poi/ss/formula/functions/DStarRunner.java @@ -24,6 +24,7 @@ import org.apache.poi.ss.formula.eval.EvaluationException; import org.apache.poi.ss.formula.eval.NotImplementedException; import org.apache.poi.ss.formula.eval.NumericValueEval; import org.apache.poi.ss.formula.eval.RefEval; +import org.apache.poi.ss.formula.eval.StringEval; import org.apache.poi.ss.formula.eval.StringValueEval; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.util.NumberComparer; @@ -234,23 +235,26 @@ public final class DStarRunner implements Function3Arg { targetHeader = solveReference(targetHeader); - if(!(targetHeader instanceof StringValueEval)) - columnCondition = false; - else if (getColumnForName(targetHeader, db) == -1) + if(!(targetHeader instanceof StringValueEval)) { + throw new EvaluationException(ErrorEval.VALUE_INVALID); + } + + if (getColumnForName(targetHeader, db) == -1) // No column found, it's again a special column that accepts formulas. columnCondition = false; if(columnCondition == true) { // normal column condition // Should not throw, checked above. - ValueEval target = db.getValue( + ValueEval value = db.getValue( row, getColumnForName(targetHeader, db)); - // Must be a string. - String conditionString = getStringFromValueEval(condition); - if(!testNormalCondition(target, conditionString)) { + if(!testNormalCondition(value, condition)) { matches = false; break; } } else { // It's a special formula condition. + if(getStringFromValueEval(condition).isEmpty()) { + throw new EvaluationException(ErrorEval.VALUE_INVALID); + } throw new NotImplementedException( "D* function with formula conditions"); } @@ -270,50 +274,83 @@ public final class DStarRunner implements Function3Arg { * @return Whether the condition holds. * @throws EvaluationException If comparison operator and operands don't match. */ - private static boolean testNormalCondition(ValueEval value, String condition) + private static boolean testNormalCondition(ValueEval value, ValueEval condition) throws EvaluationException { - if(condition.startsWith("<")) { // It's a ")) { // It's a >/>= condition. - String number = condition.substring(1); - if(number.startsWith("=")) { - number = number.substring(1); - return testNumericCondition(value, operator.largerEqualThan, number); - } else { - return testNumericCondition(value, operator.largerThan, number); + else if(conditionString.startsWith(">")) { // It's a >/>= condition. + String number = conditionString.substring(1); + if(number.startsWith("=")) { + number = number.substring(1); + return testNumericCondition(value, operator.largerEqualThan, number); + } else { + return testNumericCondition(value, operator.largerThan, number); + } } - } - else if(condition.startsWith("=")) { // It's a = condition. - String stringOrNumber = condition.substring(1); - // Distinguish between string and number. - boolean itsANumber = false; - try { - Integer.parseInt(stringOrNumber); - itsANumber = true; - } catch (NumberFormatException e) { // It's not an int. + else if(conditionString.startsWith("=")) { // It's a = condition. + String stringOrNumber = conditionString.substring(1); + + if(stringOrNumber.isEmpty()) { + return value instanceof BlankEval; + } + // Distinguish between string and number. + boolean itsANumber = false; try { - Double.parseDouble(stringOrNumber); + Integer.parseInt(stringOrNumber); itsANumber = true; - } catch (NumberFormatException e2) { // It's a string. - itsANumber = false; + } catch (NumberFormatException e) { // It's not an int. + try { + Double.parseDouble(stringOrNumber); + itsANumber = true; + } catch (NumberFormatException e2) { // It's a string. + itsANumber = false; + } + } + if(itsANumber) { + return testNumericCondition(value, operator.equal, stringOrNumber); + } else { // It's a string. + String valueString = value instanceof BlankEval ? "" : getStringFromValueEval(value); + return stringOrNumber.equals(valueString); + } + } else { // It's a text starts-with condition. + if(conditionString.isEmpty()) { + return value instanceof StringEval; + } + else { + String valueString = value instanceof BlankEval ? "" : getStringFromValueEval(value); + return valueString.startsWith(conditionString); } } - if(itsANumber) { - return testNumericCondition(value, operator.equal, stringOrNumber); - } else { // It's a string. - String valueString = getStringFromValueEval(value); - return stringOrNumber.equals(valueString); + } + else if(condition instanceof NumericValueEval) { + double conditionNumber = ((NumericValueEval)condition).getNumberValue(); + Double valueNumber = getNumerFromValueEval(value); + if(valueNumber == null) { + return false; + } + + return conditionNumber == valueNumber; + } + else if(condition instanceof ErrorEval) { + if(value instanceof ErrorEval) { + return ((ErrorEval)condition).getErrorCode() == ((ErrorEval)value).getErrorCode(); + } + else { + return false; } - } else { // It's a text starts-with condition. - String valueString = getStringFromValueEval(value); - return valueString.startsWith(condition); + } + else { + return false; } } @@ -361,6 +398,23 @@ public final class DStarRunner implements Function3Arg { } return false; // Can not be reached. } + + private static Double getNumerFromValueEval(ValueEval value) { + if(value instanceof NumericValueEval) { + return ((NumericValueEval)value).getNumberValue(); + } + else if(value instanceof StringValueEval) { + String stringValue = ((StringValueEval)value).getStringValue(); + try { + return Double.parseDouble(stringValue); + } catch (NumberFormatException e2) { + return null; + } + } + else { + return null; + } + } /** * Takes a ValueEval and tries to retrieve a String value from it. @@ -373,8 +427,6 @@ public final class DStarRunner implements Function3Arg { private static String getStringFromValueEval(ValueEval value) throws EvaluationException { value = solveReference(value); - if(value instanceof BlankEval) - return ""; if(!(value instanceof StringValueEval)) throw new EvaluationException(ErrorEval.VALUE_INVALID); return ((StringValueEval)value).getStringValue(); diff --git a/test-data/spreadsheet/DGet.xls b/test-data/spreadsheet/DGet.xls index e576d73a0327a5e5574f07e272ac0480f14d5586..860158611e34a6b4e636974291545282b12c5465 100644 GIT binary patch literal 51712 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 G^#21<@eBe0 delta 6082 zcmai2d2pM>6@UAEk}S)|CtGqX$Flt?&gEOOS2Nr zhy-ag;ShuKut!%Gn#PN|5>H|B z9iAk%8rs1Nz0d)EYV&n&&_gyb95h<7&zP?_fIUo=CeO#q#&kIe^3a@|kNw7Uylyh# zmSm&69*mft+#(l4H8z>7#Am`I$vapPzLV@@rPyFPDVM+sn#)I1ifQT}CaZ3F66yJ$ zpbGF%M#gIeuN8pq`|3@wf^pXPBPoxh%#7=yD8&B-mYNsi`(_(Ht2oViC{M zDg?)Pff?r)q~i|@YV3Gpvh!gobyu6@HUnkZ( zo12fRh5v3u$pU6b2dH$ai_|i;sc%H{1zeNH%`iF3TBgenrb8t-L4`&1Eu(J}^uY*j zEw$jplAL-AWW>N!#=KG^ zi1GvwIYnHHtQd&uScu955aR-39*6LJLsSX~!jm8>UlsAFWXHh7iArGtm`%mp7+VZP zoTw~G0P&)L$ccf76P1z#5cU$T#rznEI8muc0C7S<Td7QCXI)qSCp~@_b?1WH=V#8 zpy7Y3+mpW>t%1`jM{%)n4h3DvfD?nL-=WpXH^y* zBxWwy=e_0Ed|jGf-Ju-{Od6Y`0i>#+Spf9W#pRapgAcm6M^NWpu*eAIAOkcHljO2! zNj5(yLo@j+fScS4D|ApXE|a&^XfC}>)@*7@Y8D_kyp4@HFFVTi=~{I z2odl16gOl-?OY5`Of`@#2{A5v>@8WajOY3;&EMynKCmyKsk=3=m&(M>Xg^Cf%Jp5s z%Y783X*j@rOtcESsrAxF!*f-ODbJRV>*C~@j`FOPc1aJ#Nz{pOp6Ou4coOl?trSTV z*J%FeN@0POyh^vW`+c*w=%P7kDy2}FZWTG@BRyyK=bl=16G~Z7$Bh>jtJ9Qa2mI6f zG~cB0yK{`sCgbmzNhVK+6Yc;RGfj>lV0_HA8;{iP%eu0jTb2adwDvA_qjrkw(XU(Z z^V)jZ1um>vwm<2)l&i#X|I{532I!$*TQdFb`>O%qDSAIhb+m06Km+aK(dD#W zGQh+NfFUaDdsYI}r%at`c|O(f$GZWxwP54D#f;(Ewn4mc?+(QTN5#SbFZC&4nA*Ji z3}XhozQ=2`(Ym3hhF&+f0$l6{xNA6sFm<-=6m!*3Nnb}*w2F$ypw2_;r=c3*! z8g&!RdoJ2n)tsJczAr^)CfwfMoHGylQxy6EN{>X|p@%O7Fn?;Q{Y7aR{~-nNHJwfj z44_auLnRSK1vflrB#H`7m`Vl(pX{m`Qz&`>uhN}f64C&+MnW84*O(+YCGxsLvjBR@ zNIWDL#*nGpD&QdMm}H`L_}T#WMy`oW@mA;{3#}##3=2^lL!O19!&WWBt-u1B<2vZV zC~70up*gIBPRR40eOzA07dlkf+2HfQD&lOPlzy^=y&04 zDw7;D-Q&ws$nX$Hicp@LYJglig-Cfk-Md7YZG0B}+3;#_Zl^*HnvvqF^Q`4*kwPCu z?4uCHRi}Crp5vWr}zJcvE{ha z>tIF^frq^XcG}z|P)Yd_9U~VQZ=++(f**Lx*VGNPvIAAr?>taJEgsTe&8TmgFktopRJwBIfyLF0;PN-0WeBt$xJmCz=E$IveeC; zp+kfIn26@~#2Kp+2pNYh%z}S9tg&_2FmjMJLF-Vh_fu~Tdto*MVE?f9?pfw3Lo6`f-JnTq2S zn;=5Xu1!vn_A`aUDYkTkb9Vi4lAe)*;}j((!pXB&#+%>HW=`6%^D*V;RfBVD|I%PxU$4>Qx@4^Uv6|kTIvSp}q zS0+gYe&SM(ufZ#if)yvLSmorgd3fYxIopNLp4^;!uUMp#4*I!;DH9#TR$O|@Y3J7) zo*32iR$w8u?-JlP(&7?B-SvDDQh JE^0fy{trk1fEfS) -- 2.39.5