jsawk icon indicating copy to clipboard operation
jsawk copied to clipboard

bug in forEach usage of eval()

Open anvidal opened this issue 12 years ago • 3 comments

forEach suffers from the same bug that was mentioned and closed in #4 :

line 1167:

  window.forEach = function(ary, funct) {
    fun = eval("function(index,item) { "+funct+"; }");
    for (var i=0; i<ary.length; i++) {
      try {
        fun.call(ary[i], i, ary[i]);
      } catch (e) {
        err("jsawk: js error: "+e);
        quit(3);
      }
    }
  };

replacing the eval() with

fun = eval("(function(index,item) { "+funct+"; })");

fixes the issue by wrapping the anonymous function creation in parentheses. I haven't reviewed other usages of eval() but it may be worth taking a look.

anvidal avatar Nov 09 '13 03:11 anvidal

@anvidal Thanks, I'll look into it.

micha avatar Nov 09 '13 15:11 micha

Am I doing something wrong or is forEach broken?

Using jsawk from 7da2143505e7bc34ca5f3639cda4fa4d79cec997:

$ curl -s http://example.com/json | ./jsawk 'forEach(this, "out(item.count)") ; return'
jsawk: js error: SyntaxError: syntax error

Using 7da2143505e7bc34ca5f3639cda4fa4d79cec997 + the suggested change:

$ git diff
diff --git a/jsawk b/jsawk
index 28aaccd..45aae4c 100755
--- a/jsawk
+++ b/jsawk
@@ -1165,7 +1165,7 @@ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
     IS = IS.slice(0, $_+1).concat([record]).concat(IS.slice($_+1));
   };
   window.forEach = function(ary, fun) {
-    fun = eval("function(index,item) { "+fun+"; }");
+    fun = eval("(function(index,item) { "+funct+"; })");
     for (var i=0; i<ary.length; i++) {
       try {
         fun.call(ary[i], i, ary[i]);
$ curl -s http://example.com/json | ./jsawk 'forEach(this, "out(item.count)") ; return'
jsawk: js error: ReferenceError: funct is not defined

This is the JSON from http://example.com/json:

[{"time":1356998400000,"count":1257},{"time":1359676800000,"count":4007},{"time":1362096000000,"count":3807},{"time":1364774400000,"count":3813},{"time":1367366400000,"count":4450},{"time":1370044800000,"count":4284},{"time":1372636800000,"count":3885},{"time":1375315200000,"count":3925},{"time":1377993600000,"count":3369},{"time":1380585600000,"count":3315},{"time":1383264000000,"count":3790},{"time":1385856000000,"count":4625}]

dentarg avatar Jan 24 '14 22:01 dentarg

Oh, never mind me. I didn't read the docs carefully enough.

Also found a good comment about it elsewhere:

If the outermost element of your JSON data is an array, then jsawk automatically loops over each element.

dentarg avatar Jan 24 '14 22:01 dentarg