Permalink
Browse files

Add _.restrict(source, *keys)

Return a clone of the source with only the properties named in *keys
(either stings or arrays containing strings).

Especially useful for avoiding mass-assignment vulnerabilities.
  • Loading branch information...
1 parent 00ed5d7 commit 7c9523784555f10d65f894a66e03f71b71ce96a0 @cleishm committed Mar 24, 2012
Showing with 33 additions and 0 deletions.
  1. +13 −0 index.html
  2. +10 −0 test/objects.js
  3. +10 −0 underscore.js
View
@@ -1016,6 +1016,19 @@ <h2 id="objects">Object Functions</h2>
=&gt; {name : 'moe', age : 50}
</pre>
+ <p id="restrict">
+ <b class="header">restrict</b><code>_.restrict(source, *keys)</code>
+ <br />
+ Return a clone of the <b>source</b> with only the properties with the
+ property names, or arrays of property names, provided in <b>keys</b>.
+ </p>
+ <pre>
+_.restrict({name : 'moe', age: 50, userid : 'moe1'}, 'name', 'age');
+=&gt; {name : 'moe', age : 50}
+_.restrict({name : 'moe', age: 50, userid : 'moe1'}, ['name', 'age']);
+=&gt; {name : 'moe', age : 50}
+</pre>
+
<p id="defaults">
<b class="header">defaults</b><code>_.defaults(object, *defaults)</code>
<br />
View
@@ -41,6 +41,16 @@ $(document).ready(function() {
equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values');
});
+ test("objects: restrict", function() {
+ var result;
+ result = _.restrict({a:1, b:2, c:3}, 'a', 'c');
+ ok(_.isEqual(result, {a:1, c:3}), 'can restrict properties to those named');
+ result = _.restrict({a:1, b:2, c:3}, ['b', 'c']);
+ ok(_.isEqual(result, {b:2, c:3}), 'can restrict properties to those named in an array');
+ result = _.restrict({a:1, b:2, c:3}, ['a'], 'b');
+ ok(_.isEqual(result, {a:1, b:2}), 'can restrict properties to those named in mixed args');
+ });
+
test("objects: defaults", function() {
var result;
var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"};
View
@@ -645,6 +645,16 @@
return obj;
};
+ // Restrict a given object to the properties named
+ _.restrict = function(obj) {
+ if (obj !== Object(obj)) throw new TypeError('Invalid object');
+ var dest = {};
+ each(_.flatten(slice.call(arguments, 1)), function(prop) {
+ if (prop in obj) dest[prop] = obj[prop];
+ });
+ return dest;
+ };
+
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {

0 comments on commit 7c95237

Please sign in to comment.