node-mysql2 icon indicating copy to clipboard operation
node-mysql2 copied to clipboard

SyntaxError: Unexpected token ':' when JSON.stringify is overridden

Open aaron13100 opened this issue 2 years ago • 5 comments

Without overriding JSON.stringify, the query works fine. When JSON.stringify is overridden, I get SyntaxError: Unexpected token ':' This is the entire code.

const mysql = require('mysql2');

const originalStringify = JSON.stringify;
/* without this override there is no error */
JSON.stringify = function (obj, replacer = null, space = 2) {
  return originalStringify(obj, replacer, space);
};

const connection = mysql.createConnection({
    host: 'localhost',
    port: 8889,
    user: 'root',
    password: 'root',
    database: 'flashcards'
});

try {
    connection.connect();
    connection.query('SELECT version()', function (error, results, fields) {
        if (error) throw error;
        console.log("result OK");
    });

} finally {
    connection.end();
}

aaron13100 avatar Nov 22 '23 08:11 aaron13100

Edited


This happens when you change the native JSON.stringify method:

// It's a string
return ((function () {
  return class TextRow {
    constructor(fields) {
    }
    next(packet, fields, options) {
      this.packet = packet;
      const result = {};
      //
      "version()": : VAR_STRING
      result[
        "version()": ] = packet.readLengthCodedString(fields[0].encoding);
        return result;
      }
    };
  })())

Look at that:

//
"version()": : VAR_STRING

Now, what it should be:

// It's a string
return ((function () {
  return class TextRow {
    constructor(fields) {
    }
    next(packet, fields, options) {
      this.packet = packet;
      const result = {};
      // "version()": VAR_STRING
      result["version()"] = packet.readLengthCodedString(fields[0].encoding);
      return result;
    }
  };
})())

wellwelwel avatar Nov 25 '23 00:11 wellwelwel

Since this error comes from an external dependency, I will close this issue as not planned. But feel free to ask anything and reopen it at anytime 🙋🏻‍♂️

wellwelwel avatar Nov 25 '23 00:11 wellwelwel

the error actually comes from srcEscape, here is smaller self contained example:

const originalStringify = JSON.stringify;

if (true) {
/* without this override there is no error */
  JSON.stringify = function (obj, replacer = null, space = 2) {
    return originalStringify(obj, replacer, space);
  };
}


function srcEscape(str) {
    return JSON.stringify({
      [str]: 1
    }).slice(1, -3);
}

console.log(srcEscape(`test("test")`));

we can probably change to something more reliable:

    return JSON.stringify({
      [str]: 1
    }).trim().slice(1, -1).split('\n').filter(s => s.length > 0).split(':').slice(0, -1).join('')

or just use some more simple way of escaping. JSON.stringify + key extract works both fast and reliable but I'm open to other suggestions.

Another fix that would work with @aaron13100 example is to just pass replacer and space explicitly in srcEscape:

function srcEscape(str) {
    return JSON.stringify({
      [str]: 1
    }, null, 0).slice(1, -3);
}

sidorares avatar Nov 25 '23 07:11 sidorares

@aaron13100 do you want to send a PR with added null, 0?

sidorares avatar Nov 25 '23 07:11 sidorares

Thanks, @sidorares 🙋🏻‍♂️

I've adjusted my comment.

wellwelwel avatar Nov 25 '23 07:11 wellwelwel