Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle prepare response when number of fields in the prepare header does not match the actual number in the response #2056

Closed
wants to merge 11 commits into from
12 changes: 9 additions & 3 deletions .github/workflows/ci-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,23 @@ jobs:
fail-fast: false
matrix:
node-version: [16.x, 18.x, 20.x]
mysql-version: ["mysql:8.0.18", "mysql:8.0.22", "mysql:5.7"]
mysql-version: ["mysql:8.0.18", "mysql:8.0.22", "mysql:8.0.33", "mysql:5.7"]
use-compression: [0]
use-tls: [0]
mysql_connection_url_key: [""]
# TODO - add mariadb to the matrix. currently few tests are broken due to mariadb incompatibilities
include:
# 20.x
- node-version: "20.x"
mysql-version: "mysql:8.0.18"
mysql-version: "mysql:8.0.33"
use-compression: 1
use-tls: 0
use-builtin-test-runner: 1
- node-version: "20.x"
mysql-version: "mysql:8.0.18"
mysql-version: "mysql:8.0.33"
use-compression: 0
use-tls: 1
use-builtin-test-runner: 1

# 18.x
# - node-version: "18.x"
Expand Down Expand Up @@ -113,6 +115,10 @@ jobs:
- name: Run tests
run: FILTER=${{matrix.filter}} MYSQL_USE_TLS=${{ matrix.use-tls }} MYSQL_USE_COMPRESSION=${{ matrix.use-compression }} npm run coverage-test

- name: Run tests with built-in node test runner
if: ${{ matrix.use-builtin-test-runner }}
run: FILTER=${{matrix.filter}} MYSQL_USE_TLS=${{ matrix.use-tls }} MYSQL_USE_COMPRESSION=${{ matrix.use-compression }} npm run test:builtin-node-runner

- run: echo "coverage-artifact-name=`echo -n "${{github.run_id}}-${{ matrix.node-version }}-${{ matrix.mysql-version }}-{${{ matrix.mysql_connection_url_key }}-${{matrix.use-tls}}-${{matrix.use-compression}}" | shasum | cut -d " " -f 1`" >> $GITHUB_ENV
- uses: actions/upload-artifact@v3
with:
Expand Down
23 changes: 16 additions & 7 deletions lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -487,14 +487,23 @@ class Connection extends EventEmitter {
}
this._bumpSequenceId(packet.numPackets);
}
const done = this._command.execute(packet, this);
if (done) {
this._command = this._commands.shift();
if (this._command) {
this.sequenceId = 0;
this.compressedSequenceId = 0;
this.handlePacket();
try {
if (this._fatalError) {
// skip remaining packets after client is in the error state
return;
}
const done = this._command.execute(packet, this);
if (done) {
this._command = this._commands.shift();
if (this._command) {
this.sequenceId = 0;
this.compressedSequenceId = 0;
this.handlePacket();
}
}
} catch (err) {
this._handleFatalError(err);
this.stream.destroy();
}
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"lint:code": "eslint index.js promise.js \"lib/**/*.js\" \"test/**/*.js\" \"benchmarks/**/*.js\"",
"lint:docs": "eslint Contributing.md README.md \"documentation/**/*.md\" \"examples/*.js\"",
"test": "node ./test/run.js",
"test:builtin-node-runner": "node --test test/builtin-runner",
"test:tsc-build": "cd \"test/tsc-build\" && npx tsc -p \"tsconfig.json\"",
"coverage-test": "c8 -r cobertura -r lcov -r text node ./test/run.js",
"benchmark": "node ./benchmarks/benchmark.js",
Expand Down
27 changes: 27 additions & 0 deletions test/builtin-runner/regressions/2052.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { describe, it } from 'node:test';
import assert from 'node:assert';
import common from '../../../test/common.js';

describe('Prepare result when CLIENT_OPTIONAL_RESULTSET_METADATA is set or metadata_follows is unset', { timeout: 1000 }, () => {
it('should not throw an exception', (t, done) => {
const connection = common.createConnection({
database: 'mysql',
});

connection.on('error', (err) => {
done(err);
});

connection.prepare('select * from user order by ?', (err, stmt) => {
console.log(err);
if (err) {
if (!err.fatal) {
connection.end();
}
done(err);
} else {
connection.end(done);
}
});
});
});