oracledb 6.0.1 → 6.0.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 +18 -19
- package/SECURITY.md +1 -1
- package/build/Release/{oracledb-6.0.1-darwin-x64.node → oracledb-6.0.3-darwin-x64.node} +0 -0
- package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.0.3-js-buildinfo.txt +1 -0
- package/build/Release/{oracledb-6.0.1-linux-arm64.node → oracledb-6.0.3-linux-arm64.node} +0 -0
- package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/{oracledb-6.0.1-win32-x64.node → oracledb-6.0.3-win32-x64.node} +0 -0
- package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +1 -0
- package/lib/connection.js +1 -0
- package/lib/errors.js +5 -4
- package/lib/pool.js +4 -1
- package/lib/settings.js +1 -1
- package/lib/thin/dbObject.js +17 -5
- package/lib/thin/lob.js +2 -2
- package/lib/thin/pool.js +10 -12
- package/lib/thin/protocol/buffer.js +9 -9
- package/lib/thin/protocol/constants.js +5 -4
- package/lib/thin/protocol/encryptDecrypt.js +24 -12
- package/lib/thin/protocol/messages/auth.js +7 -9
- package/lib/thin/protocol/messages/base.js +10 -10
- package/lib/thin/protocol/messages/execute.js +5 -5
- package/lib/thin/protocol/messages/lobOp.js +3 -3
- package/lib/thin/protocol/messages/withData.js +20 -18
- package/lib/thin/protocol/packet.js +31 -27
- package/lib/thin/protocol/protocol.js +12 -7
- package/lib/thin/sqlnet/connStrategy.js +4 -2
- package/lib/thin/sqlnet/ezConnectResolver.js +9 -5
- package/lib/thin/sqlnet/navNodes.js +3 -3
- package/lib/thin/sqlnet/networkSession.js +10 -10
- package/lib/thin/sqlnet/ntTcp.js +38 -25
- package/lib/thin/sqlnet/packet.js +8 -8
- package/lib/thin/sqlnet/paramParser.js +5 -8
- package/lib/thin/statement.js +1 -0
- package/lib/thin/util.js +21 -0
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/build/Release/oracledb-6.0.1-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.1-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.1-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.1-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.1-win32-x64.node-buildinfo.txt +0 -1
- /package/build/Release/{oracledb-6.0.1-linux-x64.node → oracledb-6.0.3-linux-x64.node} +0 -0
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# node-oracledb version 6.0.
|
|
1
|
+
# node-oracledb version 6.0.3
|
|
2
2
|
|
|
3
3
|
The node-oracledb add-on for Node.js powers high performance Oracle Database
|
|
4
4
|
applications. Applications can be written in TypeScript, or directly in
|
|
5
5
|
JavaScript.
|
|
6
6
|
|
|
7
|
-
Use node-oracledb 6.0.
|
|
7
|
+
Use node-oracledb 6.0.3 to connect Node.js 14.6, or later, to Oracle
|
|
8
8
|
Database. Older versions of node-oracledb may work with older versions of
|
|
9
9
|
Node.js.
|
|
10
10
|
|
|
@@ -20,32 +20,30 @@ See [Getting Started with Node-oracledb][1] and [Quick Start Node-oracledb Insta
|
|
|
20
20
|
|
|
21
21
|
## Documentation
|
|
22
22
|
|
|
23
|
-
See [Documentation for the Oracle Database Node.js Add-on][
|
|
23
|
+
See [Documentation for the Oracle Database Node.js Add-on][9] and the [release
|
|
24
|
+
notes][10].
|
|
24
25
|
|
|
25
26
|
## Examples
|
|
26
27
|
|
|
27
|
-
See the [examples][
|
|
28
|
+
See the [examples][7] directory. Start with [examples/example.js][8].
|
|
28
29
|
|
|
29
30
|
## Help
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
Questions about node-oracledb can be posted on [GitHub][3] or [Slack][5] ([link
|
|
33
|
+
to join Slack][6]).
|
|
33
34
|
|
|
34
35
|
## <a name="testing"></a> Tests
|
|
35
36
|
|
|
36
|
-
To run the test suite see [test/README][
|
|
37
|
+
To run the test suite see [test/README][11].
|
|
37
38
|
|
|
38
39
|
## Contributing
|
|
39
40
|
|
|
40
41
|
This project welcomes contributions from the community. Before submitting a
|
|
41
|
-
pull request, please [review our contribution guide][
|
|
42
|
-
|
|
43
|
-
Oracle gratefully acknowledges the contributions to node-oracledb that have
|
|
44
|
-
been made by the community.
|
|
42
|
+
pull request, please [review our contribution guide][12].
|
|
45
43
|
|
|
46
44
|
## Security
|
|
47
45
|
|
|
48
|
-
Please consult the [security guide]
|
|
46
|
+
Please consult the [security guide][13] for our responsible security
|
|
49
47
|
vulnerability disclosure process.
|
|
50
48
|
|
|
51
49
|
## License
|
|
@@ -74,13 +72,14 @@ limitations under the License.
|
|
|
74
72
|
|
|
75
73
|
[1]: https://node-oracledb.readthedocs.io/en/latest/user_guide/introduction.html#getstarted
|
|
76
74
|
[2]: https://node-oracledb.readthedocs.io/en/latest/user_guide/installation.html#quickstart
|
|
77
|
-
[3]: https://github.com/oracle/node-oracledb/
|
|
75
|
+
[3]: https://github.com/oracle/node-oracledb/discussions
|
|
78
76
|
[4]: https://oracle.github.io/node-oracledb
|
|
79
77
|
[5]: https://node-oracledb.slack.com/
|
|
80
78
|
[6]: https://join.slack.com/t/node-oracledb/shared_invite/enQtNDU4Mjc2NzM5OTA2LWMzY2ZlZDY5MDdlMGZiMGRkY2IzYjI5OGU4YTEzZWM5YjQ3ODUzMjcxNWQyNzE4MzM5YjNkYjVmNDk5OWU5NDM
|
|
81
|
-
[
|
|
82
|
-
[
|
|
83
|
-
[
|
|
84
|
-
[
|
|
85
|
-
[
|
|
86
|
-
[
|
|
79
|
+
[7]: https://github.com/oracle/node-oracledb/blob/main/examples
|
|
80
|
+
[8]: https://github.com/oracle/node-oracledb/blob/main/examples/example.js
|
|
81
|
+
[9]: https://node-oracledb.readthedocs.io/en/latest/
|
|
82
|
+
[10]: https://node-oracledb.readthedocs.io/en/latest/release_notes.html
|
|
83
|
+
[11]: https://github.com/oracle/node-oracledb/blob/main/test/README.md
|
|
84
|
+
[12]: https://github.com/oracle/node-oracledb/blob/main/CONTRIBUTING.md
|
|
85
|
+
[13]: https://github.com/oracle/node-oracledb/blob/main/SECURITY.md
|
package/SECURITY.md
CHANGED
|
@@ -21,7 +21,7 @@ security features are welcome on GitHub Issues.
|
|
|
21
21
|
|
|
22
22
|
Security updates will be released on a regular cadence. Many of our projects
|
|
23
23
|
will typically release security fixes in conjunction with the
|
|
24
|
-
|
|
24
|
+
Oracle Critical Patch Update program. Additional
|
|
25
25
|
information, including past advisories, is available on our [security alerts][4]
|
|
26
26
|
page.
|
|
27
27
|
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.0.3-darwin-x64.node v16.20.0 39d4fe42c06aaccc3feab18cc77fb27025d1fcbb ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Wed, 05 Jul 2023 21:49:52 GMT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
39d4fe42c06aaccc3feab18cc77fb27025d1fcbb
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.0.3-linux-arm64.node v16.20.0 39d4fe42c06aaccc3feab18cc77fb27025d1fcbb ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Wed, 05 Jul 2023 21:29:48 GMT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.0.3-linux-x64.node v16.20.0 39d4fe42c06aaccc3feab18cc77fb27025d1fcbb ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Thu, 06 Jul 2023 06:38:15 GMT
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.0.3-win32-x64.node v16.19.0 39d4fe42c06aaccc3feab18cc77fb27025d1fcbb ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Thu, 06 Jul 2023 06:41:18 GMT
|
package/lib/connection.js
CHANGED
package/lib/errors.js
CHANGED
|
@@ -161,7 +161,8 @@ const ERR_INVALID_SID = 519;
|
|
|
161
161
|
const ERR_TNS_NAMES_FILE_MISSING = 520;
|
|
162
162
|
const ERR_CONNECTION_EOF = 521;
|
|
163
163
|
|
|
164
|
-
// define mapping for ODPI-C errors that need to be wrapped
|
|
164
|
+
// define mapping for ODPI-C, OCI & ORA errors that need to be wrapped
|
|
165
|
+
// with NJS errors
|
|
165
166
|
const adjustErrorXref = new Map();
|
|
166
167
|
adjustErrorXref.set("DPI-1010", ERR_CONNECTION_CLOSED);
|
|
167
168
|
adjustErrorXref.set("DPI-1024", [ERR_INVALID_COLL_INDEX_GET, 'at index ([0-9]+) does']);
|
|
@@ -327,7 +328,7 @@ messages.set(ERR_MISSING_CREDENTIALS, // NJS-101
|
|
|
327
328
|
messages.set(ERR_UNEXPECTED_END_OF_DATA, // NJS-102
|
|
328
329
|
'unexpected end of data: want %d bytes but only %d bytes are available');
|
|
329
330
|
messages.set(ERR_UNEXPECTED_MESSAGE_TYPE, // NJS-103
|
|
330
|
-
'unexpected message type %d received');
|
|
331
|
+
'unexpected message type %d received at position %d of packet %d');
|
|
331
332
|
messages.set(ERR_POOL_HAS_BUSY_CONNECTIONS, // NJS-104
|
|
332
333
|
'connection pool cannot be closed because connections are busy');
|
|
333
334
|
messages.set(ERR_NAN_VALUE, // NJS-105
|
|
@@ -343,9 +344,9 @@ messages.set(ERR_INVALID_TYPE_NUM, // NJS-109
|
|
|
343
344
|
messages.set(ERR_INVALID_ORACLE_TYPE_NUM, // NJS-110
|
|
344
345
|
'invalid Oracle type number %d [csfrm: %d]');
|
|
345
346
|
messages.set(ERR_UNEXPECTED_NEGATIVE_INTEGER, // NJS-111
|
|
346
|
-
'internal error: read a negative integer when expecting a positive integer');
|
|
347
|
+
'internal error: read a negative integer when expecting a positive integer at position %d of packet %d');
|
|
347
348
|
messages.set(ERR_INTEGER_TOO_LARGE, // NJS-112
|
|
348
|
-
'internal error: read integer of length %d when expecting integer of no more than length %d');
|
|
349
|
+
'internal error: read integer of length %d when expecting integer of no more than length %d at position %d of packet %d');
|
|
349
350
|
messages.set(ERR_UNEXPECTED_DATA, // NJS-113
|
|
350
351
|
'unexpected data received: %s');
|
|
351
352
|
messages.set(ERR_OSON_FIELD_NAME_LIMITATION, // NJS-114
|
package/lib/pool.js
CHANGED
|
@@ -47,6 +47,7 @@ class Pool extends EventEmitter {
|
|
|
47
47
|
this._timeOfReset = this._createdDate = Date.now();
|
|
48
48
|
this._sessionCallback = undefined;
|
|
49
49
|
this._connRequestQueue = [];
|
|
50
|
+
this._connectionClass = settings.connectionClass;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
//---------------------------------------------------------------------------
|
|
@@ -376,7 +377,9 @@ class Pool extends EventEmitter {
|
|
|
376
377
|
errors.assertParamValue(nodbUtil.isObject(a1), 1);
|
|
377
378
|
options = this._verifyGetConnectionOptions(a1);
|
|
378
379
|
}
|
|
379
|
-
|
|
380
|
+
|
|
381
|
+
// get connection class value from pool
|
|
382
|
+
options.connectionClass = this._connectionClass;
|
|
380
383
|
|
|
381
384
|
// if pool is draining/closed, throw an appropriate error
|
|
382
385
|
this._checkPoolOpen(true);
|
package/lib/settings.js
CHANGED
|
@@ -69,7 +69,7 @@ class Settings {
|
|
|
69
69
|
// database are returned as though they used the JavaScript time zone
|
|
70
70
|
// setting. TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE data
|
|
71
71
|
// are returned in native JavaScript format (since they contain time zone
|
|
72
|
-
// information).
|
|
72
|
+
// information). This is used only in Thick mode (from node-oracledb 6.0.0).
|
|
73
73
|
//---------------------------------------------------------------------------
|
|
74
74
|
_getDateComponents(useLocal, date) {
|
|
75
75
|
if (useLocal) {
|
package/lib/thin/dbObject.js
CHANGED
|
@@ -35,6 +35,19 @@ const { GrowableBuffer } = require('./protocol/buffer.js');
|
|
|
35
35
|
|
|
36
36
|
class DbObjectPickleBuffer extends GrowableBuffer {
|
|
37
37
|
|
|
38
|
+
//---------------------------------------------------------------------------
|
|
39
|
+
// _readBytesWithLength()
|
|
40
|
+
//
|
|
41
|
+
// Helper function that processes the number of bytes (if needed) and then
|
|
42
|
+
// acquires the specified number of bytes from the buffer.
|
|
43
|
+
//---------------------------------------------------------------------------
|
|
44
|
+
_readBytesWithLength(numBytes) {
|
|
45
|
+
if (numBytes === constants.TNS_LONG_LENGTH_INDICATOR) {
|
|
46
|
+
numBytes = this.readUInt32BE();
|
|
47
|
+
}
|
|
48
|
+
return this.readBytes(numBytes);
|
|
49
|
+
}
|
|
50
|
+
|
|
38
51
|
//---------------------------------------------------------------------------
|
|
39
52
|
// getIsAtomicNull()
|
|
40
53
|
//
|
|
@@ -349,12 +362,12 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
349
362
|
return buf.readBinaryInteger();
|
|
350
363
|
case types.DB_TYPE_VARCHAR:
|
|
351
364
|
case types.DB_TYPE_CHAR:
|
|
352
|
-
return buf.readStr(constants.
|
|
365
|
+
return buf.readStr(constants.CSFRM_IMPLICIT);
|
|
353
366
|
case types.DB_TYPE_NVARCHAR:
|
|
354
367
|
case types.DB_TYPE_NCHAR:
|
|
355
|
-
return buf.readStr(constants.
|
|
368
|
+
return buf.readStr(constants.CSFRM_NCHAR);
|
|
356
369
|
case types.DB_TYPE_RAW:
|
|
357
|
-
return buf.readBytesWithLength();
|
|
370
|
+
return Buffer.from(buf.readBytesWithLength());
|
|
358
371
|
case types.DB_TYPE_BINARY_DOUBLE:
|
|
359
372
|
return buf.readBinaryDouble();
|
|
360
373
|
case types.DB_TYPE_BINARY_FLOAT:
|
|
@@ -365,7 +378,6 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
365
378
|
case types.DB_TYPE_TIMESTAMP_LTZ:
|
|
366
379
|
case types.DB_TYPE_TIMESTAMP_TZ:
|
|
367
380
|
return buf.readOracleDate(false);
|
|
368
|
-
case types.DB_TYPE_BLOB:
|
|
369
381
|
case types.DB_TYPE_BOOLEAN:
|
|
370
382
|
return buf.readBool();
|
|
371
383
|
case types.DB_TYPE_OBJECT:
|
|
@@ -374,7 +386,7 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
374
386
|
return null;
|
|
375
387
|
obj = new ThinDbObjectImpl(typeClass);
|
|
376
388
|
if (obj._objType.isCollection || this._objType.isCollection) {
|
|
377
|
-
obj.packedData = buf.readBytesWithLength();
|
|
389
|
+
obj.packedData = Buffer.from(buf.readBytesWithLength());
|
|
378
390
|
} else {
|
|
379
391
|
obj._unpackDataFromBuf(buf);
|
|
380
392
|
}
|
package/lib/thin/lob.js
CHANGED
|
@@ -121,10 +121,10 @@ class ThinLobImpl extends LobImpl {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
getCsfrm() {
|
|
124
|
-
if (this.dbType._csfrm !== constants.
|
|
124
|
+
if (this.dbType._csfrm !== constants.CSFRM_NCHAR) {
|
|
125
125
|
if (this._locator[constants.TNS_LOB_LOC_OFFSET_FLAG_3] &
|
|
126
126
|
constants.TNS_LOB_LOC_FLAGS_VAR_LENGTH_CHARSET) {
|
|
127
|
-
return constants.
|
|
127
|
+
return constants.CSFRM_NCHAR;
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
return this.dbType._csfrm;
|
package/lib/thin/pool.js
CHANGED
|
@@ -144,13 +144,13 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
//---------------------------------------------------------------------------
|
|
147
|
-
//
|
|
147
|
+
// credentials are obfuscated and stored in an object(userConfig) during
|
|
148
|
+
// pool creation. _getConnAttrs() method is used to deobfuscate encrypted
|
|
149
|
+
// credentials for creating new connections
|
|
148
150
|
//---------------------------------------------------------------------------
|
|
149
|
-
async
|
|
151
|
+
async _getConnAttrs() {
|
|
150
152
|
let accessToken;
|
|
151
|
-
const
|
|
152
|
-
conn._pool = this;
|
|
153
|
-
let clonedAttrs = Object.assign({}, connAttrs);
|
|
153
|
+
const clonedAttrs = Object.assign({}, this._userConfig);
|
|
154
154
|
if (clonedAttrs.password === null) {
|
|
155
155
|
clonedAttrs.password = protocolUtil.getDeobfuscatedValue(this._password,
|
|
156
156
|
this._obfuscatedPassword);
|
|
@@ -204,9 +204,7 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
204
204
|
protocolUtil.getDeobfuscatedValue(this._privateKey,
|
|
205
205
|
this._obfuscatedPrivateKey);
|
|
206
206
|
}
|
|
207
|
-
|
|
208
|
-
clonedAttrs = null;
|
|
209
|
-
return conn;
|
|
207
|
+
return clonedAttrs;
|
|
210
208
|
}
|
|
211
209
|
|
|
212
210
|
//---------------------------------------------------------------------------
|
|
@@ -214,9 +212,6 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
214
212
|
// create new connection and return it
|
|
215
213
|
//---------------------------------------------------------------------------
|
|
216
214
|
async getConnection() {
|
|
217
|
-
if (settings.connectionClass !== '') {
|
|
218
|
-
this._userConfig.connectionClass = settings.connectionClass;
|
|
219
|
-
}
|
|
220
215
|
return await this.acquire();
|
|
221
216
|
}
|
|
222
217
|
|
|
@@ -318,8 +313,11 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
318
313
|
// Grows the pool to include the specified number of connections.
|
|
319
314
|
//---------------------------------------------------------------------------
|
|
320
315
|
async _growPool(numConns) {
|
|
316
|
+
const clonedAttrs = await this._getConnAttrs();
|
|
321
317
|
while (numConns > 0) {
|
|
322
|
-
|
|
318
|
+
const conn = new ThinConnectionImpl();
|
|
319
|
+
conn._pool = this;
|
|
320
|
+
await conn.connect(clonedAttrs);
|
|
323
321
|
conn._newSession = true;
|
|
324
322
|
conn._dropSess = false;
|
|
325
323
|
conn._lastTimeUsed = Date.now();
|
|
@@ -92,13 +92,13 @@ class BaseBuffer {
|
|
|
92
92
|
return 0;
|
|
93
93
|
} else if (size & 0x80) {
|
|
94
94
|
if (!signed) {
|
|
95
|
-
errors.throwErr(errors.ERR_UNEXPECTED_NEGATIVE_INTEGER);
|
|
95
|
+
errors.throwErr(errors.ERR_UNEXPECTED_NEGATIVE_INTEGER, this.pos, this.packetNum);
|
|
96
96
|
}
|
|
97
97
|
isNegative = true;
|
|
98
98
|
size = size & 0x7f;
|
|
99
99
|
}
|
|
100
100
|
if (size > maxSize) {
|
|
101
|
-
errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, size, maxSize);
|
|
101
|
+
errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, size, maxSize, this.pos, this.packetNum);
|
|
102
102
|
}
|
|
103
103
|
if (skip) {
|
|
104
104
|
this.skipBytes(size);
|
|
@@ -375,18 +375,18 @@ class BaseBuffer {
|
|
|
375
375
|
const obj = {};
|
|
376
376
|
let numBytes = this.readUB4();
|
|
377
377
|
if (numBytes > 0)
|
|
378
|
-
obj.toid = this.readBytesWithLength();
|
|
378
|
+
obj.toid = Buffer.from(this.readBytesWithLength());
|
|
379
379
|
numBytes = this.readUB4();
|
|
380
380
|
if (numBytes > 0)
|
|
381
|
-
obj.oid = this.readBytesWithLength();
|
|
381
|
+
obj.oid = Buffer.from(this.readBytesWithLength());
|
|
382
382
|
numBytes = this.readUB4();
|
|
383
383
|
if (numBytes > 0)
|
|
384
|
-
obj.snapshot = this.readBytesWithLength();
|
|
384
|
+
obj.snapshot = Buffer.from(this.readBytesWithLength());
|
|
385
385
|
this.skipUB2(); // version
|
|
386
386
|
numBytes = this.readUB4();
|
|
387
387
|
this.skipUB2(); // flags
|
|
388
388
|
if (numBytes > 0)
|
|
389
|
-
obj.packedData = this.readBytesWithLength();
|
|
389
|
+
obj.packedData = Buffer.from(this.readBytesWithLength());
|
|
390
390
|
return obj;
|
|
391
391
|
}
|
|
392
392
|
|
|
@@ -465,7 +465,7 @@ class BaseBuffer {
|
|
|
465
465
|
if (!buf) {
|
|
466
466
|
return null;
|
|
467
467
|
}
|
|
468
|
-
if (csfrm === constants.
|
|
468
|
+
if (csfrm === constants.CSFRM_IMPLICIT)
|
|
469
469
|
return buf.toString();
|
|
470
470
|
|
|
471
471
|
// need a copy of the buffer since swap16() changes the buffer in place and
|
|
@@ -748,7 +748,7 @@ class BaseBuffer {
|
|
|
748
748
|
const ptr = this.reserveBytes(length);
|
|
749
749
|
if (type === types.DB_TYPE_DATE || type == types.DB_TYPE_TIMESTAMP) {
|
|
750
750
|
const year = date.getFullYear();
|
|
751
|
-
ptr[0] = Math.
|
|
751
|
+
ptr[0] = Math.trunc(year / 100) + 100;
|
|
752
752
|
ptr[1] = year % 100 + 100;
|
|
753
753
|
ptr[2] = date.getMonth() + 1;
|
|
754
754
|
ptr[3] = date.getDate();
|
|
@@ -757,7 +757,7 @@ class BaseBuffer {
|
|
|
757
757
|
ptr[6] = date.getSeconds() + 1;
|
|
758
758
|
} else {
|
|
759
759
|
const year = date.getUTCFullYear();
|
|
760
|
-
ptr[0] = Math.
|
|
760
|
+
ptr[0] = Math.trunc(year / 100) + 100;
|
|
761
761
|
ptr[1] = year % 100 + 100;
|
|
762
762
|
ptr[2] = date.getUTCMonth() + 1;
|
|
763
763
|
ptr[3] = date.getUTCDate();
|
|
@@ -40,7 +40,12 @@ module.exports = {
|
|
|
40
40
|
constants.VERSION_MAJOR << 24 |
|
|
41
41
|
constants.VERSION_MINOR << 20 |
|
|
42
42
|
constants.VERSION_PATCH << 12,
|
|
43
|
+
CSFRM_IMPLICIT: constants.CSFRM_IMPLICIT,
|
|
44
|
+
CSFRM_NCHAR: constants.CSFRM_NCHAR,
|
|
43
45
|
DRIVER_NAME: constants.DEFAULT_DRIVER_NAME + ' thn',
|
|
46
|
+
PURITY_DEFAULT: constants.PURITY_DEFAULT,
|
|
47
|
+
PURITY_NEW: constants.PURITY_NEW,
|
|
48
|
+
PURITY_SELF: constants.PURITY_SELF,
|
|
44
49
|
SYSASM: constants.SYSASM,
|
|
45
50
|
SYSBKP: constants.SYSBKP,
|
|
46
51
|
SYSDBA: constants.SYSDBA,
|
|
@@ -88,10 +93,6 @@ module.exports = {
|
|
|
88
93
|
TNS_MARKER_TYPE_BREAK: 1,
|
|
89
94
|
TNS_MARKER_TYPE_RESET: 2,
|
|
90
95
|
|
|
91
|
-
// charset forms
|
|
92
|
-
TNS_CS_IMPLICIT: 1,
|
|
93
|
-
TNS_CS_NCHAR: 2,
|
|
94
|
-
|
|
95
96
|
// data types
|
|
96
97
|
TNS_DATA_TYPE_DEFAULT: 0,
|
|
97
98
|
TNS_DATA_TYPE_VARCHAR: 1,
|
|
@@ -138,18 +138,30 @@ class EncryptDecrypt {
|
|
|
138
138
|
if (newPassword) {
|
|
139
139
|
newPasswordBytes = Buffer.from(newPassword, 'utf8');
|
|
140
140
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
crypto.randomFillSync(sessionKeyPartb
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
141
|
+
const sessionKeyParta = this._decrypt(passwordHash, encodedServerKey);
|
|
142
|
+
const sessionKeyPartb = Buffer.alloc(sessionKeyParta.length);
|
|
143
|
+
crypto.randomFillSync(sessionKeyPartb);
|
|
144
|
+
const encodedClientKey = this._encrypt(passwordHash, sessionKeyPartb);
|
|
145
|
+
|
|
146
|
+
if (sessionKeyParta.length === 48) {
|
|
147
|
+
authObj.sessionKey = encodedClientKey.slice().toString('hex').toUpperCase().slice(0, 96);
|
|
148
|
+
const buf = Buffer.alloc(24);
|
|
149
|
+
for (let i = 16; i <= 40; i++) {
|
|
150
|
+
buf[i - 16] = sessionKeyParta[i] ^ sessionKeyPartb[i];
|
|
151
|
+
}
|
|
152
|
+
const part1 = crypto.createHash("md5").update(buf.subarray(0, 16)).digest();
|
|
153
|
+
const part2 = crypto.createHash("md5").update(buf.subarray(16)).digest();
|
|
154
|
+
authObj.comboKey = Buffer.concat([part1, part2]).slice(0, keyLen);
|
|
155
|
+
} else {
|
|
156
|
+
authObj.sessionKey = encodedClientKey.slice().toString('hex').toUpperCase().slice(0, 64);
|
|
157
|
+
const mixingSalt = Buffer.from(sessionData['AUTH_PBKDF2_CSK_SALT'], 'hex');
|
|
158
|
+
iterations = Number(sessionData['AUTH_PBKDF2_SDER_COUNT']);
|
|
159
|
+
const partABKey = Buffer.concat([sessionKeyPartb.slice(0, keyLen), sessionKeyParta.slice(0, keyLen)]);
|
|
160
|
+
const partABKeyStr = partABKey.toString('hex').toUpperCase();
|
|
161
|
+
const partABKeyBuffer = Buffer.from(partABKeyStr, 'utf8');
|
|
162
|
+
authObj.comboKey = crypto.pbkdf2Sync(partABKeyBuffer, mixingSalt,
|
|
163
|
+
iterations, keyLen, 'sha512');
|
|
164
|
+
}
|
|
153
165
|
|
|
154
166
|
let salt = Buffer.alloc(16);
|
|
155
167
|
if (!verifier11G) {
|
|
@@ -29,12 +29,11 @@
|
|
|
29
29
|
const { Buffer } = require('buffer');
|
|
30
30
|
const constants = require("../constants.js");
|
|
31
31
|
const errors = require("../../../errors.js");
|
|
32
|
-
const os = require("os");
|
|
33
32
|
const process = require("process");
|
|
34
33
|
const ED = require("../encryptDecrypt.js");
|
|
35
34
|
const Message = require("./base.js");
|
|
36
35
|
const util = require("../../util.js");
|
|
37
|
-
|
|
36
|
+
const cInfo = util.CLIENT_INFO;
|
|
38
37
|
const crypto = require('crypto');
|
|
39
38
|
|
|
40
39
|
/**
|
|
@@ -184,11 +183,10 @@ class AuthMessage extends Message {
|
|
|
184
183
|
buf.writeBytesWithLength(Buffer.from(this.username));
|
|
185
184
|
}
|
|
186
185
|
buf.writeKeyValue("AUTH_TERMINAL", "unknown");
|
|
187
|
-
buf.writeKeyValue("AUTH_PROGRAM_NM",
|
|
188
|
-
buf.writeKeyValue("AUTH_MACHINE",
|
|
189
|
-
buf.writeKeyValue("AUTH_PID",
|
|
190
|
-
buf.writeKeyValue("AUTH_SID",
|
|
191
|
-
|
|
186
|
+
buf.writeKeyValue("AUTH_PROGRAM_NM", cInfo.program);
|
|
187
|
+
buf.writeKeyValue("AUTH_MACHINE", cInfo.hostName);
|
|
188
|
+
buf.writeKeyValue("AUTH_PID", cInfo.pid);
|
|
189
|
+
buf.writeKeyValue("AUTH_SID", cInfo.userName);
|
|
192
190
|
} else {
|
|
193
191
|
let numPairs = 0;
|
|
194
192
|
|
|
@@ -302,11 +300,11 @@ class AuthMessage extends Message {
|
|
|
302
300
|
let numParams = buf.readUB2();
|
|
303
301
|
for (let i = 0; i < numParams;i++) {
|
|
304
302
|
buf.skipUB4();
|
|
305
|
-
let key = buf.readStr(constants.
|
|
303
|
+
let key = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
306
304
|
let value = "";
|
|
307
305
|
let numBytes = buf.readUB4();
|
|
308
306
|
if (numBytes > 0) {
|
|
309
|
-
value = buf.readStr(constants.
|
|
307
|
+
value = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
310
308
|
}
|
|
311
309
|
let flag = buf.readUB4();
|
|
312
310
|
if (key === "AUTH_VFR_DATA") {
|
|
@@ -149,7 +149,7 @@ class Message {
|
|
|
149
149
|
for (let i = 0; i < numEntries; i++) {
|
|
150
150
|
buf.skipUB2(); // skip chunk length
|
|
151
151
|
|
|
152
|
-
this.errorInfo.batchErrors[i].message = buf.readStr(constants.
|
|
152
|
+
this.errorInfo.batchErrors[i].message = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
153
153
|
buf.skipBytes(2); // ignore end marker
|
|
154
154
|
}
|
|
155
155
|
}
|
|
@@ -158,7 +158,7 @@ class Message {
|
|
|
158
158
|
this.errorInfo.rowCount = buf.readUB8(); // row number (extended)
|
|
159
159
|
if (this.errorInfo.num !== 0) {
|
|
160
160
|
this.errorOccurred = true;
|
|
161
|
-
this.errorInfo.message = buf.readStr(constants.
|
|
161
|
+
this.errorInfo.message = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
162
162
|
/*
|
|
163
163
|
* Remove ending newline from ORA error message
|
|
164
164
|
*/
|
|
@@ -175,7 +175,7 @@ class Message {
|
|
|
175
175
|
let numBytes = buf.readUB2(); // length of error message
|
|
176
176
|
buf.skipUB2(); // flags
|
|
177
177
|
if (this.errorInfo.num != 0 && numBytes > 0) {
|
|
178
|
-
this.errorInfo.message = buf.readStr(constants.
|
|
178
|
+
this.errorInfo.message = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
179
179
|
}
|
|
180
180
|
this.errorInfo.isWarning = true;
|
|
181
181
|
}
|
|
@@ -215,7 +215,7 @@ class Message {
|
|
|
215
215
|
} else if (messageType === constants.TNS_MSG_TYPE_SERVER_SIDE_PIGGYBACK) {
|
|
216
216
|
this.processServerSidePiggyBack(buf);
|
|
217
217
|
} else {
|
|
218
|
-
errors.throwErr(errors.ERR_UNEXPECTED_MESSAGE_TYPE, messageType);
|
|
218
|
+
errors.throwErr(errors.ERR_UNEXPECTED_MESSAGE_TYPE, messageType, buf.pos, buf.packetNum);
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
|
|
@@ -230,8 +230,8 @@ class Message {
|
|
|
230
230
|
|| (opcode === constants.TNS_SERVER_PIGGYBACK_TRACE_EVENT)) {
|
|
231
231
|
// pass
|
|
232
232
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_OS_PID_MTS) {
|
|
233
|
-
|
|
234
|
-
buf.
|
|
233
|
+
buf.skipUB2();
|
|
234
|
+
buf.skipBytesChunked();
|
|
235
235
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_SYNC) {
|
|
236
236
|
buf.skipUB2(); // skip number of DTYs
|
|
237
237
|
buf.skipUB1(); // skip length of DTYs
|
|
@@ -240,11 +240,11 @@ class Message {
|
|
|
240
240
|
for (let i = 0; i < num_elements; i++) {
|
|
241
241
|
let temp16 = buf.readUB2();
|
|
242
242
|
if (temp16 > 0) { // skip key
|
|
243
|
-
buf.
|
|
243
|
+
buf.skipBytesChunked();
|
|
244
244
|
}
|
|
245
245
|
temp16 = buf.readUB2();
|
|
246
246
|
if (temp16 > 0) { // skip value
|
|
247
|
-
buf.
|
|
247
|
+
buf.skipBytesChunked();
|
|
248
248
|
}
|
|
249
249
|
buf.skipUB2(); // skip flags
|
|
250
250
|
buf.skipUB4(); // skip overall flags
|
|
@@ -271,11 +271,11 @@ class Message {
|
|
|
271
271
|
for (let i = 0; i < num_elements; ++i) {
|
|
272
272
|
let temp16 = buf.readUB2();
|
|
273
273
|
if (temp16 > 0) { // skip key
|
|
274
|
-
buf.
|
|
274
|
+
buf.skipBytesChunked();
|
|
275
275
|
}
|
|
276
276
|
temp16 = buf.readUB2();
|
|
277
277
|
if (temp16 > 0) { // skip value
|
|
278
|
-
buf.
|
|
278
|
+
buf.skipBytesChunked();
|
|
279
279
|
}
|
|
280
280
|
buf.skipUB2(); // skip flags
|
|
281
281
|
}
|
|
@@ -77,21 +77,21 @@ class ExecuteMessage extends MessageWithData {
|
|
|
77
77
|
dmlOptions = constants.TNS_EXEC_OPTION_IMPLICIT_RESULTSET;
|
|
78
78
|
options |= constants.TNS_EXEC_OPTION_EXECUTE;
|
|
79
79
|
}
|
|
80
|
-
if (stmt.cursorId
|
|
80
|
+
if (stmt.cursorId === 0 || stmt.isDdl) {
|
|
81
81
|
options |= constants.TNS_EXEC_OPTION_PARSE;
|
|
82
82
|
}
|
|
83
83
|
if (stmt.isQuery) {
|
|
84
84
|
if (this.parseOnly) {
|
|
85
85
|
options |= constants.TNS_EXEC_OPTION_DESCRIBE;
|
|
86
86
|
} else {
|
|
87
|
-
if (this.options.prefetchRows > 0) {
|
|
88
|
-
options |= constants.TNS_EXEC_OPTION_FETCH;
|
|
89
|
-
}
|
|
90
87
|
if (stmt.cursorId === 0 || stmt.requiresDefine) {
|
|
91
88
|
numIters = this.options.prefetchRows;
|
|
92
89
|
} else {
|
|
93
90
|
numIters = this.options.fetchArraySize;
|
|
94
91
|
}
|
|
92
|
+
if (numIters > 0 && !stmt.noPrefetch) {
|
|
93
|
+
options |= constants.TNS_EXEC_OPTION_FETCH;
|
|
94
|
+
}
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
if (!stmt.isPlSql && !this.parseOnly) {
|
|
@@ -276,7 +276,7 @@ class ExecuteMessage extends MessageWithData {
|
|
|
276
276
|
if (this.currentRow === 0) {
|
|
277
277
|
let stmt = this.statement;
|
|
278
278
|
if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !this.parseOnly && !stmt.requiresDefine && !stmt.isDdl && !this.batchErrors) {
|
|
279
|
-
if (stmt.isQuery && !stmt.requiresDefine && this.options.prefetchRows > 0) {
|
|
279
|
+
if (stmt.isQuery && !stmt.requiresDefine && !stmt.noPrefetch && this.options.prefetchRows > 0) {
|
|
280
280
|
this.functionCode = constants.TNS_FUNC_REEXECUTE_AND_FETCH;
|
|
281
281
|
} else {
|
|
282
282
|
this.functionCode = constants.TNS_FUNC_REEXECUTE;
|
|
@@ -116,7 +116,7 @@ class LobOpMessage extends Message {
|
|
|
116
116
|
buf.writeBytes(this.destLobImpl._locator);
|
|
117
117
|
}
|
|
118
118
|
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP) {
|
|
119
|
-
if (this.sourceLobImpl.dbType._csfrm === constants.
|
|
119
|
+
if (this.sourceLobImpl.dbType._csfrm === constants.CSFRM_NCHAR) {
|
|
120
120
|
buf.caps.checkNCharsetId();
|
|
121
121
|
buf.writeUB4(constants.TNS_CHARSET_UTF16);
|
|
122
122
|
} else {
|
|
@@ -128,7 +128,7 @@ class LobOpMessage extends Message {
|
|
|
128
128
|
buf.writeUInt8(constants.TNS_MSG_TYPE_LOB_DATA);
|
|
129
129
|
if (this.sourceLobImpl.dbType._oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
|
|
130
130
|
data = this.data;
|
|
131
|
-
} else if (this.sourceLobImpl.getCsfrm() === constants.
|
|
131
|
+
} else if (this.sourceLobImpl.getCsfrm() === constants.CSFRM_NCHAR) {
|
|
132
132
|
data = this.data;
|
|
133
133
|
// TODO: avoid conversion back to string, if possible
|
|
134
134
|
// this is since bind data is converted to buffer automatically, but if
|
|
@@ -154,7 +154,7 @@ class LobOpMessage extends Message {
|
|
|
154
154
|
if (data !== null) {
|
|
155
155
|
if (oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
|
|
156
156
|
data = Buffer.from(data);
|
|
157
|
-
} else if (this.sourceLobImpl.getCsfrm() === constants.
|
|
157
|
+
} else if (this.sourceLobImpl.getCsfrm() === constants.CSFRM_NCHAR) {
|
|
158
158
|
data = Buffer.from(data).swap16().toString('utf16le');
|
|
159
159
|
} else {
|
|
160
160
|
data = data.toString();
|