Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion packages/pg/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ function dateToStringUTC(date) {

function normalizeQueryConfig(config, values, callback) {
// can take in strings or config objects
config = typeof config === 'string' ? { text: config } : config
// Copy config so normalization does not mutate the caller's object.
config = typeof config === 'string' ? { text: config } : cloneQueryConfig(config)
if (values) {
if (typeof values === 'function') {
config.callback = values
Expand All @@ -157,6 +158,13 @@ function normalizeQueryConfig(config, values, callback) {
return config
}

function cloneQueryConfig(config) {
if (config == null) {
return config
}
return Object.defineProperties(Object.create(Object.getPrototypeOf(config)), Object.getOwnPropertyDescriptors(config))
}

// Ported from PostgreSQL 9.2.4 source code in src/interfaces/libpq/fe-exec.c
const escapeIdentifier = function (str) {
return '"' + str.replace(/"/g, '""') + '"'
Expand Down
14 changes: 14 additions & 0 deletions packages/pg/test/unit/client/simple-query-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,18 @@ test('executing query', function () {
)
})
})

test('reusing a config object across calls', function () {
// Regression test for https://github.com/brianc/node-postgres/issues/2651.
test('does not leak callback state into a later promise-style call', function () {
const client = helper.client()
const config = { text: 'SELECT $1', values: [1] }

client.query(config, function () {})
const result = client.query(config)

assert.ok(result instanceof Promise, 'expected client.query() to return a Promise')
result.catch(() => {})
})
})
})
35 changes: 35 additions & 0 deletions packages/pg/test/unit/utils-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,41 @@ test('normalizing query configs', function () {
assert.deepEqual(config, { text: 'TEXT', values: [10], callback: callback })
})

test('normalizeQueryConfig does not mutate the passed-in config object', function () {
// Regression test for https://github.com/brianc/node-postgres/issues/2651.
const original = { text: 'TEXT' }
const callback = function () {}

const normalized = utils.normalizeQueryConfig(original, [10], callback)

assert.equal(original.callback, undefined)
assert.equal(original.values, undefined)
assert.deepEqual(normalized, { text: 'TEXT', values: [10], callback: callback })
})

test('normalizeQueryConfig preserves inherited config properties', function () {
class QueryConfig {
constructor() {
this._text = 'TEXT'
}

get text() {
return this._text
}
}

const original = new QueryConfig()
const callback = function () {}

const normalized = utils.normalizeQueryConfig(original, [10], callback)

assert.equal(original.callback, undefined)
assert.equal(original.values, undefined)
assert.equal(normalized.text, 'TEXT')
assert.deepEqual(normalized.values, [10])
assert.equal(normalized.callback, callback)
})

test('prepareValues: buffer prepared properly', function () {
const buf = Buffer.from('quack')
const out = utils.prepareValue(buf)
Expand Down
Loading