From 58759bf5fa5c50ab590c6cb53a0c84cc7e650b7d Mon Sep 17 00:00:00 2001 From: rpedela Date: Thu, 11 Jul 2013 16:35:23 -0600 Subject: [PATCH 1/5] Add native and JS tests for escapeLiteral and escapeIdentifier. --- test/native/escape-tests.js | 120 +++++++++++++++++++++++++++ test/unit/connection/escape-tests.js | 113 +++++++++++++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 test/native/escape-tests.js create mode 100644 test/unit/connection/escape-tests.js diff --git a/test/native/escape-tests.js b/test/native/escape-tests.js new file mode 100644 index 00000000..3503be04 --- /dev/null +++ b/test/native/escape-tests.js @@ -0,0 +1,120 @@ +var helper = require(__dirname + "/../test-helper"); +var Client = require(__dirname + "/../../lib/native"); + +function createClient() { + var client = new Client(helper.config); + client.connect(); + return client; +} + +test('escapeLiteral: no special characters', function() { + var client = createClient(); + var expected = "'hello world'"; + var actual = client.escapeLiteral('hello world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains double quotes only', function() { + var client = createClient(); + var expected = "'hello \" world'"; + var actual = client.escapeLiteral('hello " world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains single quotes only', function() { + var client = createClient(); + var expected = "'hello \'\' world'"; + var actual = client.escapeLiteral('hello \' world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains backslashes only', function() { + var client = createClient(); + var expected = " E'hello \\\\ world'"; + var actual = client.escapeLiteral('hello \\ world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains single quotes and double quotes', function() { + var client = createClient(); + var expected = "'hello '' \" world'"; + var actual = client.escapeLiteral('hello \' " world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains double quotes and backslashes', function() { + var client = createClient(); + var expected = " E'hello \\\\ \" world'"; + var actual = client.escapeLiteral('hello \\ " world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains single quotes and backslashes', function() { + var client = createClient(); + var expected = " E'hello \\\\ '' world'"; + var actual = client.escapeLiteral('hello \\ \' world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains single quotes, double quotes, and backslashes', function() { + var client = createClient(); + var expected = " E'hello \\\\ '' \" world'"; + var actual = client.escapeLiteral('hello \\ \' " world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: no special characters', function() { + var client = createClient(); + var expected = '"hello world"'; + var actual = client.escapeIdentifier('hello world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains double quotes only', function() { + var client = createClient(); + var expected = '"hello "" world"'; + var actual = client.escapeIdentifier('hello " world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains single quotes only', function() { + var client = createClient(); + var expected = '"hello \' world"'; + var actual = client.escapeIdentifier('hello \' world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains backslashes only', function() { + var client = createClient(); + var expected = '"hello \\ world"'; + var actual = client.escapeIdentifier('hello \\ world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains single quotes and double quotes', function() { + var client = createClient(); + var expected = '"hello \' "" world"'; + var actual = client.escapeIdentifier('hello \' " world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains double quotes and backslashes', function() { + var client = createClient(); + var expected = '"hello \\ "" world"'; + var actual = client.escapeIdentifier('hello \\ " world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains single quotes and backslashes', function() { + var client = createClient(); + var expected = '"hello \\ \' world"'; + var actual = client.escapeIdentifier('hello \\ \' world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains single quotes, double quotes, and backslashes', function() { + var client = createClient(); + var expected = '"hello \\ \' "" world"'; + var actual = client.escapeIdentifier('hello \\ \' " world'); + assert.equal(expected, actual); +}); diff --git a/test/unit/connection/escape-tests.js b/test/unit/connection/escape-tests.js new file mode 100644 index 00000000..df23fe05 --- /dev/null +++ b/test/unit/connection/escape-tests.js @@ -0,0 +1,113 @@ +require(__dirname + "/test-helper"); + +test('escapeLiteral: no special characters', function() { + var client = createClient(); + var expected = "'hello world'"; + var actual = client.escapeLiteral('hello world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains double quotes only', function() { + var client = createClient(); + var expected = "'hello \" world'"; + var actual = client.escapeLiteral('hello " world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains single quotes only', function() { + var client = createClient(); + var expected = "'hello \'\' world'"; + var actual = client.escapeLiteral('hello \' world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains backslashes only', function() { + var client = createClient(); + var expected = " E'hello \\\\ world'"; + var actual = client.escapeLiteral('hello \\ world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains single quotes and double quotes', function() { + var client = createClient(); + var expected = "'hello '' \" world'"; + var actual = client.escapeLiteral('hello \' " world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains double quotes and backslashes', function() { + var client = createClient(); + var expected = " E'hello \\\\ \" world'"; + var actual = client.escapeLiteral('hello \\ " world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains single quotes and backslashes', function() { + var client = createClient(); + var expected = " E'hello \\\\ '' world'"; + var actual = client.escapeLiteral('hello \\ \' world'); + assert.equal(expected, actual); +}); + +test('escapeLiteral: contains single quotes, double quotes, and backslashes', function() { + var client = createClient(); + var expected = " E'hello \\\\ '' \" world'"; + var actual = client.escapeLiteral('hello \\ \' " world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: no special characters', function() { + var client = createClient(); + var expected = '"hello world"'; + var actual = client.escapeIdentifier('hello world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains double quotes only', function() { + var client = createClient(); + var expected = '"hello "" world"'; + var actual = client.escapeIdentifier('hello " world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains single quotes only', function() { + var client = createClient(); + var expected = '"hello \' world"'; + var actual = client.escapeIdentifier('hello \' world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains backslashes only', function() { + var client = createClient(); + var expected = '"hello \\ world"'; + var actual = client.escapeIdentifier('hello \\ world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains single quotes and double quotes', function() { + var client = createClient(); + var expected = '"hello \' "" world"'; + var actual = client.escapeIdentifier('hello \' " world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains double quotes and backslashes', function() { + var client = createClient(); + var expected = '"hello \\ "" world"'; + var actual = client.escapeIdentifier('hello \\ " world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains single quotes and backslashes', function() { + var client = createClient(); + var expected = '"hello \\ \' world"'; + var actual = client.escapeIdentifier('hello \\ \' world'); + assert.equal(expected, actual); +}); + +test('escapeIdentifier: contains single quotes, double quotes, and backslashes', function() { + var client = createClient(); + var expected = '"hello \\ \' "" world"'; + var actual = client.escapeIdentifier('hello \\ \' " world'); + assert.equal(expected, actual); +}); From baaacd2a8f71ffa8fa629d6c2df5aa81d9eb4d34 Mon Sep 17 00:00:00 2001 From: rpedela Date: Fri, 12 Jul 2013 11:08:00 -0600 Subject: [PATCH 2/5] Move string escaping tests to proper locations. --- test/native/escape-tests.js | 120 --------------------------- test/unit/connection/escape-tests.js | 113 ------------------------- 2 files changed, 233 deletions(-) delete mode 100644 test/native/escape-tests.js delete mode 100644 test/unit/connection/escape-tests.js diff --git a/test/native/escape-tests.js b/test/native/escape-tests.js deleted file mode 100644 index 3503be04..00000000 --- a/test/native/escape-tests.js +++ /dev/null @@ -1,120 +0,0 @@ -var helper = require(__dirname + "/../test-helper"); -var Client = require(__dirname + "/../../lib/native"); - -function createClient() { - var client = new Client(helper.config); - client.connect(); - return client; -} - -test('escapeLiteral: no special characters', function() { - var client = createClient(); - var expected = "'hello world'"; - var actual = client.escapeLiteral('hello world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains double quotes only', function() { - var client = createClient(); - var expected = "'hello \" world'"; - var actual = client.escapeLiteral('hello " world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains single quotes only', function() { - var client = createClient(); - var expected = "'hello \'\' world'"; - var actual = client.escapeLiteral('hello \' world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains backslashes only', function() { - var client = createClient(); - var expected = " E'hello \\\\ world'"; - var actual = client.escapeLiteral('hello \\ world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains single quotes and double quotes', function() { - var client = createClient(); - var expected = "'hello '' \" world'"; - var actual = client.escapeLiteral('hello \' " world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains double quotes and backslashes', function() { - var client = createClient(); - var expected = " E'hello \\\\ \" world'"; - var actual = client.escapeLiteral('hello \\ " world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains single quotes and backslashes', function() { - var client = createClient(); - var expected = " E'hello \\\\ '' world'"; - var actual = client.escapeLiteral('hello \\ \' world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains single quotes, double quotes, and backslashes', function() { - var client = createClient(); - var expected = " E'hello \\\\ '' \" world'"; - var actual = client.escapeLiteral('hello \\ \' " world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: no special characters', function() { - var client = createClient(); - var expected = '"hello world"'; - var actual = client.escapeIdentifier('hello world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains double quotes only', function() { - var client = createClient(); - var expected = '"hello "" world"'; - var actual = client.escapeIdentifier('hello " world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains single quotes only', function() { - var client = createClient(); - var expected = '"hello \' world"'; - var actual = client.escapeIdentifier('hello \' world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains backslashes only', function() { - var client = createClient(); - var expected = '"hello \\ world"'; - var actual = client.escapeIdentifier('hello \\ world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains single quotes and double quotes', function() { - var client = createClient(); - var expected = '"hello \' "" world"'; - var actual = client.escapeIdentifier('hello \' " world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains double quotes and backslashes', function() { - var client = createClient(); - var expected = '"hello \\ "" world"'; - var actual = client.escapeIdentifier('hello \\ " world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains single quotes and backslashes', function() { - var client = createClient(); - var expected = '"hello \\ \' world"'; - var actual = client.escapeIdentifier('hello \\ \' world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains single quotes, double quotes, and backslashes', function() { - var client = createClient(); - var expected = '"hello \\ \' "" world"'; - var actual = client.escapeIdentifier('hello \\ \' " world'); - assert.equal(expected, actual); -}); diff --git a/test/unit/connection/escape-tests.js b/test/unit/connection/escape-tests.js deleted file mode 100644 index df23fe05..00000000 --- a/test/unit/connection/escape-tests.js +++ /dev/null @@ -1,113 +0,0 @@ -require(__dirname + "/test-helper"); - -test('escapeLiteral: no special characters', function() { - var client = createClient(); - var expected = "'hello world'"; - var actual = client.escapeLiteral('hello world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains double quotes only', function() { - var client = createClient(); - var expected = "'hello \" world'"; - var actual = client.escapeLiteral('hello " world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains single quotes only', function() { - var client = createClient(); - var expected = "'hello \'\' world'"; - var actual = client.escapeLiteral('hello \' world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains backslashes only', function() { - var client = createClient(); - var expected = " E'hello \\\\ world'"; - var actual = client.escapeLiteral('hello \\ world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains single quotes and double quotes', function() { - var client = createClient(); - var expected = "'hello '' \" world'"; - var actual = client.escapeLiteral('hello \' " world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains double quotes and backslashes', function() { - var client = createClient(); - var expected = " E'hello \\\\ \" world'"; - var actual = client.escapeLiteral('hello \\ " world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains single quotes and backslashes', function() { - var client = createClient(); - var expected = " E'hello \\\\ '' world'"; - var actual = client.escapeLiteral('hello \\ \' world'); - assert.equal(expected, actual); -}); - -test('escapeLiteral: contains single quotes, double quotes, and backslashes', function() { - var client = createClient(); - var expected = " E'hello \\\\ '' \" world'"; - var actual = client.escapeLiteral('hello \\ \' " world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: no special characters', function() { - var client = createClient(); - var expected = '"hello world"'; - var actual = client.escapeIdentifier('hello world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains double quotes only', function() { - var client = createClient(); - var expected = '"hello "" world"'; - var actual = client.escapeIdentifier('hello " world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains single quotes only', function() { - var client = createClient(); - var expected = '"hello \' world"'; - var actual = client.escapeIdentifier('hello \' world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains backslashes only', function() { - var client = createClient(); - var expected = '"hello \\ world"'; - var actual = client.escapeIdentifier('hello \\ world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains single quotes and double quotes', function() { - var client = createClient(); - var expected = '"hello \' "" world"'; - var actual = client.escapeIdentifier('hello \' " world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains double quotes and backslashes', function() { - var client = createClient(); - var expected = '"hello \\ "" world"'; - var actual = client.escapeIdentifier('hello \\ " world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains single quotes and backslashes', function() { - var client = createClient(); - var expected = '"hello \\ \' world"'; - var actual = client.escapeIdentifier('hello \\ \' world'); - assert.equal(expected, actual); -}); - -test('escapeIdentifier: contains single quotes, double quotes, and backslashes', function() { - var client = createClient(); - var expected = '"hello \\ \' "" world"'; - var actual = client.escapeIdentifier('hello \\ \' " world'); - assert.equal(expected, actual); -}); From cf07a4f2b4b0aca7580505927a5703f248f2e819 Mon Sep 17 00:00:00 2001 From: rpedela Date: Tue, 23 Jul 2013 12:04:03 -0600 Subject: [PATCH 3/5] #403 Only use native escape functions if PG version >= 9.0.0. Otherwise use the JS functions. --- lib/native/index.js | 10 ++++++++++ src/binding.cc | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/native/index.js b/lib/native/index.js index f89740db..efb37bfa 100644 --- a/lib/native/index.js +++ b/lib/native/index.js @@ -4,6 +4,7 @@ var EventEmitter = require('events').EventEmitter; var ConnectionParameters = require(__dirname + '/../connection-parameters'); var CopyFromStream = require(__dirname + '/../copystream').CopyFromStream; var CopyToStream = require(__dirname + '/../copystream').CopyToStream; +var JsClient = require(__dirname + '/../client'); // used to import JS escape functions var binding; @@ -80,6 +81,15 @@ Connection.prototype.endCopyFrom = function (msg) { this._endCopyFrom(msg); }; +// use JS version if native version undefined +// happens when PG version < 9.0.0 +if (!Connection.prototype.escapeIdentifier) { + Connection.prototype.escapeIdentifier = JsClient.prototype.escapeIdentifier; +} +if (!Connection.prototype.escapeLiteral) { + Connection.prototype.escapeLiteral = JsClient.prototype.escapeLiteral; +} + Connection.prototype.query = function(config, values, callback) { var query = (config instanceof NativeQuery) ? config : new NativeQuery(config, values, callback); diff --git a/src/binding.cc b/src/binding.cc index 7a2364be..6081171d 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -8,6 +8,9 @@ #define LOG(msg) printf("%s\n",msg); #define TRACE(msg) //printf("%s\n", msg); +#if PG_VERSION_NUM > 90000 +#define ESCAPE_SUPPORTED +#endif #define THROW(msg) return ThrowException(Exception::Error(String::New(msg))); @@ -67,8 +70,10 @@ public: command_symbol = NODE_PSYMBOL("command"); NODE_SET_PROTOTYPE_METHOD(t, "connect", Connect); +#ifdef ESCAPE_SUPPORTED NODE_SET_PROTOTYPE_METHOD(t, "escapeIdentifier", EscapeIdentifier); NODE_SET_PROTOTYPE_METHOD(t, "escapeLiteral", EscapeLiteral); +#endif NODE_SET_PROTOTYPE_METHOD(t, "_sendQuery", SendQuery); NODE_SET_PROTOTYPE_METHOD(t, "_sendQueryWithParams", SendQueryWithParams); NODE_SET_PROTOTYPE_METHOD(t, "_sendPrepare", SendPrepare); @@ -132,6 +137,7 @@ public: return Undefined(); } +#ifdef ESCAPE_SUPPORTED //v8 entry point into Connection#escapeIdentifier static Handle EscapeIdentifier(const Arguments& args) @@ -183,6 +189,7 @@ public: return scope.Close(jsStr); } +#endif //v8 entry point into Connection#_sendQuery static Handle @@ -361,6 +368,7 @@ protected: return args.This(); } +#ifdef ESCAPE_SUPPORTED char * EscapeIdentifier(const char *str) { TRACE("js::EscapeIdentifier") @@ -372,6 +380,7 @@ protected: TRACE("js::EscapeLiteral") return PQescapeLiteral(connection_, str, strlen(str)); } +#endif int Send(const char *queryText) { From 8129f194093b00514ba7a3d8cdd823205c3cae80 Mon Sep 17 00:00:00 2001 From: rpedela Date: Tue, 23 Jul 2013 12:18:13 -0600 Subject: [PATCH 4/5] Include pg_config.h to get PG_VERSION_NUM. --- src/binding.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/binding.cc b/src/binding.cc index 6081171d..17794a8f 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -1,3 +1,4 @@ +#include #include #include #include From 6dffc0c6cdcab202e6d48888f70a1d59e5cc8905 Mon Sep 17 00:00:00 2001 From: rpedela Date: Tue, 23 Jul 2013 12:20:02 -0600 Subject: [PATCH 5/5] Include version 9.0.0 in escape function check. --- src/binding.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/binding.cc b/src/binding.cc index 17794a8f..a9a7943f 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -9,7 +9,7 @@ #define LOG(msg) printf("%s\n",msg); #define TRACE(msg) //printf("%s\n", msg); -#if PG_VERSION_NUM > 90000 +#if PG_VERSION_NUM >= 90000 #define ESCAPE_SUPPORTED #endif