Skip to content

Commit

Permalink
Merge branch 'release/2.5.5'
Browse files Browse the repository at this point in the history
  • Loading branch information
diego Dupin committed Oct 18, 2021
2 parents f68ecb3 + a3f0cb1 commit bc9f6c7
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 91 deletions.
14 changes: 7 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,19 @@ jobs:
- env: srv=mariadb v=10.5 local=1
node_js: 12
- env: srv=mariadb v=10.6 BENCH=1 local=1
- if: env(CONNECTOR_TEST_SECRET_KEY) IS present
- if: type = push AND fork = false
env: srv=maxscale
- if: env(CONNECTOR_TEST_SECRET_KEY) IS present
- if: type = push AND fork = false
env: srv=mariadb-es v=10.5
- if: env(CONNECTOR_TEST_SECRET_KEY) IS present
- if: type = push AND fork = false
env: srv=skysql RUN_LONG_TEST=0
- if: env(CONNECTOR_TEST_SECRET_KEY) IS present
- if: type = push AND fork = false
env: srv=skysql-ha RUN_LONG_TEST=0
- if: env(CONNECTOR_TEST_SECRET_KEY) IS present
- if: type = push AND fork = false
env: srv=build v=10.6
- if: env(CONNECTOR_TEST_SECRET_KEY) IS present
- if: type = push AND fork = false
env: srv=mysql v=5.7
- if: env(CONNECTOR_TEST_SECRET_KEY) IS present
- if: type = push AND fork = false
env: srv=mysql v=8.0

script:
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Change Log

## [2.5.5](https://github.com/mariadb-corporation/mariadb-connector-nodejs/tree/2.5.5) (19 Oct 2021)
[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-nodejs/compare/2.5.4...2.5.5)

* [CONJS-170] Pool.query(undefined) never release connection
* [CONJS-173] not permitting providing null as a value without an array
* [CONJS-175] Missing leakDetectionTimeout option in Typescript description

## [2.5.4](https://github.com/mariadb-corporation/mariadb-connector-nodejs/tree/2.5.4) (08 Jun 2021)
[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-nodejs/compare/2.5.3...2.5.4)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ To file an issue or follow the development, see [JIRA](https://jira.mariadb.org/


[travis-image]:https://travis-ci.com/mariadb-corporation/mariadb-connector-nodejs.svg?branch=master
[travis-url]:https://travis-ci.com/mariadb-corporation/mariadb-connector-nodejs
[travis-url]:https://app.travis-ci.com/github/mariadb-corporation/mariadb-connector-nodejs
[npm-image]:https://img.shields.io/npm/v/mariadb.svg
[npm-url]:http://npmjs.org/package/mariadb
[licence-image]:https://img.shields.io/badge/license-GNU%20LGPL%20version%202.1-green.svg?style=flat-square
Expand Down
2 changes: 1 addition & 1 deletion documentation/promise-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ connection

### Placeholder

To prevent SQL Injection attacks, queries permit the use of question marks as placeholders. The Connection escapes values according to their type. Values can be of native JavaScript types, Buffers, Readables, objects with `toSQLString` methods, or objects that can be stringified (that is, `JSON.stringfy`).
To prevent SQL Injection attacks, queries permit the use of question marks as placeholders. The Connection escapes values according to their type. Values can be of native JavaScript types, Buffers, Readables, objects with `toSQLString` methods, or objects that can be stringified (that is, `JSON.stringify`).

When streaming, objects that implement Readable are streamed automatically. But, there are two server system variables that may interfere:

Expand Down
2 changes: 1 addition & 1 deletion lib/cmd/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Query extends CommonText {
* @param info connection information
*/
start(out, opts, info) {
if (!this.initialValues) {
if (this.initialValues === undefined) {
//shortcut if no parameters
out.startPacket(this);
out.writeInt8(0x03);
Expand Down
1 change: 1 addition & 0 deletions lib/misc/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ module.exports.ER_PING_TIMEOUT = 45042;
module.exports.ER_BAD_PARAMETER_VALUE = 45043;
module.exports.ER_CANNOT_RETRIEVE_RSA_KEY = 45044;
module.exports.ER_MINIMUM_NODE_VERSION_REQUIRED = 45045;
module.exports.ER_POOL_UNDEFINED_SQL = 45049;

const keys = Object.keys(module.exports);
const errByNo = {};
Expand Down
16 changes: 16 additions & 0 deletions lib/pool-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,22 @@ function PoolBase(options, processTask, createConnectionPool, pingPromise) {
* @return {*}
*/
const addRequest = function (pool, sql, values, isBatch) {
if (isBatch != undefined && !sql) {
// request for query/batch without sql
return Promise.reject(
Errors.createError(
'sql parameter is mandatory',
null,
false,
null,
'HY000',
Errors.ER_POOL_UNDEFINED_SQL,
undefined,
false
)
);
}

if (closed) {
return Promise.reject(
Errors.createError(
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mariadb",
"version": "2.5.4",
"version": "2.5.5",
"description": "fast mariadb/mysql connector.",
"main": "promise.js",
"types": "types/index.d.ts",
Expand Down
171 changes: 92 additions & 79 deletions test/integration/test-pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,50 @@ describe('Pool', () => {
pool.end();
});

it('undefined query', async function () {
const pool = base.createPool({ connectionLimit: 1 });
try {
await pool.query(undefined);
throw new Error('must have thrown an error');
} catch (err) {
assert(err.message.includes('sql parameter is mandatory'));
assert.equal(err.sqlState, 'HY000');
assert.equal(err.errno, 45049);
assert.equal(err.code, 'ER_POOL_UNDEFINED_SQL');
} finally {
await pool.end();
}
});

it('undefined batch', async function () {
const pool = base.createPool({ connectionLimit: 1 });
try {
await pool.batch(undefined);
throw new Error('must have thrown an error');
} catch (err) {
assert(err.message.includes('sql parameter is mandatory'));
assert.equal(err.sqlState, 'HY000');
assert.equal(err.errno, 45049);
assert.equal(err.code, 'ER_POOL_UNDEFINED_SQL');
} finally {
await pool.end();
}
});

it('query with null placeholder', async function () {
const pool = base.createPool({ connectionLimit: 1 });
let rows = await pool.query('select ? as a', [null]);
assert.deepEqual(rows, [{ a: null }]);
await pool.end();
});

it('query with null placeholder no array', async function () {
const pool = base.createPool({ connectionLimit: 1 });
let rows = await pool.query('select ? as a', null);
assert.deepEqual(rows, [{ a: null }]);
await pool.end();
});

it('pool with wrong authentication', function (done) {
if (process.env.srv === 'maxscale' || process.env.srv === 'skysql-ha') this.skip(); //to avoid host beeing blocked
this.timeout(10000);
Expand Down Expand Up @@ -171,75 +215,54 @@ describe('Pool', () => {
});
});

it('pool with wrong authentication connection', function (done) {
it('pool with wrong authentication connection', async function () {
if (
process.env.srv === 'maxscale' ||
process.env.srv === 'skysql' ||
process.env.srv === 'skysql-ha'
)
this.skip();
this.timeout(10000);
const pool = base.createPool({
acquireTimeout: 4000,
initializationTimeout: 2000,
user: 'wrongAuthentication'
});
pool
.getConnection()
.then(() => {
pool.end();
done(new Error('must have thrown error'));
})
.catch((err) => {
assert.isTrue(
err.errno === 1524 ||
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
err.errno === 45025 ||
err.errno === 45044,
err.message
);
pool
.getConnection()
.then(() => {
pool.end();
done(new Error('must have thrown error'));
})
.catch((err) => {
pool.end();
assert.isTrue(
err.errno === 1524 ||
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
err.errno === 45025 ||
err.errno === 45044,
err.message
);
done();
});
});
pool
.getConnection()
.then(() => {
pool.end();
done(new Error('must have thrown error'));
})
.catch((err) => {
assert.isTrue(
err.errno === 1524 ||
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
err.errno === 45025 ||
err.errno === 45044,
err.message
);
let err;
let pool;
try {
pool = base.createPool({
acquireTimeout: 4000,
initializationTimeout: 2000,
user: 'wrongAuthentication'
});
await pool.getConnection();
throw new Error('must have thrown error');
} catch (err) {
assert.isTrue(
err.errno === 1524 ||
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
err.errno === 45025 ||
err.errno === 45044,
err.message
);
}
try {
await pool.getConnection();
throw new Error('must have thrown error');
} catch (err) {
assert.isTrue(
err.errno === 1524 ||
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
err.errno === 45025 ||
err.errno === 45044,
err.message
);
} finally {
pool.end();
}
});

it('create pool', function (done) {
it('create pool', async function () {
if (
process.env.srv === 'maxscale' ||
process.env.srv === 'skysql' ||
Expand All @@ -249,26 +272,16 @@ describe('Pool', () => {
this.timeout(5000);
const pool = base.createPool({ connectionLimit: 1 });
const initTime = Date.now();
pool.getConnection().then((conn) => {
conn.query('SELECT SLEEP(1)').then(() => {
conn.release();
});
});
pool.getConnection().then((conn) => {
conn
.query('SELECT SLEEP(1)')
.then(() => {
assert(
Date.now() - initTime >= 1999,
'expected > 2s, but was ' + (Date.now() - initTime)
);
conn.release();
return pool.end();
})
.then(() => {
done();
});
});
let conn = await pool.getConnection();
await conn.query('SELECT SLEEP(1)');
conn.release();

await pool.getConnection();
await conn.query('SELECT SLEEP(1)');
const time = Date.now() - initTime;
assert(time >= 1980, 'expected > 2s, but was ' + time);
conn.release();
await pool.end();
});

it('create pool with multipleStatement', function (done) {
Expand Down
10 changes: 10 additions & 0 deletions test/integration/test-query.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ describe('basic query', () => {
.catch(done);
});

it('query with null placeholder', async function () {
let rows = await shareConn.query('select ? as a', [null]);
assert.deepEqual(rows, [{ a: null }]);
});

it('query with null placeholder no array', async function () {
let rows = await shareConn.query('select ? as a', null);
assert.deepEqual(rows, [{ a: null }]);
});

it('parameter last', async () => {
const value = "'`\\";
const conn = await base.createConnection();
Expand Down
9 changes: 9 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,15 @@ export interface PoolConfig extends ConnectionConfig {
* Default: false
*/
noControlAfterUse?: boolean;

/**
* Permit to indicate a timeout to log connection borrowed from pool.
* When a connection is borrowed from pool and this timeout is reached,
* a message will be logged to console indicating a possible connection leak.
* Another message will tell if the possible logged leak has been released.
* A value of 0 (default) meaning Leak detection is disable
*/
leakDetectionTimeout?: number;
}

export interface PoolClusterConfig {
Expand Down
3 changes: 2 additions & 1 deletion types/mariadb-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ function createPoolConfig(options?: PoolConfig): mariadb.PoolConfig {
{
host: baseConfig.host,
user: baseConfig.user,
password: baseConfig.password
password: baseConfig.password,
leakDetectionTimeout: 10
},
options
);
Expand Down

0 comments on commit bc9f6c7

Please sign in to comment.