Skip to content

fix: avoid mutating query config#3720

Open
GiHoon1123 wants to merge 3 commits into
brianc:masterfrom
GiHoon1123:fix-2651-query-config-mutation
Open

fix: avoid mutating query config#3720
GiHoon1123 wants to merge 3 commits into
brianc:masterfrom
GiHoon1123:fix-2651-query-config-mutation

Conversation

@GiHoon1123

Copy link
Copy Markdown

Fixes #2651

client.query() adds callback and values to config objects passed by the caller. Reusing the same object can make a later promise-style call return undefined.

Copy the config before normalizing it and add regression tests for config reuse and mutation.

Fixes brianc#2651.

normalizeQueryConfig() wrote values/callback directly onto the object
it was given instead of copying it first. Reusing the same config
object across calls (callback style, then promise style) left a stale
callback on it, so a later promise-style call would see query.callback
already set, skip creating the promise, and silently return undefined
while the real result went to the old callback instead.

Copy the object before writing to it so the caller's config is never
touched, and add regression tests for both the direct case and the
callback-then-promise reuse scenario.
Comment thread packages/pg/lib/utils.js Outdated
// 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 } : { ...config }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a potential breaking change for query objects that don’t have own enumerable query config properties. I’d say return an object like { callback: config.callback, values: config.values, config } and have callers access normalizedConfig.config?.otherProperty, but that would be a breaking change for normalizeQueryConfig itself, so… another function?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good catch. I switched this away from object spread so it keeps the original prototype and property descriptors while still avoiding mutation of the caller's object.

I added a unit test with an inherited text getter for this case. Also ran make test-unit, yarn lint, and yarn build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Client.query(config, values, callback) sets config.callback, causing subsequent invocations to fail

2 participants