node-firebird 2.3.1 → 2.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +218 -31
- package/lib/index.d.ts +22 -0
- package/lib/pool.js +97 -10
- package/lib/srp.js +12 -1
- package/lib/wire/connection.js +40 -7
- package/lib/wire/socket.js +13 -1
- package/lib/wire/xsqlvar.js +69 -6
- package/package.json +1 -1
- package/poc/README.md +160 -0
- package/poc/helpers.js +59 -0
- package/poc/node_modules/.package-lock.json +14 -0
- package/poc/node_modules/node-firebird/.eslintrc.json +12 -0
- package/poc/node_modules/node-firebird/.github/workflows/codeql.yml +76 -0
- package/poc/node_modules/node-firebird/.github/workflows/node.js.yml +95 -0
- package/poc/node_modules/node-firebird/BIGINT_MIGRATION.md +374 -0
- package/poc/node_modules/node-firebird/CI_DEBUGGING_GUIDE.md +148 -0
- package/poc/node_modules/node-firebird/ENCRYPTION_CALLBACK.md +152 -0
- package/poc/node_modules/node-firebird/FIREBIRD_LOG_FEATURE.md +145 -0
- package/poc/node_modules/node-firebird/LICENSE +373 -0
- package/poc/node_modules/node-firebird/MINIMAL_CHANGES_SUMMARY.md +136 -0
- package/poc/node_modules/node-firebird/PR_SUMMARY.md +96 -0
- package/poc/node_modules/node-firebird/README.md +794 -0
- package/poc/node_modules/node-firebird/ROADMAP.md +223 -0
- package/poc/node_modules/node-firebird/SRP_PROTOCOL.md +482 -0
- package/poc/node_modules/node-firebird/lib/callback.js +38 -0
- package/poc/node_modules/node-firebird/lib/firebird.msg +0 -0
- package/poc/node_modules/node-firebird/lib/firebird.msg.json +1371 -0
- package/poc/node_modules/node-firebird/lib/gdscodes.d.ts +1524 -0
- package/poc/node_modules/node-firebird/lib/gdscodes.js +1531 -0
- package/poc/node_modules/node-firebird/lib/ieee754-decimal.js +500 -0
- package/poc/node_modules/node-firebird/lib/index.d.ts +316 -0
- package/poc/node_modules/node-firebird/lib/index.js +128 -0
- package/poc/node_modules/node-firebird/lib/messages.js +162 -0
- package/poc/node_modules/node-firebird/lib/pool.js +108 -0
- package/poc/node_modules/node-firebird/lib/srp.js +299 -0
- package/poc/node_modules/node-firebird/lib/unix-crypt.js +343 -0
- package/poc/node_modules/node-firebird/lib/utils.js +164 -0
- package/poc/node_modules/node-firebird/lib/wire/connection.js +2510 -0
- package/poc/node_modules/node-firebird/lib/wire/const.js +807 -0
- package/poc/node_modules/node-firebird/lib/wire/database.js +378 -0
- package/poc/node_modules/node-firebird/lib/wire/eventConnection.js +118 -0
- package/poc/node_modules/node-firebird/lib/wire/fbEventManager.js +326 -0
- package/poc/node_modules/node-firebird/lib/wire/serialize.js +588 -0
- package/poc/node_modules/node-firebird/lib/wire/service.js +1058 -0
- package/poc/node_modules/node-firebird/lib/wire/socket.js +175 -0
- package/poc/node_modules/node-firebird/lib/wire/statement.js +48 -0
- package/poc/node_modules/node-firebird/lib/wire/transaction.js +206 -0
- package/poc/node_modules/node-firebird/lib/wire/xsqlvar.js +703 -0
- package/poc/node_modules/node-firebird/package.json +38 -0
- package/poc/node_modules/node-firebird/vitest.config.js +24 -0
- package/poc/package-lock.json +21 -0
- package/poc/package.json +12 -0
- package/poc/reproduce-fixed.js +150 -0
- package/poc/reproduce.js +133 -0
- package/vitest.config.js +4 -1
package/lib/wire/xsqlvar.js
CHANGED
|
@@ -13,17 +13,79 @@ const
|
|
|
13
13
|
TimeCoeff = 86400000,
|
|
14
14
|
MsPerMinute = 60000;
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Maps Firebird character-set names (upper-case) to the Node.js Buffer
|
|
18
|
+
* encoding string used by Buffer.toString() / Buffer.from().
|
|
19
|
+
*
|
|
20
|
+
* Firebird stores CHAR/VARCHAR data in the on-wire character set of the
|
|
21
|
+
* column (or the connection character set for NONE/unspecified columns).
|
|
22
|
+
* We must decode raw bytes with the matching Node.js encoding so that
|
|
23
|
+
* characters outside ASCII are reproduced correctly.
|
|
24
|
+
*
|
|
25
|
+
* Commonly used Firebird charsets not listed here fall back to the
|
|
26
|
+
* connection-level DEFAULT_ENCODING (typically 'utf8').
|
|
27
|
+
*/
|
|
28
|
+
const FirebirdToNodeEncoding = Object.freeze({
|
|
29
|
+
UTF8: 'utf8',
|
|
30
|
+
UNICODE_FSS: 'utf8',
|
|
31
|
+
WIN1252: 'latin1',
|
|
32
|
+
ISO8859_1: 'latin1',
|
|
33
|
+
LATIN1: 'latin1',
|
|
34
|
+
ASCII: 'ascii',
|
|
35
|
+
NONE: 'latin1', // unspecified charset – treat as binary-safe latin1
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const FirebirdCharsetWidths = {
|
|
39
|
+
'UTF8': 4,
|
|
40
|
+
'UNICODE_FSS': 3,
|
|
41
|
+
'SJIS': 2,
|
|
42
|
+
'EUCJ': 2
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
function getFirebirdCharsetWidth(charset) {
|
|
46
|
+
if (!charset) return 4;
|
|
47
|
+
const upper = charset.toUpperCase();
|
|
48
|
+
return FirebirdCharsetWidths[upper] || 1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Resolve the Node.js Buffer encoding to use when decoding text from a
|
|
53
|
+
* Firebird response buffer.
|
|
54
|
+
*
|
|
55
|
+
* @param {object|null} options Connection options object (may be falsy).
|
|
56
|
+
* @returns {string} A Node.js-compatible encoding string.
|
|
57
|
+
*/
|
|
58
|
+
function resolveTextEncoding(options) {
|
|
59
|
+
const encoding = (options && options.encoding)
|
|
60
|
+
? options.encoding.toUpperCase()
|
|
61
|
+
: Const.DEFAULT_ENCODING;
|
|
62
|
+
return FirebirdToNodeEncoding[encoding] || Const.DEFAULT_ENCODING.toLowerCase();
|
|
63
|
+
}
|
|
64
|
+
|
|
16
65
|
//------------------------------------------------------
|
|
17
66
|
|
|
18
67
|
class SQLVarText {
|
|
19
|
-
decode(data, lowerV13) {
|
|
68
|
+
decode(data, lowerV13, options) {
|
|
20
69
|
let ret;
|
|
70
|
+
const textEncoding = resolveTextEncoding(options);
|
|
21
71
|
if (this.subType > 1) {
|
|
22
72
|
// ToDo: with column charset
|
|
23
|
-
ret = data.readText(this.length,
|
|
73
|
+
ret = data.readText(this.length, textEncoding);
|
|
74
|
+
const encoding = options && options.encoding ? options.encoding : 'UTF8';
|
|
75
|
+
const width = getFirebirdCharsetWidth(encoding);
|
|
76
|
+
const charLength = Math.floor(this.length / width);
|
|
77
|
+
if (ret.length > charLength) {
|
|
78
|
+
ret = ret.substring(0, charLength);
|
|
79
|
+
}
|
|
24
80
|
} else if (this.subType === 0) {
|
|
25
81
|
// without charset definition
|
|
26
|
-
ret = data.readText(this.length,
|
|
82
|
+
ret = data.readText(this.length, textEncoding);
|
|
83
|
+
const encoding = options && options.encoding ? options.encoding : 'UTF8';
|
|
84
|
+
const width = getFirebirdCharsetWidth(encoding);
|
|
85
|
+
const charLength = Math.floor(this.length / width);
|
|
86
|
+
if (ret.length > charLength) {
|
|
87
|
+
ret = ret.substring(0, charLength);
|
|
88
|
+
}
|
|
27
89
|
} else {
|
|
28
90
|
ret = data.readBuffer(this.length);
|
|
29
91
|
}
|
|
@@ -49,14 +111,15 @@ class SQLVarNull extends SQLVarText {
|
|
|
49
111
|
//------------------------------------------------------
|
|
50
112
|
|
|
51
113
|
class SQLVarString {
|
|
52
|
-
decode(data, lowerV13) {
|
|
114
|
+
decode(data, lowerV13, options) {
|
|
53
115
|
let ret;
|
|
116
|
+
const textEncoding = resolveTextEncoding(options);
|
|
54
117
|
if (this.subType > 1) {
|
|
55
118
|
// ToDo: with column charset
|
|
56
|
-
ret = data.readString(
|
|
119
|
+
ret = data.readString(textEncoding);
|
|
57
120
|
} else if (this.subType === 0) {
|
|
58
121
|
// without charset definition
|
|
59
|
-
ret = data.readString(
|
|
122
|
+
ret = data.readString(textEncoding);
|
|
60
123
|
} else {
|
|
61
124
|
ret = data.readBuffer();
|
|
62
125
|
}
|
package/package.json
CHANGED
package/poc/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# node-firebird pool — Bug PoC & Fix
|
|
2
|
+
|
|
3
|
+
Proof of concept for three bugs in `lib/pool.js` (node-firebird ≥ 2.x).
|
|
4
|
+
No real Firebird server is needed — a tiny fake TCP server simulates the failure scenario.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## The bugs
|
|
9
|
+
|
|
10
|
+
### Bug 1 — `_creating` stuck forever (critical)
|
|
11
|
+
|
|
12
|
+
**File:** `lib/pool.js` → `Pool.check()`
|
|
13
|
+
|
|
14
|
+
When no idle connection exists, `check()` calls `this.attach()` and increments `_creating`. The counter is only decremented **inside the `attach()` callback**. If the server accepts TCP but never responds to the Firebird wire protocol (e.g. during SRP authentication under load), the callback never fires. `_creating` stays elevated permanently, the slot is lost, and every `pool.get()` caller waits forever.
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
// original code
|
|
18
|
+
self._creating++;
|
|
19
|
+
this.attach(self.options, function (err, db) {
|
|
20
|
+
self._creating--; // ← never reached if attach() hangs
|
|
21
|
+
cb(err, db); // ← caller never notified
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Real-world log signature:**
|
|
26
|
+
```
|
|
27
|
+
*ERRO* Timeout (15000ms) ao aguardar conexão para tenant X.
|
|
28
|
+
Estado do pool: {"dbinuse":0,"_creating":1,"pending":0,"idle":4}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Fix:** `connectTimeout` option — a `setTimeout` wraps the `attach()` call. On expiry, `_creating` is decremented and the caller receives an error immediately. A late-arriving connection (if attach eventually completes) is discarded safely.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
### Bug 2 — `destroy()` does not drain the `pending` queue
|
|
36
|
+
|
|
37
|
+
**File:** `lib/pool.js` → `Pool.destroy()`
|
|
38
|
+
|
|
39
|
+
Callbacks queued in `this.pending` (waiting for a free pool slot) are silently abandoned when `destroy()` is called. Their callers hang indefinitely — there is no error, no timeout, nothing. This is especially harmful when `destroy()` is used as a recovery strategy after a stuck pool.
|
|
40
|
+
|
|
41
|
+
**Fix:** `this.pending.splice(0)` at the start of `destroy()` calls every waiting callback with `Error('Pool is being destroyed')` before any connection is closed.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
### Bug 3 — `pool.get()` after `pool.destroy()` silently accumulates
|
|
46
|
+
|
|
47
|
+
**File:** `lib/pool.js` → `Pool.get()` and `Pool.check()`
|
|
48
|
+
|
|
49
|
+
There is no `_destroyed` flag. Calling `pool.get()` on an already-destroyed pool pushes the callback into `this.pending` and calls `check()`. `check()` returns early because all slots are gone, but the callback is never served. The caller hangs forever.
|
|
50
|
+
|
|
51
|
+
**Fix:** `_destroyed = true` is set in `destroy()`. Both `get()` and `check()` check it and reject immediately with `Error('Pool has been destroyed')`.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
### Bug 4 (minor) — `destroy()` callback never fires when connections are in use
|
|
56
|
+
|
|
57
|
+
**File:** `lib/pool.js` → `Pool.destroy()`
|
|
58
|
+
|
|
59
|
+
The original `destroy()` only calls `detachCallback()` for connections found in `pooldb` (idle). Connections currently in use (`dbinuse > 0`) fall through the `forEach` without decrementing `connectionCount`, so it never reaches zero and the `destroy()` completion callback is never invoked.
|
|
60
|
+
|
|
61
|
+
**Fix:** The `else` branch counts in-use connections down without forcing a detach — releasing them remains the caller's responsibility.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Files
|
|
66
|
+
|
|
67
|
+
| File | Purpose |
|
|
68
|
+
|------|---------|
|
|
69
|
+
| `helpers.js` | Shared logging and fake-server factory |
|
|
70
|
+
| `reproduce.js` | Demonstrates all bugs — exits with code **1** |
|
|
71
|
+
| `reproduce-fixed.js` | Validates all fixes — exits with code **0** |
|
|
72
|
+
| `pool-patched.js` | Drop-in replacement for `lib/pool.js` |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## How to run
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npm install
|
|
80
|
+
|
|
81
|
+
# Show the bugs (process hangs → forced exit 1)
|
|
82
|
+
node reproduce.js
|
|
83
|
+
|
|
84
|
+
# Show the fixes (process exits cleanly → exit 0)
|
|
85
|
+
node reproduce-fixed.js
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Expected output
|
|
91
|
+
|
|
92
|
+
### `node reproduce.js` (bugs present)
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
[fake-server] Listening on 127.0.0.1:13050 ...
|
|
96
|
+
[BUG-1] pool.get() → TCP connects, Firebird protocol hangs, callback NEVER fires
|
|
97
|
+
[pool-state] creating=1 idle=0 inuse=0 pending=0 destroyed=(no flag)
|
|
98
|
+
[pool-state] creating=1 idle=0 inuse=0 pending=0 destroyed=(no flag)
|
|
99
|
+
[BUG-2] Queuing a second get() in pending, then calling destroy()
|
|
100
|
+
[BUG-2] Before destroy — creating=1 idle=0 inuse=0 pending=1 ...
|
|
101
|
+
[BUG-2] After destroy — creating=1 idle=0 inuse=0 pending=1 ... ← pending NOT drained
|
|
102
|
+
[BUG-2] ↑ pending callback was NEVER called — Promise hangs forever
|
|
103
|
+
[BUG-3] pool.get() AFTER pool.destroy() — should be rejected immediately
|
|
104
|
+
[BUG-3] After post-destroy get — creating=1 idle=0 inuse=0 pending=2 ...
|
|
105
|
+
[SUMMARY] Bug 1 confirmed : _creating=1, permanently stuck (slot lost)
|
|
106
|
+
[SUMMARY] Bug 2 confirmed : pending callback from before destroy never fired
|
|
107
|
+
[SUMMARY] Bug 3 confirmed : post-destroy get silently accumulated in pending
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### `node reproduce-fixed.js` (fixes applied)
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
[fake-server] Listening on 127.0.0.1:13051 ...
|
|
114
|
+
[FIX-1] pool.get() — attach() will hang, timeout fires after 1500 ms
|
|
115
|
+
[pool-state] creating=1 idle=0 inuse=0 pending=0 destroyed=false
|
|
116
|
+
[pool-state] creating=1 idle=0 inuse=0 pending=0 destroyed=false
|
|
117
|
+
[FIX-1 ✓ OK] callback received error (expected): "Connection timeout after 1500ms"
|
|
118
|
+
[pool-state] creating=0 idle=0 inuse=0 pending=0 destroyed=false ← back to 0 ✓
|
|
119
|
+
[FIX-4] Queuing a get() in pending, then destroying pool immediately
|
|
120
|
+
[FIX-4 ✓ OK] pending callback received error: "Pool is being destroyed" ← immediate ✓
|
|
121
|
+
[FIX-4] After destroy — creating=0 idle=0 inuse=0 pending=0 destroyed=true
|
|
122
|
+
[FIX-2] pool.get() AFTER pool.destroy() — must be rejected immediately
|
|
123
|
+
[FIX-2 ✓ OK] immediately rejected: "Pool has been destroyed" ← no accumulation ✓
|
|
124
|
+
[SUMMARY] Fix 1 confirmed : _creating returned to 0 after 1500 ms timeout
|
|
125
|
+
[SUMMARY] Fix 2 confirmed : post-destroy get() rejected immediately (_destroyed flag)
|
|
126
|
+
[SUMMARY] Fix 4 confirmed : pending callback drained synchronously by destroy()
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Proposed change to `lib/index.d.ts`
|
|
132
|
+
|
|
133
|
+
Add `connectTimeout` to the `Options` interface:
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
export interface Options {
|
|
137
|
+
// ... existing fields ...
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Timeout in milliseconds for a single pool.get() attach operation.
|
|
141
|
+
* If attach() does not complete within this time the slot is freed,
|
|
142
|
+
* the caller receives an error, and any late-arriving connection is
|
|
143
|
+
* safely discarded. Set to 0 or omit to disable (default: no timeout).
|
|
144
|
+
*
|
|
145
|
+
* Recommended value: 5000–10000 ms depending on network latency and
|
|
146
|
+
* expected Firebird server response time under load.
|
|
147
|
+
*/
|
|
148
|
+
connectTimeout?: number;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Backward compatibility
|
|
155
|
+
|
|
156
|
+
All changes are **fully backward-compatible**:
|
|
157
|
+
|
|
158
|
+
- `connectTimeout` is optional and defaults to disabled (`undefined > 0` is `false`)
|
|
159
|
+
- `_destroyed` defaults to `false` — existing code paths are unchanged
|
|
160
|
+
- `destroy()` draining of `pending` is new behaviour but harmless for callers that did not add pending requests before calling `destroy()`
|
package/poc/helpers.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared helpers used by reproduce.js and reproduce-fixed.js.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const net = require('net');
|
|
8
|
+
|
|
9
|
+
/** Timestamp prefix for log lines (HH:MM:SS.mmm) */
|
|
10
|
+
function ts() {
|
|
11
|
+
return new Date().toISOString().slice(11, 23);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Structured log with fixed-width tag */
|
|
15
|
+
function log(tag, msg) {
|
|
16
|
+
console.log(`[${ts()}] ${tag.padEnd(22)} ${msg}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Compact pool state string */
|
|
20
|
+
function poolState(pool) {
|
|
21
|
+
return (
|
|
22
|
+
`creating=${pool._creating} ` +
|
|
23
|
+
`idle=${pool.pooldb.length} ` +
|
|
24
|
+
`inuse=${pool.dbinuse} ` +
|
|
25
|
+
`pending=${pool.pending.length} ` +
|
|
26
|
+
`destroyed=${pool._destroyed ?? '(no flag)'}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Starts a TCP server that accepts connections but NEVER responds to data.
|
|
32
|
+
*
|
|
33
|
+
* This simulates a Firebird server that:
|
|
34
|
+
* - Completes the TCP three-way handshake (SYN / SYN-ACK / ACK)
|
|
35
|
+
* - Receives the initial op_connect packet from the client
|
|
36
|
+
* - Never sends op_accept_data back
|
|
37
|
+
*
|
|
38
|
+
* Result: node-firebird's attach() callback is never called, reproducing the
|
|
39
|
+
* scenario where _creating is permanently incremented.
|
|
40
|
+
*/
|
|
41
|
+
function startFakeServer(port, onReady) {
|
|
42
|
+
const server = net.createServer((socket) => {
|
|
43
|
+
log('fake-server', `TCP accepted from :${socket.remotePort} — will NOT respond to Firebird protocol`);
|
|
44
|
+
socket.on('data', () => { /* receive op_connect but ignore it */ });
|
|
45
|
+
socket.on('error', () => { /* suppress errors on forced cleanup */ });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
server.on('error', (err) => {
|
|
49
|
+
console.error(`[fake-server] Error: ${err.message}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
server.listen(port, '127.0.0.1', () => {
|
|
54
|
+
log('fake-server', `Listening on 127.0.0.1:${port} (accepts TCP, ignores Firebird wire protocol)`);
|
|
55
|
+
onReady(server);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = { ts, log, poolState, startFakeServer };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "node-firebird-pool-poc",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"node_modules/node-firebird": {
|
|
8
|
+
"version": "2.3.1",
|
|
9
|
+
"resolved": "https://registry.npmjs.org/node-firebird/-/node-firebird-2.3.1.tgz",
|
|
10
|
+
"integrity": "sha512-3yTwiLHwgtLYRv+aS4frzsQEwHMDXkP5Z1SPM/W103TvMemVRoCIaxPYO7axnUrKhgTfPHGXzqC5umYlQail/w==",
|
|
11
|
+
"license": "MPL-2.0"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# For most projects, this workflow file will not need changing; you simply need
|
|
2
|
+
# to commit it to your repository.
|
|
3
|
+
#
|
|
4
|
+
# You may wish to alter this file to override the set of languages analyzed,
|
|
5
|
+
# or to provide custom queries or build logic.
|
|
6
|
+
#
|
|
7
|
+
# ******** NOTE ********
|
|
8
|
+
# We have attempted to detect the languages in your repository. Please check
|
|
9
|
+
# the `language` matrix defined below to confirm you have the correct set of
|
|
10
|
+
# supported CodeQL languages.
|
|
11
|
+
#
|
|
12
|
+
name: "CodeQL"
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches: [ "master" ]
|
|
17
|
+
pull_request:
|
|
18
|
+
# The branches below must be a subset of the branches above
|
|
19
|
+
branches: [ "master" ]
|
|
20
|
+
schedule:
|
|
21
|
+
- cron: '26 2 * * 3'
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
analyze:
|
|
25
|
+
name: Analyze
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
permissions:
|
|
28
|
+
actions: read
|
|
29
|
+
contents: read
|
|
30
|
+
security-events: write
|
|
31
|
+
|
|
32
|
+
strategy:
|
|
33
|
+
fail-fast: false
|
|
34
|
+
matrix:
|
|
35
|
+
language: [ 'javascript' ]
|
|
36
|
+
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
|
37
|
+
# Use only 'java' to analyze code written in Java, Kotlin or both
|
|
38
|
+
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
|
39
|
+
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
|
40
|
+
|
|
41
|
+
steps:
|
|
42
|
+
- name: Checkout repository
|
|
43
|
+
uses: actions/checkout@v3
|
|
44
|
+
|
|
45
|
+
# Initializes the CodeQL tools for scanning.
|
|
46
|
+
- name: Initialize CodeQL
|
|
47
|
+
uses: github/codeql-action/init@v2
|
|
48
|
+
with:
|
|
49
|
+
languages: ${{ matrix.language }}
|
|
50
|
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
51
|
+
# By default, queries listed here will override any specified in a config file.
|
|
52
|
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
53
|
+
|
|
54
|
+
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
|
55
|
+
# queries: security-extended,security-and-quality
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
|
|
59
|
+
# If this step fails, then you should remove it and run the build manually (see below)
|
|
60
|
+
- name: Autobuild
|
|
61
|
+
uses: github/codeql-action/autobuild@v2
|
|
62
|
+
|
|
63
|
+
# ℹ️ Command-line programs to run using the OS shell.
|
|
64
|
+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
|
65
|
+
|
|
66
|
+
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
|
67
|
+
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
|
68
|
+
|
|
69
|
+
# - run: |
|
|
70
|
+
# echo "Run, Build Application using script"
|
|
71
|
+
# ./location_of_script_within_repo/buildscript.sh
|
|
72
|
+
|
|
73
|
+
- name: Perform CodeQL Analysis
|
|
74
|
+
uses: github/codeql-action/analyze@v2
|
|
75
|
+
with:
|
|
76
|
+
category: "/language:${{matrix.language}}"
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
|
|
9
|
+
strategy:
|
|
10
|
+
fail-fast: false
|
|
11
|
+
matrix:
|
|
12
|
+
node: [20, 22, 24]
|
|
13
|
+
firebird: [3, 4, 5]
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v6
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 10
|
|
19
|
+
|
|
20
|
+
- name: Setup FirebirdSQL ${{ matrix.firebird }} container
|
|
21
|
+
run: |
|
|
22
|
+
# Create data directory
|
|
23
|
+
sudo mkdir -p /firebird/data
|
|
24
|
+
sudo chmod 755 /firebird/data
|
|
25
|
+
|
|
26
|
+
# Start Firebird container
|
|
27
|
+
docker run -d \
|
|
28
|
+
--name firebird \
|
|
29
|
+
-e FIREBIRD_ROOT_PASSWORD="masterkey" \
|
|
30
|
+
-e FIREBIRD_CONF_WireCrypt="Enabled" \
|
|
31
|
+
-e FIREBIRD_CONF_AuthServer="Legacy_Auth;Srp;Win_Sspi" \
|
|
32
|
+
-p 3050:3050 \
|
|
33
|
+
-v /firebird/data:/firebird/data \
|
|
34
|
+
firebirdsql/firebird:${{ matrix.firebird }}
|
|
35
|
+
|
|
36
|
+
# Wait for Firebird to be ready
|
|
37
|
+
MAX_RETRIES=30
|
|
38
|
+
RETRY_INTERVAL=2
|
|
39
|
+
echo "Waiting for Firebird to start..."
|
|
40
|
+
FIREBIRD_READY=false
|
|
41
|
+
for i in $(seq 1 $MAX_RETRIES); do
|
|
42
|
+
if docker exec firebird /opt/firebird/bin/isql -user SYSDBA -password masterkey -z 2>&1 | grep -q "ISQL Version"; then
|
|
43
|
+
echo "Firebird is ready!"
|
|
44
|
+
FIREBIRD_READY=true
|
|
45
|
+
break
|
|
46
|
+
fi
|
|
47
|
+
echo "Waiting... ($i/$MAX_RETRIES)"
|
|
48
|
+
sleep $RETRY_INTERVAL
|
|
49
|
+
done
|
|
50
|
+
|
|
51
|
+
if [ "$FIREBIRD_READY" = false ]; then
|
|
52
|
+
echo "ERROR: Firebird failed to start within the timeout period"
|
|
53
|
+
docker ps -a
|
|
54
|
+
docker logs firebird
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Verify Firebird is running
|
|
59
|
+
docker ps -a
|
|
60
|
+
docker logs firebird
|
|
61
|
+
|
|
62
|
+
- name: Use Node.js ${{ matrix.node }}
|
|
63
|
+
uses: actions/setup-node@v3
|
|
64
|
+
with:
|
|
65
|
+
node-version: ${{ matrix.node }}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
- name: Build
|
|
69
|
+
shell: bash
|
|
70
|
+
run: |
|
|
71
|
+
npm ci
|
|
72
|
+
|
|
73
|
+
- name: Test (Linux)
|
|
74
|
+
run: |
|
|
75
|
+
export FIREBIRD_DATA=/firebird/data
|
|
76
|
+
export FIREBIRD_DEBUG=1
|
|
77
|
+
npm test
|
|
78
|
+
|
|
79
|
+
- name: Show Firebird log on failure
|
|
80
|
+
if: failure()
|
|
81
|
+
run: |
|
|
82
|
+
echo "=========================================="
|
|
83
|
+
echo "Firebird Server Log (last 100 lines):"
|
|
84
|
+
echo "=========================================="
|
|
85
|
+
docker exec firebird tail -n 100 /firebird/log/firebird.log || echo "Could not read firebird.log"
|
|
86
|
+
echo ""
|
|
87
|
+
echo "=========================================="
|
|
88
|
+
echo "Docker container status:"
|
|
89
|
+
echo "=========================================="
|
|
90
|
+
docker ps -a
|
|
91
|
+
echo ""
|
|
92
|
+
echo "=========================================="
|
|
93
|
+
echo "Docker container logs:"
|
|
94
|
+
echo "=========================================="
|
|
95
|
+
docker logs firebird --tail 50
|