spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[ALL] Criteria evaluations accept dollar-to-number comparisons, eg '>=-0'
author
Ben Vogt <[email protected]>
date
2017-04-02 19:45:27
stats
3 file(s) changed, 13 insertions(+), 17 deletions(-)
files
README.md
src/RawFormulas/Utils.ts
tests/FormulasTest.ts
 1diff --git a/README.md b/README.md
 2index 8d52f4a..75c9673 100644
 3--- a/README.md
 4+++ b/README.md
 5@@ -7,16 +7,8 @@ Things I should do.
 6 ### SUM and SUMA should be different, and I'm pretty sure they're currently the same.
 7 And the same for MAX, MAXA, COUNT, COUNTA, etc. Look these over.
 8 
 9-### Protect against injection
10-How do we protect against users injecting data that looks like `console.log(sensitive_data)` when we evaluate variables
11-inside parser.js? If we ever want to impliment custom formulas, or even accept data in raw format, we need to guard
12-against this. Or else someone could load a CSV with javascript and when our spreadsheet opens it, then suddenly
13-arbitrary javascript is executed in the client machine.
14-
15 ### Criteria evaluations should escape reg-ex characters: http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
16 
17-### Criteria evaluations should accept dollar-to-number comparisons: `=COUNTIF({10, 20, 40}, ">=$20")`
18-
19 ### License for all code used.
20 
21 ### Document the functions pulled in from jStat.
22diff --git a/src/RawFormulas/Utils.ts b/src/RawFormulas/Utils.ts
23index 18f8037..51712a4 100644
24--- a/src/RawFormulas/Utils.ts
25+++ b/src/RawFormulas/Utils.ts
26@@ -294,20 +294,19 @@ class CriteriaFunctionFactory {
27         return x === criteria;
28       };
29     } else if (typeof criteria === "string") {
30-      // https://regex101.com/r/c2hxAZ/6
31-      var comparisonMatches = criteria.match(/(^<=|^>=|^=|^<>|^>|^<)\s*(-?[0-9]+([,.][0-9]+)?)\s*$/);
32-      if (comparisonMatches !== null && comparisonMatches.length >= 4 && comparisonMatches[2] !== undefined) {
33+      var comparisonMatches = criteria.match(/^\s*(<=|>=|=|<>|>|<)\s*(-)?\s*(\$)?\s*([0-9]+([,.][0-9]+)?)\s*$/);
34+      if (comparisonMatches !== null && comparisonMatches.length >= 6 && comparisonMatches[4] !== undefined) {
35         criteriaEvaluation = function (x) : boolean {
36-          return eval(x + criteria);
37+          return eval(x + comparisonMatches[1] + (comparisonMatches[2] === undefined ? "" : "-") +  comparisonMatches[4]);
38         };
39         if (comparisonMatches[1] === "=") {
40           criteriaEvaluation = function (x) : boolean {
41-            return eval(x + "===" + comparisonMatches[2]);
42+            return eval(x + "===" + (comparisonMatches[2] === undefined ? "" : "-") +  comparisonMatches[4]);
43           };
44         }
45         if (comparisonMatches[1] === "<>") {
46           criteriaEvaluation = function (x) : boolean {
47-            return eval(x + "!==" + comparisonMatches[2]);
48+            return eval(x + "!==" + (comparisonMatches[2] === undefined ? "" : "-") +  comparisonMatches[4]);
49           };
50         }
51       } else if (criteria.match(/\*|\~\*|\?|\~\?/) !== null) {
52diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
53index d49c1d6..6c65bf3 100644
54--- a/tests/FormulasTest.ts
55+++ b/tests/FormulasTest.ts
56@@ -643,6 +643,13 @@ assertEquals(COUNTIF(["mom", "pop", "dad", "etc", "mom"], "?o?"), 3);
57 assertEquals(COUNTIF(["mom", "pop", "dad", "etc", "mom"], "???"), 5);
58 assertEquals(COUNTIF(["mom", "pop", "dad", "etc", "mom"], "????"), 0);
59 assertEquals(COUNTIF(["mom", "pop", "dad", "etc", "mom"], "?"), 0);
60+// dollar sign and negative values
61+assertEquals(COUNTIF([1, 5, 5, 5, 10, 5], "=$5"), 4);
62+assertEquals(COUNTIF([1, -5, -5, -5, 10, -5], "=-$5"), 4);
63+assertEquals(COUNTIF([1, -5, -5, -5, 10, -5], "=-5"), 4);
64+assertEquals(COUNTIF([1, 5, 5, 5, 10, 5], ">$5"), 1);
65+assertEquals(COUNTIF([1, 5, 5, 5, 10, 5], "=$10"), 1);
66+assertEquals(COUNTIF([1, 5, 5, 5, 10, 5], "=  $ 10"), 1);
67 catchAndAssertEquals(function() {
68   COUNTIF([0, 1, 0, 1]);
69 }, ERRORS.NA_ERROR);