oracledb 6.0.3 → 6.1.0
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 +2 -2
- package/build/Release/oracledb-6.1.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.1.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.1.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.1.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.1.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.1.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.1.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.1.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.1.0-win32-x64.node-buildinfo.txt +1 -0
- package/examples/example.js +0 -1
- package/lib/aqQueue.js +40 -26
- package/lib/connection.js +15 -3
- package/lib/errors.js +10 -6
- package/lib/impl/connection.js +9 -0
- package/lib/impl/resultset.js +7 -4
- package/lib/oracledb.js +15 -12
- package/lib/pool.js +7 -1
- package/lib/sodaCollection.js +1 -1
- package/lib/thin/connection.js +92 -30
- package/lib/thin/pool.js +153 -68
- package/lib/thin/protocol/buffer.js +19 -1
- package/lib/thin/protocol/constants.js +3 -14
- package/lib/thin/protocol/encryptDecrypt.js +17 -17
- package/lib/thin/protocol/messages/auth.js +21 -23
- package/lib/thin/protocol/messages/base.js +22 -45
- package/lib/thin/protocol/messages/connectionCookie.js +76 -0
- package/lib/thin/protocol/messages/dataType.js +13 -9
- package/lib/thin/protocol/messages/execute.js +7 -7
- package/lib/thin/protocol/messages/index.js +2 -0
- package/lib/thin/protocol/messages/protocol.js +31 -20
- package/lib/thin/protocol/messages/withData.js +49 -43
- package/lib/thin/protocol/oson.js +4 -4
- package/lib/thin/protocol/packet.js +31 -10
- package/lib/thin/protocol/utils.js +2 -2
- package/lib/thin/resultSet.js +6 -6
- package/lib/thin/sqlnet/connStrategy.js +130 -5
- package/lib/thin/sqlnet/constants.js +2 -0
- package/lib/thin/sqlnet/ezConnectResolver.js +20 -19
- package/lib/thin/sqlnet/navNodes.js +32 -25
- package/lib/thin/sqlnet/networkSession.js +35 -30
- package/lib/thin/sqlnet/ntTcp.js +30 -14
- package/lib/thin/sqlnet/nvStrToNvPair.js +16 -16
- package/lib/thin/sqlnet/packet.js +9 -2
- package/lib/thin/sqlnet/paramParser.js +9 -9
- package/lib/thin/sqlnet/sessionAtts.js +4 -0
- package/lib/thin/statement.js +3 -3
- package/lib/thin/util.js +7 -8
- package/lib/transformer.js +3 -1
- package/lib/util.js +0 -13
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/build/Release/oracledb-6.0.3-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-linux-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-win32-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +0 -1
|
@@ -37,7 +37,7 @@ const { Buffer } = require('buffer');
|
|
|
37
37
|
const EzConnect = require("./ezConnectResolver.js");
|
|
38
38
|
const { NLParamParser, tnsnamesFilePath } = require("./paramParser.js");
|
|
39
39
|
const process = require('process');
|
|
40
|
-
|
|
40
|
+
const downHostInstance = require("./connStrategy.js").SOLE_INST_DHCACHE;
|
|
41
41
|
/**
|
|
42
42
|
*
|
|
43
43
|
* @param {string} userConfig
|
|
@@ -45,19 +45,20 @@ const process = require('process');
|
|
|
45
45
|
*/
|
|
46
46
|
|
|
47
47
|
async function getConnectionInfo(userConfig) {
|
|
48
|
-
|
|
48
|
+
const connStr = await resolveConnectStr(userConfig.connectString, userConfig.configDir);
|
|
49
49
|
let nvpair;
|
|
50
50
|
if (typeof connStr === 'string')
|
|
51
51
|
nvpair = createNVPair(connStr);
|
|
52
52
|
else
|
|
53
53
|
nvpair = connStr;//Already a NVPair
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
const serverVal = findValue(nvpair, ["DESCRIPTION", "CONNECT_DATA", "SERVER"]);
|
|
56
|
+
const connClass = findValue(nvpair, ["DESCRIPTION", "CONNECT_DATA", "POOL_CONNECTION_CLASS"]);
|
|
57
|
+
const svcname = findValue(nvpair, ["DESCRIPTION", "CONNECT_DATA", "SERVICE_NAME"]);
|
|
58
|
+
const sid = findValue(nvpair, ["DESCRIPTION", "CONNECT_DATA", "SID"]);
|
|
59
|
+
const poolPurity = findValue(nvpair, ["DESCRIPTION", "CONNECT_DATA", "POOL_PURITY"]);
|
|
59
60
|
|
|
60
|
-
return [serverVal, connClass, svcname, poolPurity ];
|
|
61
|
+
return [serverVal, connClass, svcname, poolPurity, sid ];
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
/**
|
|
@@ -65,20 +66,20 @@ async function getConnectionInfo(userConfig) {
|
|
|
65
66
|
* @param {String} connStr Connect string
|
|
66
67
|
* @returns AddressNode
|
|
67
68
|
*/
|
|
68
|
-
|
|
69
|
+
const nlParamParser = new NLParamParser;
|
|
69
70
|
async function resolveConnectStr(connectString, configDir) {
|
|
70
|
-
|
|
71
|
+
const connStr = connectString.trim();
|
|
71
72
|
let resolvedVal = connStr;
|
|
72
73
|
if ((connStr.indexOf(')') == -1) || (connStr.indexOf('(') != 0)) {
|
|
73
74
|
try {
|
|
74
75
|
/* Try through ezconnect */
|
|
75
|
-
|
|
76
|
+
const ezcnObj = new EzConnect(connStr);
|
|
76
77
|
resolvedVal = await ezcnObj.getResolvedUrl();
|
|
77
78
|
} catch (err) {
|
|
78
79
|
try {
|
|
79
80
|
/* try tns alias */
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
const namesFilePath = tnsnamesFilePath(configDir);
|
|
82
|
+
const p = await nlParamParser.initializeNlpa(namesFilePath);
|
|
82
83
|
resolvedVal = p.get(connStr.toUpperCase());
|
|
83
84
|
if (!resolvedVal)
|
|
84
85
|
errors.throwErr(errors.ERR_TNS_ENTRY_NOT_FOUND, connStr, configDir ? configDir + '/tnsnames.ora' : process.env.TNS_ADMIN + '/tnsnames.ora');
|
|
@@ -96,7 +97,7 @@ async function resolveConnectStr(connectString, configDir) {
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
async function resolveAddress(connStr, configDir) {
|
|
99
|
-
|
|
100
|
+
const connstr = await resolveConnectStr(connStr, configDir);
|
|
100
101
|
return createNode(connstr);
|
|
101
102
|
}
|
|
102
103
|
|
|
@@ -140,23 +141,24 @@ class NetworkSession {
|
|
|
140
141
|
|
|
141
142
|
async getAddress(addressNode, userConfig) {
|
|
142
143
|
/* Get the next address */
|
|
143
|
-
|
|
144
|
+
const address = await addressNode.execute(userConfig);
|
|
144
145
|
/* Prepare connection attributes */
|
|
145
|
-
|
|
146
|
+
const uuid = this.sAtts ? this.sAtts.uuid : null;
|
|
146
147
|
this.sAtts = new SessionAtts(uuid);
|
|
147
148
|
this.sAtts.setFrom(userConfig);
|
|
148
149
|
this.sAtts.setFrom(address.desc.params); /* Resolve attributes from Connect String */
|
|
149
150
|
await this.sAtts.prepare(address.protocol);
|
|
150
151
|
|
|
151
152
|
/* Insert Connection ID */
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
const rootNVPair = createNVPair(address.CNdata.join(""));
|
|
154
|
+
const cdataNVPair = findNVPairRecurse(rootNVPair, "CONNECT_DATA");
|
|
155
|
+
const connidStr = `(CONNECTION_ID=${this.sAtts.connectionId})`;
|
|
156
|
+
const childNVPair = createNVPair(connidStr);
|
|
156
157
|
cdataNVPair.addListElement(childNVPair);
|
|
157
158
|
|
|
158
159
|
this.cData = Buffer.from(rootNVPair.toString(), 'ascii');
|
|
159
160
|
this.cDataNVPair = rootNVPair;
|
|
161
|
+
this.sAtts.nt.cDataNVPair = rootNVPair;
|
|
160
162
|
|
|
161
163
|
return (address);
|
|
162
164
|
}
|
|
@@ -210,7 +212,7 @@ class NetworkSession {
|
|
|
210
212
|
|
|
211
213
|
/* Transport connect */
|
|
212
214
|
if (this.sAtts.transportConnectTimeout) {
|
|
213
|
-
|
|
215
|
+
const asyncPromise = this.transportConnect(address);
|
|
214
216
|
await timeout(asyncPromise, this.sAtts.transportConnectTimeout, "transportConnectTimeout", address, this.sAtts.connectionId);
|
|
215
217
|
} else {
|
|
216
218
|
await this.transportConnect(address);
|
|
@@ -230,9 +232,9 @@ class NetworkSession {
|
|
|
230
232
|
await this._recvPacket();
|
|
231
233
|
this.refusePkt.dataBuf = this.rcvDatapkt.buf.subarray(this.rcvDatapkt.offset, this.rcvDatapkt.len).toString();
|
|
232
234
|
}
|
|
233
|
-
|
|
235
|
+
const nvpair = createNVPair(this.refusePkt.dataBuf);
|
|
234
236
|
this.refusePkt = null;
|
|
235
|
-
|
|
237
|
+
const err = findValue(nvpair, ["DESCRIPTION", "ERR"]);
|
|
236
238
|
if (err == "12514") {
|
|
237
239
|
errors.throwErr(errors.ERR_INVALID_SERVICE_NAME, this.getOption(constants.SVCNAME), address.host, address.port, this.sAtts.connectionId);
|
|
238
240
|
} else if (err == "12505") {
|
|
@@ -249,7 +251,7 @@ class NetworkSession {
|
|
|
249
251
|
}
|
|
250
252
|
this._sendConnect(connectPkt);
|
|
251
253
|
} else if (packet.type === constants.NSPTRD) { /* REDIRECT */
|
|
252
|
-
let adrLen, adrStr,
|
|
254
|
+
let adrLen, adrStr, redirConnData;
|
|
253
255
|
|
|
254
256
|
/* Read and connect to Redirect address */
|
|
255
257
|
if (this.redirectPkt.overflow) {
|
|
@@ -266,8 +268,8 @@ class NetworkSession {
|
|
|
266
268
|
redirConnData = this.cData;
|
|
267
269
|
}
|
|
268
270
|
|
|
269
|
-
redirAddressNode = await resolveAddress(adrStr);
|
|
270
|
-
|
|
271
|
+
const redirAddressNode = await resolveAddress(adrStr);
|
|
272
|
+
const host = address.hostname;
|
|
271
273
|
address = await redirAddressNode.execute();
|
|
272
274
|
if (address.desc)
|
|
273
275
|
this.sAtts.setFrom(address.desc.params); /* Add on attributes from redirect connect String */
|
|
@@ -276,7 +278,7 @@ class NetworkSession {
|
|
|
276
278
|
this.ntAdapter.disconnect(constants.NSFIMM);
|
|
277
279
|
|
|
278
280
|
if (this.sAtts.transportConnectTimeout) {
|
|
279
|
-
|
|
281
|
+
const asyncPromise = this.transportConnect(address);
|
|
280
282
|
await timeout(asyncPromise, this.sAtts.transportConnectTimeout, "transportConnectTimeout", address, this.sAtts.connectionId);
|
|
281
283
|
} else {
|
|
282
284
|
await this.transportConnect(address);
|
|
@@ -311,13 +313,14 @@ class NetworkSession {
|
|
|
311
313
|
do {
|
|
312
314
|
try {
|
|
313
315
|
if (this.sAtts.connectTimeout) {
|
|
314
|
-
|
|
316
|
+
const asyncPromise = this.connect2(address);
|
|
315
317
|
connected = await timeout(asyncPromise, this.sAtts.connectTimeout, "connectTimeout", address, this.sAtts.connectionId);
|
|
316
318
|
} else {
|
|
317
319
|
connected = await this.connect2(address);
|
|
318
320
|
}
|
|
319
321
|
} catch (err) {
|
|
320
|
-
if (err.message.startsWith('NJS-510')) {
|
|
322
|
+
if (err.message.startsWith('NJS-510') && !this.ntAdapter.connected) {
|
|
323
|
+
downHostInstance.markDownHost(address.host, Date.now()); // mark the host as down
|
|
321
324
|
this.ntAdapter.connected = true; // Pretend as connected
|
|
322
325
|
}
|
|
323
326
|
if (this.ntAdapter) {
|
|
@@ -356,6 +359,8 @@ class NetworkSession {
|
|
|
356
359
|
break;
|
|
357
360
|
case constants.NSPTAC: /* ACCEPT */
|
|
358
361
|
Packet.AcceptPacket(packet, this.sAtts);
|
|
362
|
+
this.dbUUID = packet.dbUUID;
|
|
363
|
+
packet.dbUUID = null;
|
|
359
364
|
break;
|
|
360
365
|
case constants.NSPTRF: /* REFUSE */
|
|
361
366
|
this.refusePkt = new Packet.RefusePacket(packet);
|
|
@@ -510,8 +515,8 @@ class NetworkSession {
|
|
|
510
515
|
* Establish network connection
|
|
511
516
|
*/
|
|
512
517
|
async connect(userConfig) {
|
|
513
|
-
|
|
514
|
-
|
|
518
|
+
const connStr = userConfig.connectString ? userConfig.connectString : userConfig.connectionString;
|
|
519
|
+
const addressNode = await resolveAddress(connStr, userConfig.configDir);
|
|
515
520
|
let address;
|
|
516
521
|
try {
|
|
517
522
|
address = await this.getAddress(addressNode, userConfig);
|
package/lib/thin/sqlnet/ntTcp.js
CHANGED
|
@@ -34,6 +34,7 @@ const http = require("http");
|
|
|
34
34
|
const Timers = require('timers');
|
|
35
35
|
const constants = require("./constants.js");
|
|
36
36
|
const errors = require("../../errors.js");
|
|
37
|
+
const { findValue } = require("./nvStrToNvPair.js");
|
|
37
38
|
|
|
38
39
|
const PACKET_HEADER_SIZE = 8;
|
|
39
40
|
const DEFAULT_PORT = 1521;
|
|
@@ -67,28 +68,40 @@ class NTTCP {
|
|
|
67
68
|
this.largeSDU = false;
|
|
68
69
|
this.streamNum = streamNum++;
|
|
69
70
|
this.packetNum = 1;
|
|
71
|
+
this.doDNMatch = true;
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
/**
|
|
73
75
|
* DN matching funciton(used with TLS)
|
|
74
76
|
*/
|
|
75
77
|
dnMatch(serverName, cert) {
|
|
76
|
-
if (this.atts.sslServerDNMatch) {
|
|
77
|
-
|
|
78
|
+
if (this.atts.sslServerDNMatch && this.doDNMatch) {
|
|
79
|
+
const toObject = str =>str .split(',').map(x => x.split('=').map(y => y.trim())).reduce((a, x) => {
|
|
78
80
|
a[x[0]] = x[1];
|
|
79
81
|
return a;
|
|
80
82
|
}, {});
|
|
81
83
|
if (this.atts.sslServerCertDN) { /* Full DN Match */
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
const obj = toObject(this.atts.sslServerCertDN);
|
|
85
|
+
if (Object.keys(obj).length == Object.keys(cert.subject).length) {
|
|
86
|
+
for (const key in obj) {
|
|
87
|
+
if (obj[key] != cert.subject[key]) {
|
|
88
|
+
return (errors.getErr(errors.ERR_TLS_DNMATCH_FAILURE));
|
|
89
|
+
}
|
|
86
90
|
}
|
|
91
|
+
} else {
|
|
92
|
+
return (errors.getErr(errors.ERR_TLS_DNMATCH_FAILURE));
|
|
87
93
|
}
|
|
88
94
|
} else {
|
|
89
95
|
if (tls.checkServerIdentity(this.hostName, cert) && (!this.originHost || tls.checkServerIdentity(this.originHost, cert))) { /* Hostname match */
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
if (this.atts.sslAllowWeakDNMatch) {
|
|
97
|
+
const serviceName = findValue(this.atts.cDataNVPair, ["DESCRIPTION", "CONNECT_DATA", "SERVICE_NAME"]); /* Service Name match */
|
|
98
|
+
if (serviceName != cert.subject.CN) {
|
|
99
|
+
return (errors.getErr(errors.ERR_TLS_DNMATCH_FAILURE));
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
const hostName = this.hostName + " " + (this.originHost ? "or " + this.originHost : "");
|
|
103
|
+
return (errors.getErr(errors.ERR_TLS_HOSTMATCH_FAILURE, hostName));
|
|
104
|
+
}
|
|
92
105
|
}
|
|
93
106
|
}
|
|
94
107
|
}
|
|
@@ -136,7 +149,7 @@ class NTTCP {
|
|
|
136
149
|
}
|
|
137
150
|
|
|
138
151
|
let connectErrCause, proxyConnectErrCause, req;
|
|
139
|
-
|
|
152
|
+
const httpsProxy = address.httpsProxy || this.atts.httpsProxy;
|
|
140
153
|
let httpsProxyPort = address.httpsProxyPort || this.atts.httpsProxyPort;
|
|
141
154
|
|
|
142
155
|
await new Promise((resolve) => {
|
|
@@ -211,6 +224,8 @@ class NTTCP {
|
|
|
211
224
|
if (address.protocol.toUpperCase() == "TCPS") {
|
|
212
225
|
let secureContext;
|
|
213
226
|
this.secure = true;
|
|
227
|
+
if (this.atts.sslAllowWeakDNMatch)
|
|
228
|
+
this.doDNMatch = false; //Don't match initial connect
|
|
214
229
|
try {
|
|
215
230
|
secureContext = tls.createSecureContext({
|
|
216
231
|
cert : this.atts.wallet,
|
|
@@ -259,7 +274,7 @@ class NTTCP {
|
|
|
259
274
|
const block = buffer.slice(i, i + 8);
|
|
260
275
|
const hexDumpValues = [];
|
|
261
276
|
const printableValues = [];
|
|
262
|
-
for (
|
|
277
|
+
for (const hexByte of block) {
|
|
263
278
|
hexDumpValues.push(hexByte.toString(16).toUpperCase().padStart(2, '0'));
|
|
264
279
|
if (hexByte > 0x20 && hexByte < 0x7f) {
|
|
265
280
|
printableValues.push(String.fromCharCode(hexByte));
|
|
@@ -301,7 +316,7 @@ class NTTCP {
|
|
|
301
316
|
*/
|
|
302
317
|
checkErr() {
|
|
303
318
|
if (!this.connected || this.err) {
|
|
304
|
-
let err
|
|
319
|
+
let err;
|
|
305
320
|
if (this.savedErr) {
|
|
306
321
|
err = errors.getErr(errors.ERR_CONNECTION_LOSTCONTACT,
|
|
307
322
|
this.host, this.port, this.atts.connectionId, this.savedErr.message);
|
|
@@ -309,7 +324,7 @@ class NTTCP {
|
|
|
309
324
|
err = errors.getErr(errors.ERR_CONNECTION_EOF, this.host, this.port, this.atts.connectionId,);
|
|
310
325
|
}
|
|
311
326
|
/* Wrap around NJS-500 */
|
|
312
|
-
newErr = errors.getErr(errors.ERR_CONNECTION_CLOSED);
|
|
327
|
+
const newErr = errors.getErr(errors.ERR_CONNECTION_CLOSED);
|
|
313
328
|
newErr.message = newErr.message + "\n" + err.message;
|
|
314
329
|
throw (newErr);
|
|
315
330
|
}
|
|
@@ -457,7 +472,8 @@ class NTTCP {
|
|
|
457
472
|
async renegTLS() {
|
|
458
473
|
try {
|
|
459
474
|
this.checkErr();
|
|
460
|
-
|
|
475
|
+
this.doDNMatch = true;
|
|
476
|
+
const secureContext = tls.createSecureContext({
|
|
461
477
|
cert : this.atts.wallet,
|
|
462
478
|
key : this.atts.wallet,
|
|
463
479
|
passphrase: this.atts.walletPassword,
|
|
@@ -513,7 +529,7 @@ class NTTCP {
|
|
|
513
529
|
return (this.packets.length > 0);
|
|
514
530
|
case constants.REMOTEADDR: /* Remote Address */
|
|
515
531
|
{
|
|
516
|
-
|
|
532
|
+
const socket = this.secure ? this.connStream : this.stream;
|
|
517
533
|
return (socket.remoteAddress + ":" + socket.remotePort);
|
|
518
534
|
}
|
|
519
535
|
default:
|
|
@@ -176,7 +176,7 @@ class NVPair {
|
|
|
176
176
|
}
|
|
177
177
|
} else if (this.listType == LIST_COMMASEP) {
|
|
178
178
|
for (let i = 0; i < this.getListSize(); i++) {
|
|
179
|
-
|
|
179
|
+
const listElem = this.getListElement(i);
|
|
180
180
|
out = out + listElem.name;
|
|
181
181
|
if (i != this.getListSize() - 1)
|
|
182
182
|
out = out + ", ";
|
|
@@ -202,7 +202,7 @@ class NVPair {
|
|
|
202
202
|
} else if (this.listType == LIST_COMMASEP) {
|
|
203
203
|
out = out + " (";
|
|
204
204
|
for (let i = 0; i < this.getListSize(); i++) {
|
|
205
|
-
|
|
205
|
+
const listElem = this.getListElement(i);
|
|
206
206
|
out = out + listElem.name;
|
|
207
207
|
|
|
208
208
|
if (i != this.getListSize() - 1)
|
|
@@ -308,7 +308,7 @@ class NVTokens {
|
|
|
308
308
|
* function to trim leading and trailing spaces from a literal.
|
|
309
309
|
*/
|
|
310
310
|
_trimWhiteSpace(it) {
|
|
311
|
-
|
|
311
|
+
const length = it.length;
|
|
312
312
|
let start = 0;
|
|
313
313
|
let end = length;
|
|
314
314
|
|
|
@@ -337,7 +337,7 @@ class NVTokens {
|
|
|
337
337
|
this.tkType = new Array();
|
|
338
338
|
this.tkValue = new Array();
|
|
339
339
|
|
|
340
|
-
|
|
340
|
+
const len = nvString.length;
|
|
341
341
|
let eql_seen = false;
|
|
342
342
|
// convert NVString to character array for easier access
|
|
343
343
|
let input = new Array();
|
|
@@ -560,7 +560,7 @@ class NVTokens {
|
|
|
560
560
|
* @param nvString the nvString to parse
|
|
561
561
|
*/
|
|
562
562
|
function createNVPair(nvString) {
|
|
563
|
-
|
|
563
|
+
const nvt = new NVTokens();
|
|
564
564
|
nvt.parseTokens(nvString);
|
|
565
565
|
return readTopLevelNVPair(nvt);
|
|
566
566
|
}
|
|
@@ -579,7 +579,7 @@ function readTopLevelNVPair(nvt) {
|
|
|
579
579
|
}
|
|
580
580
|
|
|
581
581
|
let name = readNVLiteral(nvt);
|
|
582
|
-
|
|
582
|
+
const nvp = new NVPair(name);
|
|
583
583
|
|
|
584
584
|
if ((tk = nvt.getToken()) == TKN_COMMA) {
|
|
585
585
|
// read comma'ed names as one name
|
|
@@ -601,14 +601,14 @@ function readTopLevelNVPair(nvt) {
|
|
|
601
601
|
*/
|
|
602
602
|
function readNVPair(nvt) {
|
|
603
603
|
// Opening ( or , for NVPair
|
|
604
|
-
|
|
604
|
+
const tk = nvt.getToken();
|
|
605
605
|
nvt.eatToken();
|
|
606
606
|
if (!((tk == TKN_LPAREN) || (tk == TKN_COMMA))) {
|
|
607
607
|
errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_SYNTAX);
|
|
608
608
|
}
|
|
609
609
|
|
|
610
|
-
|
|
611
|
-
|
|
610
|
+
const name = readNVLiteral(nvt);
|
|
611
|
+
const nvp = new NVPair(name);
|
|
612
612
|
|
|
613
613
|
return readRightHandSide(nvp, nvt);
|
|
614
614
|
}
|
|
@@ -628,7 +628,7 @@ function readRightHandSide(nvp, nvt) {
|
|
|
628
628
|
// otherwise read an NVList.
|
|
629
629
|
tk = nvt.getToken();
|
|
630
630
|
if (tk == TKN_LITERAL) {
|
|
631
|
-
|
|
631
|
+
const value = readNVLiteral(nvt);
|
|
632
632
|
nvp.setAtom = value;
|
|
633
633
|
} else {
|
|
634
634
|
// NVList is responsible for adding child NVPairs to this parent
|
|
@@ -663,7 +663,7 @@ function readRightHandSide(nvp, nvt) {
|
|
|
663
663
|
* function which returns the next literal from NVTokens.
|
|
664
664
|
*/
|
|
665
665
|
function readNVLiteral(nvt) {
|
|
666
|
-
|
|
666
|
+
const tk = nvt.getToken();
|
|
667
667
|
if (tk != TKN_LITERAL) {
|
|
668
668
|
errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_SYNTAX);
|
|
669
669
|
}
|
|
@@ -677,12 +677,12 @@ function readNVLiteral(nvt) {
|
|
|
677
677
|
function readNVList(nvt, parent) {
|
|
678
678
|
// if next token is "(" or ",", then read an NVPair
|
|
679
679
|
// otherwise, assume epsilon
|
|
680
|
-
|
|
680
|
+
const tk = nvt.getToken();
|
|
681
681
|
if (!(tk == TKN_LPAREN || tk == TKN_COMMA)) {
|
|
682
682
|
return; // didn't read an nvpair
|
|
683
683
|
}
|
|
684
684
|
|
|
685
|
-
|
|
685
|
+
const child = readNVPair(nvt);
|
|
686
686
|
|
|
687
687
|
// read a good NVPair
|
|
688
688
|
parent.addListElement(child);
|
|
@@ -715,7 +715,7 @@ function findNVPairRecurse(nvp, name) {
|
|
|
715
715
|
|
|
716
716
|
/* Loop thru the list of children and searching each child for name. */
|
|
717
717
|
for (let i = 0; i < nvp.getListSize(); i++) {
|
|
718
|
-
|
|
718
|
+
const child = findNVPairRecurse(nvp.getListElement(i), name);
|
|
719
719
|
|
|
720
720
|
/* Did we find "name"? */
|
|
721
721
|
if (child !== null)
|
|
@@ -742,7 +742,7 @@ function findNVPair(nvp, name) {
|
|
|
742
742
|
|
|
743
743
|
/* Loop thru the list of children and searching each child for name. */
|
|
744
744
|
for (let i = 0; i < nvp.getListSize(); i++) {
|
|
745
|
-
|
|
745
|
+
const child = nvp.getListElement(i);
|
|
746
746
|
if (name.toUpperCase() == (child.name).toUpperCase())
|
|
747
747
|
return child;
|
|
748
748
|
}
|
|
@@ -764,7 +764,7 @@ function findValue(nvp, names) {
|
|
|
764
764
|
return null;
|
|
765
765
|
|
|
766
766
|
let output = nvp;
|
|
767
|
-
|
|
767
|
+
const sze = names.length;
|
|
768
768
|
|
|
769
769
|
for (let i = 1; i < sze; i++) {
|
|
770
770
|
output = findNVPair(output, names[i]);
|
|
@@ -42,7 +42,7 @@ function ConnectPacket(connectData, sAtts, flags = 0) {
|
|
|
42
42
|
this.connectDataLen = connectData.length;
|
|
43
43
|
this.overflow = false;
|
|
44
44
|
|
|
45
|
-
let size
|
|
45
|
+
let size;
|
|
46
46
|
|
|
47
47
|
if (this.connectDataLen <= MAX_CDATA_LEN) {
|
|
48
48
|
size = NSPCNL + this.connectDataLen;
|
|
@@ -69,7 +69,7 @@ function ConnectPacket(connectData, sAtts, flags = 0) {
|
|
|
69
69
|
/* Options:
|
|
70
70
|
Note : Node JS does not support TCP Out-of-band so not setting NSGSENDATTN or NSGRECVATTN
|
|
71
71
|
*/
|
|
72
|
-
options = constants.NSGDONTCARE;
|
|
72
|
+
const options = constants.NSGDONTCARE;
|
|
73
73
|
//options = options | constants.NSGUSEVIO /* Vectored I/O support.Uncomment when support is added */
|
|
74
74
|
this.buf.writeUInt16BE(options, constants.NSPCNOPT);
|
|
75
75
|
|
|
@@ -245,6 +245,13 @@ function AcceptPacket(packet, sAtts) {
|
|
|
245
245
|
/* Accept flags */
|
|
246
246
|
this.flag0 = packet.buf.readUInt8(constants.NSPACFL0);
|
|
247
247
|
this.flag1 = packet.buf.readUInt8(constants.NSPACFL1);
|
|
248
|
+
|
|
249
|
+
/* UUID - CDB Instance ID */
|
|
250
|
+
if (sAtts.version >= constants.TNS_VERSION_MIN_UUID) {
|
|
251
|
+
packet.dbUUID = packet.buf.subarray(constants.TNS_UUID_OFFSET,
|
|
252
|
+
constants.TNS_UUID_OFFSET + 16);
|
|
253
|
+
packet.dbUUID = packet.dbUUID.toString('base64');
|
|
254
|
+
}
|
|
248
255
|
}
|
|
249
256
|
|
|
250
257
|
/**
|
|
@@ -37,7 +37,7 @@ const errors = require("../../errors.js");
|
|
|
37
37
|
*/
|
|
38
38
|
function tnsnamesFilePath(configDir) {
|
|
39
39
|
let filePathVal = null;
|
|
40
|
-
|
|
40
|
+
const tnsAdminVal = process.env.TNS_ADMIN;
|
|
41
41
|
if (configDir) {
|
|
42
42
|
filePathVal = configDir + '/tnsnames.ora';
|
|
43
43
|
if (fs.existsSync(filePathVal)) {
|
|
@@ -69,7 +69,7 @@ class NLParamParser {
|
|
|
69
69
|
* @returns {Promise}
|
|
70
70
|
*/
|
|
71
71
|
async initializeNlpa(file_path) {
|
|
72
|
-
|
|
72
|
+
const stat = fs.statSync(file_path);
|
|
73
73
|
|
|
74
74
|
if (!(stat.mtime - prevmtime)) {
|
|
75
75
|
/* File has been read */
|
|
@@ -139,10 +139,10 @@ class NLParamParser {
|
|
|
139
139
|
* @return String The modified String returned
|
|
140
140
|
*/
|
|
141
141
|
checkNLPforComments(str) {
|
|
142
|
-
|
|
142
|
+
const str1 = new Array(str.length);
|
|
143
143
|
|
|
144
144
|
for (let i = 0; i < str.length; i++) {
|
|
145
|
-
|
|
145
|
+
const current_char = str[i];
|
|
146
146
|
if (current_char == '#') {
|
|
147
147
|
if (i != 0) {
|
|
148
148
|
break; // No need to continue. Return the line
|
|
@@ -160,14 +160,14 @@ class NLParamParser {
|
|
|
160
160
|
* @param {string} ibuf
|
|
161
161
|
*/
|
|
162
162
|
addNLPListElement(ibuf) {
|
|
163
|
-
|
|
163
|
+
const res = ibuf.split(/\r?\n/).filter(element => element);
|
|
164
164
|
for (let i = 0; i < res.length; i++) {
|
|
165
165
|
if (res[i].charAt(0) != '(') {
|
|
166
166
|
res[i] = '(' + res[i] + ')';
|
|
167
167
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
const nvp = createNVPair(res[i]);
|
|
169
|
+
const name = nvp.name;
|
|
170
|
+
const uname = name.toUpperCase();
|
|
171
171
|
nvp.name = uname;
|
|
172
172
|
const unames = uname.split(","); //multiple aliases (alias1, alias2, alias3)
|
|
173
173
|
for (let i = 0; i < unames.length; i++) {
|
|
@@ -191,7 +191,7 @@ class NLParamParser {
|
|
|
191
191
|
* @returns {string}
|
|
192
192
|
*/
|
|
193
193
|
findValueOf(key) {
|
|
194
|
-
|
|
194
|
+
const myarr = key.split('/');
|
|
195
195
|
return (findValue(this.ht.get(myarr[0].toUpperCase()), myarr));
|
|
196
196
|
}
|
|
197
197
|
|
|
@@ -59,6 +59,7 @@ class SessionAtts {
|
|
|
59
59
|
this.nt.tcpNoDelay = true;
|
|
60
60
|
this.uuid = uuid;
|
|
61
61
|
this.nt.sslServerDNMatch = true;
|
|
62
|
+
this.nt.sslAllowWeakDNMatch = false;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
/**
|
|
@@ -100,6 +101,9 @@ class SessionAtts {
|
|
|
100
101
|
if (typeof params.sslServerDNMatch === 'boolean') {
|
|
101
102
|
this.nt.sslServerDNMatch = params.sslServerDNMatch;
|
|
102
103
|
}
|
|
104
|
+
if (typeof params.sslAllowWeakDNMatch === 'boolean') {
|
|
105
|
+
this.nt.sslAllowWeakDNMatch = params.sslAllowWeakDNMatch;
|
|
106
|
+
}
|
|
103
107
|
if (typeof params.sslServerCertDN === 'string') {
|
|
104
108
|
this.nt.sslServerCertDN = params.sslServerCertDN;
|
|
105
109
|
}
|
package/lib/thin/statement.js
CHANGED
|
@@ -145,7 +145,7 @@ class Statement {
|
|
|
145
145
|
//---------------------------------------------------------------------------
|
|
146
146
|
_determineStatementType(sql) {
|
|
147
147
|
sql = thinUtil.cleanSql(sql);
|
|
148
|
-
|
|
148
|
+
const tokens = sql.trim().trimStart('(').substring(0, 10).split(" ");
|
|
149
149
|
if (tokens.length > 0) {
|
|
150
150
|
const sqlKeyword = tokens[0].toUpperCase();
|
|
151
151
|
if (["DECLARE", "BEGIN", "CALL"].includes(sqlKeyword)) {
|
|
@@ -221,7 +221,7 @@ class Statement {
|
|
|
221
221
|
let result;
|
|
222
222
|
let intoKey = -1;
|
|
223
223
|
const retKey = sql.search(DML_RETURNING_KEY);
|
|
224
|
-
|
|
224
|
+
const intoRegex = DML_RETURNING_INTO_KEY;
|
|
225
225
|
// simulate lastInfdexOf with intoRegex input
|
|
226
226
|
while ((result = intoRegex.exec(sql.slice(retKey))) != null) {
|
|
227
227
|
intoKey = result.index;
|
|
@@ -259,7 +259,7 @@ class Statement {
|
|
|
259
259
|
if (this.isPlSql && this.bindInfoDict.has(name)) {
|
|
260
260
|
return;
|
|
261
261
|
}
|
|
262
|
-
|
|
262
|
+
const info = new BindInfo(name, isReturnBind);
|
|
263
263
|
this.bindInfoList.push(info);
|
|
264
264
|
|
|
265
265
|
if (this.bindInfoDict.has(info.bindName)) {
|
package/lib/thin/util.js
CHANGED
|
@@ -68,7 +68,7 @@ function getMetadataMany(vars) {
|
|
|
68
68
|
// Get the outBinds for the sql
|
|
69
69
|
//---------------------------------------------------------------------------
|
|
70
70
|
function getOutBinds(bindVars, pos) {
|
|
71
|
-
|
|
71
|
+
const bindByPos = (bindVars[0].name === undefined);
|
|
72
72
|
let outBinds;
|
|
73
73
|
if (bindByPos) {
|
|
74
74
|
outBinds = [];
|
|
@@ -93,11 +93,11 @@ function getOutBinds(bindVars, pos) {
|
|
|
93
93
|
// Get the outBinds for the sql when doing an executeMany call
|
|
94
94
|
//---------------------------------------------------------------------------
|
|
95
95
|
function getExecuteManyOutBinds(bindVars, numIters) {
|
|
96
|
-
|
|
96
|
+
const numOutBinds = getNumOutBinds(bindVars);
|
|
97
97
|
if (numOutBinds === 0) {
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
const outBinds = new Array(numIters).fill(null);
|
|
101
101
|
for (let i = 0; i < numIters; i++) {
|
|
102
102
|
outBinds[i] = getOutBinds(bindVars, i);
|
|
103
103
|
}
|
|
@@ -125,7 +125,7 @@ function getNumOutBinds(bindVars) {
|
|
|
125
125
|
// Get the outBinds for the sql when doing an execute call
|
|
126
126
|
//---------------------------------------------------------------------------
|
|
127
127
|
function getExecuteOutBinds(bindVars) {
|
|
128
|
-
|
|
128
|
+
const numOutBinds = getNumOutBinds(bindVars);
|
|
129
129
|
if (numOutBinds === 0) {
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
@@ -151,7 +151,7 @@ function cleanSql(sql) {
|
|
|
151
151
|
// Get the bind variables from the bindInfoList of the statement object
|
|
152
152
|
//---------------------------------------------------------------------------
|
|
153
153
|
function getBindVars(statement) {
|
|
154
|
-
|
|
154
|
+
const bindVars = [];
|
|
155
155
|
for (const bindInfo of statement.bindInfoList) {
|
|
156
156
|
bindVars.push(bindInfo.bindVar);
|
|
157
157
|
}
|
|
@@ -167,8 +167,7 @@ function checkProxyUserValidity(userName) {
|
|
|
167
167
|
let schemaUser = '', proxyUser = '';
|
|
168
168
|
let quoteFound = false, openSquareBracketFound = false;
|
|
169
169
|
let lastQuoteFoundIndex = 0;
|
|
170
|
-
|
|
171
|
-
let result = {
|
|
170
|
+
const result = {
|
|
172
171
|
status : -1,
|
|
173
172
|
proxyUser : '',
|
|
174
173
|
schemaUser : ''
|
|
@@ -219,7 +218,7 @@ function checkProxyUserValidity(userName) {
|
|
|
219
218
|
// extract schema user
|
|
220
219
|
index = index + 1;
|
|
221
220
|
quoteFound = false;
|
|
222
|
-
schemaUserStartIndex = index;
|
|
221
|
+
const schemaUserStartIndex = index;
|
|
223
222
|
lastQuoteFoundIndex = 0;
|
|
224
223
|
while (index < userNameLength) {
|
|
225
224
|
// check for double quotes
|
package/lib/transformer.js
CHANGED
package/lib/util.js
CHANGED
|
@@ -294,18 +294,6 @@ function isTokenValid(accessToken) {
|
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
-
function isPrivateKeyValid(accessToken) {
|
|
298
|
-
errors.assert(typeof accessToken.privateKey === 'string',
|
|
299
|
-
errors.ERR_TOKEN_BASED_AUTH);
|
|
300
|
-
|
|
301
|
-
if (accessToken.privateKey.startsWith("-----BEGIN PRIVATE KEY-----") ||
|
|
302
|
-
accessToken.privateKey.endsWith("-----END PRIVATE KEY-----")) {
|
|
303
|
-
return false;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
return true;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
297
|
//-----------------------------------------------------------------------------
|
|
310
298
|
// addTypeProperties()
|
|
311
299
|
//
|
|
@@ -342,7 +330,6 @@ module.exports = {
|
|
|
342
330
|
isArrayOfStrings,
|
|
343
331
|
isObject,
|
|
344
332
|
isObjectOrArray,
|
|
345
|
-
isPrivateKeyValid,
|
|
346
333
|
isShardingKey,
|
|
347
334
|
isSodaDocument,
|
|
348
335
|
isTokenExpired,
|