Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

buffer: change output of Buffer.prototype.toJSON()

Expand the JSON representation of Buffer to include type information
so that it can be deserialized in JSON.parse() without context.

Fixes #5110.
Fixes #5143.
  • Loading branch information...
commit 840a29fc0fd256a63b3f2f5e7528de5107a608a3 1 parent 9b8dd39
David Braun authored TooTallNate committed
View
13 doc/api/buffer.markdown
@@ -114,9 +114,8 @@ See `buffer.write()` example, above.
### buf.toJSON()
-Returns a JSON-representation of the Buffer instance, which is identical to the
-output for JSON Arrays. `JSON.stringify` implicitly calls this function when
-stringifying a Buffer instance.
+Returns a JSON-representation of the Buffer instance. `JSON.stringify`
+implicitly calls this function when stringifying a Buffer instance.
Example:
@@ -124,9 +123,13 @@ Example:
var json = JSON.stringify(buf);
console.log(json);
- // '[116,101,115,116]'
+ // '{"type":"Buffer","data":[116,101,115,116]}'
- var copy = new Buffer(JSON.parse(json));
+ var copy = JSON.parse(json, function(key, value) {
+ return value && value.type === 'Buffer'
+ ? new Buffer(value.data)
+ : value;
+ });
console.log(copy);
// <Buffer 74 65 73 74>
View
5 lib/buffer.js
@@ -379,7 +379,10 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
Buffer.prototype.toJSON = function() {
- return Array.prototype.slice.call(this, 0);
+ return {
+ type: 'Buffer',
+ data: Array.prototype.slice.call(this, 0)
+ };
};
View
15 test/simple/test-buffer.js
@@ -833,8 +833,19 @@ Buffer(Buffer(0), 0, 0);
});
-// GH-3905
-assert.equal(JSON.stringify(Buffer('test')), '[116,101,115,116]');
+// GH-5110
+(function () {
+ var buffer = new Buffer('test'),
+ string = JSON.stringify(buffer);
+
+ assert.equal(string, '{"type":"Buffer","data":[116,101,115,116]}');
+
+ assert.deepEqual(buffer, JSON.parse(string, function(key, value) {
+ return value && value.type === 'Buffer'
+ ? new Buffer(value.data)
+ : value;
+ }));
+})();
// issue GH-4331
assert.throws(function() {

3 comments on commit 840a29f

@q2dg

Ei, the example code of buf.toJSON() in official doc (http://nodejs.org/docs/v0.11.13/api/buffer.html#buffer_buf_tojson) doesn't use buf.toJSON()!!!!!!!!!!

If I replace this line: var json = JSON.stringify(buf) by this line: var json=buf.toJSON(), running that example I get this output (node v0.11.13, Fedora 20):

{ type: 'Buffer', data: [ 116, 101, 115, 116 ] }
undefined:1
[object Object]
^
SyntaxError: Unexpected token o
at Object.parse (native)
at Object. (/home/q2dg/borrar:9:17)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:349:32)
at Function.Module._load (module.js:305:12)
at Function.Module.runMain (module.js:490:10)
at startup (node.js:124:16)
at node.js:807:3

instead of the expected:

{"type":"Buffer","data":[116,101,115,116]}

@cjihrig
Owner

@q2dg - it might be helpful to have an example that actually calls toJSON(), but this function is typically called internally by JSON.stringify(). Taken from MDN:

If an object being stringified has a property named toJSON whose value is a function, then the toJSON method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the toJSON method when called will be serialized.

In this particular case, toJSON() returns an object, not a string. So it makes sense that JSON.parse() would throw.

@q2dg

@cjihrig Ooh, I see!! Thanks a lot!!

Please sign in to comment.
Something went wrong with that request. Please try again.