Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between angular.fromJson and $scope.$eval when applied to JSON string

Tags:

In my angularjs apps, I usually parse a JSON string by using angular.fromJson, like so:

var myObject=angular.fromJSON(jsonString); 

However, it seems that I would obtain the same result by using $scope.$eval:

var myObject=$scope.$eval(jsonString); 

See this fiddle

Or by using vanilla javaScript, like so:

var myObject=JSON.parse(jsonString); 
  • Is there any particular reason to use angular.fromJSON rather than JSON.parse?

  • Is there any possible issue when using $scope.$eval to parse a JSON string?

like image 644
Manube Avatar asked Mar 24 '15 22:03

Manube


People also ask

What does eval () method do in JSON?

The eval() function in JavaScript is used to take an expression and return the string. As a result, it can be used to convert the string into JSON.

Why JSON eval is not recommended for use?

Malicious code : invoking eval can crash a computer. For example: if you use eval server-side and a mischievous user decides to use an infinite loop as their username. Terribly slow : the JavaScript language is designed to use the full gamut of JavaScript types (numbers, functions, objects, etc)… Not just strings!

Does JSON parse use eval?

JSON is derived from JavaScript and its syntax is mostly a subset of the language, it is often possible to use the JavaScript eval() function to parse JSON data.


2 Answers

Check out the source code:

function fromJson(json) {   return isString(json)       ? JSON.parse(json)       : json; } 

They're just passing through to JSON.parse.

As for $eval it shells out to $parse:

  // $scope.$eval source:   $eval: function(expr, locals) {     return $parse(expr)(this, locals);   }, 

$parse source is too long to post, but it is essentially capable of converting inline (stringified) objects to real Objects and so it makes sense that in this case, it will actually convert your JSON as well.

(I did not know this until reading through the $parse source just now.)

Is there any particular reason to use angular.fromJSON rather than JSON.parse?

Nope, not really. Although they do check to you to ensure that you don't double-parse a JSON string, like so:

var jsonString = '{"foo":"bar"}'; var json = JSON.parse(jsonString); // Parsing once is good :) JSON.parse(json); // Parsing twice is bad :( 

Is there any possible issue when using $scope.$eval to parse a JSON string?

I don't think so off the top of my head, other than that you're doing more work than is necessary. So if you know you have JSON, there's no reason to use the heavier $parse function.

like image 165
bvaughn Avatar answered Nov 03 '22 09:11

bvaughn


The above answer is almost correct. However, there is a potential issue with using $scope.$eval() to parse a JSON string, which does not exist with either JSON.parse() or angular.fromJson(): security. Angular allows an expression to contain complex JavaScript including function calls, conditionals with ?:, variable assignments, and so on. All of these are recognised and processed if you use $scope.$eval(), even if they were added by a malicious end-user.

JSON does not support any of those more complex JavaScript features, nor anything else potentially "dangerous". If you use a true JSON parser like JSON.parse() or angular.fromJson(), there is no chance of malicious code being injected and executed.

Since Angular expressions are isolated and evaluate only in the current $scope, the risk of code injection is somewhat mitigated - $scope.$eval() is far less dangerous than JavaScript's native eval() for parsing JSON. However there is still no reason to use either function for this purpose, since there is a potential security risk and using a proper JSON parser is likely to be faster.

like image 26
00dani Avatar answered Nov 03 '22 08:11

00dani