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.
Files changed (44) hide show
  1. package/README.md +18 -19
  2. package/SECURITY.md +1 -1
  3. package/build/Release/{oracledb-6.0.1-darwin-x64.node → oracledb-6.0.3-darwin-x64.node} +0 -0
  4. package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +1 -0
  5. package/build/Release/oracledb-6.0.3-js-buildinfo.txt +1 -0
  6. package/build/Release/{oracledb-6.0.1-linux-arm64.node → oracledb-6.0.3-linux-arm64.node} +0 -0
  7. package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +1 -0
  8. package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/{oracledb-6.0.1-win32-x64.node → oracledb-6.0.3-win32-x64.node} +0 -0
  10. package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +1 -0
  11. package/lib/connection.js +1 -0
  12. package/lib/errors.js +5 -4
  13. package/lib/pool.js +4 -1
  14. package/lib/settings.js +1 -1
  15. package/lib/thin/dbObject.js +17 -5
  16. package/lib/thin/lob.js +2 -2
  17. package/lib/thin/pool.js +10 -12
  18. package/lib/thin/protocol/buffer.js +9 -9
  19. package/lib/thin/protocol/constants.js +5 -4
  20. package/lib/thin/protocol/encryptDecrypt.js +24 -12
  21. package/lib/thin/protocol/messages/auth.js +7 -9
  22. package/lib/thin/protocol/messages/base.js +10 -10
  23. package/lib/thin/protocol/messages/execute.js +5 -5
  24. package/lib/thin/protocol/messages/lobOp.js +3 -3
  25. package/lib/thin/protocol/messages/withData.js +20 -18
  26. package/lib/thin/protocol/packet.js +31 -27
  27. package/lib/thin/protocol/protocol.js +12 -7
  28. package/lib/thin/sqlnet/connStrategy.js +4 -2
  29. package/lib/thin/sqlnet/ezConnectResolver.js +9 -5
  30. package/lib/thin/sqlnet/navNodes.js +3 -3
  31. package/lib/thin/sqlnet/networkSession.js +10 -10
  32. package/lib/thin/sqlnet/ntTcp.js +38 -25
  33. package/lib/thin/sqlnet/packet.js +8 -8
  34. package/lib/thin/sqlnet/paramParser.js +5 -8
  35. package/lib/thin/statement.js +1 -0
  36. package/lib/thin/util.js +21 -0
  37. package/lib/version.js +1 -1
  38. package/package.json +1 -1
  39. package/build/Release/oracledb-6.0.1-darwin-x64.node-buildinfo.txt +0 -1
  40. package/build/Release/oracledb-6.0.1-js-buildinfo.txt +0 -1
  41. package/build/Release/oracledb-6.0.1-linux-arm64.node-buildinfo.txt +0 -1
  42. package/build/Release/oracledb-6.0.1-linux-x64.node-buildinfo.txt +0 -1
  43. package/build/Release/oracledb-6.0.1-win32-x64.node-buildinfo.txt +0 -1
  44. /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
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.1 to connect Node.js 14.6, or later, to Oracle
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][32] and the [CHANGELOG][33].
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][30] directory. Start with [examples/example.js][31].
28
+ See the [examples][7] directory. Start with [examples/example.js][8].
28
29
 
29
30
  ## Help
30
31
 
31
- Issues and questions about node-oracledb can be posted on [GitHub][3] or
32
- [Slack][5] ([link to join Slack][6]).
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][34].
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][35].
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](./SECURITY.md) for our responsible security
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/issues
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
- [30]: https://github.com/oracle/node-oracledb/blob/main/examples
82
- [31]: https://github.com/oracle/node-oracledb/blob/main/examples/example.js
83
- [32]: https://node-oracledb.readthedocs.io/en/latest/
84
- [33]: https://github.com/oracle/node-oracledb/blob/main/CHANGELOG.md
85
- [34]: https://github.com/oracle/node-oracledb/blob/main/test/README.md
86
- [35]: https://github.com/oracle/node-oracledb/blob/main/CONTRIBUTING.md
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
- [Oracle Critical Patch Update][3] program. Additional
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
 
@@ -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
@@ -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
@@ -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
@@ -146,6 +146,7 @@ class Connection extends EventEmitter {
146
146
  cls = this._buildDbObjectClass(objType);
147
147
  cls._connection = this;
148
148
  cls._objType = objType;
149
+ objType._connection = this._impl;
149
150
  this._dbObjectClasses.set(objType, cls);
150
151
  }
151
152
  return (cls);
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 with NJS errors
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
- settings.addToOptions(options, "connectionClass");
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) {
@@ -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.TNS_CS_IMPLICIT);
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.TNS_CS_NCHAR);
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.TNS_CS_NCHAR) {
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.TNS_CS_NCHAR;
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
- // get connection from pool
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 _connect(connAttrs) {
151
+ async _getConnAttrs() {
150
152
  let accessToken;
151
- const conn = new ThinConnectionImpl();
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
- await conn.connect(clonedAttrs);
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
- let conn = await this._connect(this._userConfig);
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.TNS_CS_IMPLICIT)
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.floor(year / 100) + 100;
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.floor(year / 100) + 100;
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
- let sessionKeyParta = this._decrypt(passwordHash, encodedServerKey);
142
- let sessionKeyPartb = Buffer.alloc(32);
143
- crypto.randomFillSync(sessionKeyPartb, 0, 32);
144
- let encodedClientKey = this._encrypt(passwordHash, sessionKeyPartb);
145
- authObj.sessionKey = encodedClientKey.slice().toString('hex').toUpperCase().slice(0, 64);
146
-
147
- iterations = Number(sessionData['AUTH_PBKDF2_SDER_COUNT']);
148
- let mixingSalt = Buffer.from(sessionData['AUTH_PBKDF2_CSK_SALT'], 'hex');
149
- let partABKey = Buffer.concat([sessionKeyPartb.slice(0, keyLen), sessionKeyParta.slice(0, keyLen)]);
150
- let partABKeyStr = partABKey.toString('hex').toUpperCase();
151
- let partABKeyBuffer = Buffer.from(partABKeyStr, 'utf8');
152
- authObj.comboKey = crypto.pbkdf2Sync(partABKeyBuffer, mixingSalt, iterations, keyLen, 'sha512');
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", process.argv0);
188
- buf.writeKeyValue("AUTH_MACHINE", os.hostname());
189
- buf.writeKeyValue("AUTH_PID", process.pid.toString());
190
- buf.writeKeyValue("AUTH_SID", os.userInfo().username);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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
- const nb = buf.readUB2();
234
- buf.skipBytes(nb + 1);
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.skipBytes(temp16 + 1);
243
+ buf.skipBytesChunked();
244
244
  }
245
245
  temp16 = buf.readUB2();
246
246
  if (temp16 > 0) { // skip value
247
- buf.skipBytes(temp16 + 1);
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.skipBytes(temp16 + 1);
274
+ buf.skipBytesChunked();
275
275
  }
276
276
  temp16 = buf.readUB2();
277
277
  if (temp16 > 0) { // skip value
278
- buf.skipBytes(temp16 + 1);
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 == 0 || stmt.isDdl) {
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.TNS_CS_NCHAR) {
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.TNS_CS_NCHAR) {
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.TNS_CS_NCHAR) {
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();