Search code examples
javascriptnode.jsjsonbuffercryptojs

NodeJS - How to retrieve original data from a Buffer after use JSON.parse(JSON.stringify())


I am working with crypto library to send a POST request to update some data and for some reason I get as if I used JSON.parse(JSON.stringify(myBufferData)) to a Buffer data. I want to recover the original data.

How you can replicate my situation:

var buf = Buffer.from('abc');
var parsedBuf = JSON.parse(JSON.stringify(buf)); -> I faced with this result at some point.

buf.toString() -> Give the expected result ('abc').
parsedBuf.toString() -> Doesn't retrieve original data ('[object Object]').

How can I retrieve the original data from parsedBuf ?


Solution

  • Solution

    Use Buffer(parsedBuf).toString() instead of parsedBuf.toString() to retrieve original data.


    Explanation

    Checking the Buffer docs, I found out that its toString method is not Javascript's built-in. You can simply check it's source wherever you want by calling buf.[method].toString(). In this case:

    • buf.toString.toString()

    • JSON.parse(JSON.stringify(buf)).toString.toString()

    So it revealed me somehow their source code:

    // Buffer's toString method
    function () {
      let result;
      if (arguments.length === 0) {
        result = this.utf8Slice(0, this.length);
      } else {
        result = slowToString.apply(this, arguments);
      }
      if (result === undefined)
        throw new Error('"toString()" failed');
      return result;
    }
    
    // Javascript's built-in
    function toString() { [native code] } // I haven't sought to find it out
    

    It turns out that whenever you do JSON.parse(JSON.stringify(buf)) you are actually transforming your Buffer into a Javascript object. For example:

    { type: 'Buffer', data: [ 61, 62, 63] }.

    So another toString() on it will run native JS function (not Buffer's) which returns by default [object Object].