Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

oracledb

Package Overview
Dependencies
Maintainers
4
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

oracledb - npm Package Compare versions

Comparing version 6.4.0 to 6.5.0

build/Release/oracledb-6.5.0-darwin-x64.node

2

lib/aqQueue.js

@@ -184,3 +184,3 @@ // Copyright (c) 2019, 2024, Oracle and/or its affiliates.

const msgImpls = await this._impl.deq(1);
if (msgImpls)
if (msgImpls.length > 0)
return this._makeMessage(msgImpls[0]);

@@ -187,0 +187,0 @@ }

@@ -203,2 +203,3 @@ // Copyright (c) 2016, 2024, Oracle and/or its affiliates.

typeof value === 'boolean' ||
typeof value === 'bigint' ||
Array.isArray(value) ||

@@ -209,3 +210,3 @@ value instanceof Float32Array ||

Buffer.isBuffer(value) ||
util.isDate(value) ||
util.types.isDate(value) ||
value instanceof Lob ||

@@ -575,7 +576,4 @@ value instanceof ResultSet ||

// fetchArraySize must be a positive integer
if (options.fetchArraySize !== undefined) {
errors.assertParamPropValue(Number.isInteger(options.fetchArraySize) &&
options.fetchArraySize > 0, 3, "fetchArraySize");
outOptions.fetchArraySize = options.fetchArraySize;
}
errors.assertParamPropUnsignedIntNonZero(options, 3, "fetchArraySize");
outOptions.fetchArraySize = options.fetchArraySize;

@@ -866,3 +864,3 @@ // fetchInfo must be an object with keys containing an object with a

const encoder = new oson.OsonEncoder();
return encoder.encode(transformer.transformJsonValue(value));
return encoder.encode(transformer.transformJsonValue(value), this._impl._osonMaxFieldNameSize);
}

@@ -934,4 +932,4 @@

if (result.outBinds !== undefined) {
for (const key in result.outBinds) {
const val = this._transformOutBind(result.outBinds[key], options);
for (const [key, value] of Object.entries(result.outBinds)) {
const val = this._transformOutBind(value, options);
result.outBinds[key] = val;

@@ -945,6 +943,5 @@ }

if (result.implicitResults) {
for (const key in result.implicitResults) {
const resultSetImpl = result.implicitResults[key];
for (const [key, impl] of Object.entries(result.implicitResults)) {
const resultSet = new ResultSet();
resultSet._setup(this, resultSetImpl);
resultSet._setup(this, impl);
if (options.resultSet) {

@@ -1005,4 +1002,4 @@ result.implicitResults[key] = resultSet;

const outBind = result.outBinds[i];
for (const key in outBind) {
outBind[key] = this._transformOutBind(outBind[key], options);
for (const [key, value] of Object.entries(outBind)) {
outBind[key] = this._transformOutBind(value, options);
}

@@ -1009,0 +1006,0 @@ }

@@ -146,2 +146,4 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

const ERR_OBJECT_IS_NOT_A_COLLECTION = 146;
const ERR_CURSOR_HAS_BEEN_CLOSED = 147;
const ERR_DML_RETURNING_DUP_BINDS = 149;

@@ -360,3 +362,3 @@ // Oracle Net layer errors start from 500

messages.set(ERR_OSON_FIELD_NAME_LIMITATION, // NJS-114
'OSON field names may not exceed 255 UTF-8 encoded bytes');
'OSON field names may not exceed %d UTF-8 encoded bytes');
messages.set(ERR_ORACLE_NUMBER_NO_REPR, // NJS-115

@@ -422,2 +424,6 @@ 'value cannot be represented as an Oracle Database number');

'object %s is not a collection');
messages.set(ERR_CURSOR_HAS_BEEN_CLOSED, // NJS-147
'cursor has been closed by the database');
messages.set(ERR_DML_RETURNING_DUP_BINDS, // NJS-149
'the bind variable placeholder "%s" cannot be used both before and after the RETURNING clause in a DML RETURNING statement');

@@ -550,2 +556,15 @@ // Oracle Net layer errors

//-----------------------------------------------------------------------------
// assertParamPropUnsignedIntNonZero()
//
// Asserts that the property value of a parameter is a positive integer value
// (or undefined).
//-----------------------------------------------------------------------------
function assertParamPropUnsignedIntNonZero(obj, parameterNum, propName) {
if (obj[propName] !== undefined) {
assertParamPropValue(Number.isInteger(obj[propName]) && obj[propName] > 0,
parameterNum, propName);
}
}
//-----------------------------------------------------------------------------
// assertParamPropString()

@@ -646,3 +665,3 @@ //

messages, but only in thin mode since this is done
automatically in thick mode with Oracle Client 23c and higher
automatically in thick mode with Oracle Client 23ai and higher
*/

@@ -816,2 +835,4 @@ const settings = require('./settings.js');

ERR_OBJECT_IS_NOT_A_COLLECTION,
ERR_CURSOR_HAS_BEEN_CLOSED,
ERR_DML_RETURNING_DUP_BINDS,
ERR_CONNECTION_CLOSED_CODE: `${ERR_PREFIX}-${ERR_CONNECTION_CLOSED}`,

@@ -826,2 +847,3 @@ WRN_COMPILATION_CREATE,

assertParamPropUnsignedInt,
assertParamPropUnsignedIntNonZero,
assertParamPropValue,

@@ -828,0 +850,0 @@ assertParamValue,

@@ -40,2 +40,3 @@ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.

this._requestQueue = [];
this._osonMaxFieldNameSize = 255;
}

@@ -114,3 +115,3 @@

_isDate(val) {
return (util.isDate(val));
return (util.types.isDate(val));
}

@@ -117,0 +118,0 @@

@@ -38,6 +38,4 @@ // Copyright (c) 2024, Oracle and/or its affiliates.

// vector flags
TNS_VECTOR_FLAG_DIM_UINT8: 0x0001,
TNS_VECTOR_FLAG_DIM_UINT32: 0x0002,
TNS_VECTOR_FLAG_NORMSRC: 0x0040,
TNS_VECTOR_FLAG_NORM: 0x0008,
TNS_VECTOR_FLAG_NORMSRC: 0x0010,
TNS_VECTOR_FLAG_NORM: 0x0002,

@@ -48,3 +46,4 @@ // base JSON constants

TNS_JSON_MAGIC_BYTE_3: 0x5a, // 'Z'
TNS_JSON_VERSION: 1,
TNS_JSON_VERSION_MAX_FNAME_255: 1,
TNS_JSON_VERSION_MAX_FNAME_65535: 3,
TNS_JSON_FLAG_HASH_ID_UINT8: 0x0100,

@@ -61,2 +60,3 @@ TNS_JSON_FLAG_HASH_ID_UINT16: 0x0200,

TNS_JSON_FLAG_IS_SCALAR: 0x10,
TNS_JSON_FLAG_SEC_FNAMES_SEG_UINT16: 0x100,

@@ -85,2 +85,3 @@ // JSON data types

TNS_JSON_TYPE_VECTOR: 0x01,
TNS_JSON_TYPE_ID: 0x7e,

@@ -87,0 +88,0 @@ // timezone offsets

@@ -1,2 +0,2 @@

// Copyright (c) 2023, Oracle and/or its affiliates.
// Copyright (c) 2023, 2024, Oracle and/or its affiliates.

@@ -39,3 +39,3 @@ //-----------------------------------------------------------------------------

/**
* Class used for decodeing
* Class used for decoding
*/

@@ -56,2 +56,3 @@ class OsonDecoder extends BaseBuffer {

let container, offsetsPos, fieldIdsPos;
const containerOffset = this.pos - this.treeSegPos - 1;
let numChildren = this._getNumChildren(nodeType);

@@ -91,3 +92,6 @@ const isObject = ((nodeType & 0x40) === 0);

this.pos = offsetsPos;
const offset = this._getOffset(nodeType);
let offset = this._getOffset(nodeType);
if (this.relativeOffsets) {
offset += containerOffset;
}
offsetsPos = this.pos;

@@ -149,2 +153,7 @@ this.pos = this.treeSegPos + offset;

return parseFloat(this.readOracleNumber());
} else if (nodeType === constants.TNS_JSON_TYPE_ID) {
const buf = this.readBytes(this.readUInt8());
const jsonId = new types.JsonId(buf.length);
buf.copy(jsonId);
return jsonId;
} else if (nodeType === constants.TNS_JSON_TYPE_BINARY_LENGTH_UINT16) {

@@ -224,2 +233,42 @@ return Buffer.from(this.readBytes(this.readUInt16BE()));

//---------------------------------------------------------------------------
// _getFieldNames
//
// Reads the field names from the buffer.
//---------------------------------------------------------------------------
_getFieldNames(arrStartPos, numFields, offsetsSize, fieldNamesSegSize, fieldNamesSize) {
// skip the hash id array (1 byte * fieldNamesSize for each field)
this.skipBytes(numFields * fieldNamesSize);
// skip the field name offsets array for now
const offsetsPos = this.pos;
this.skipBytes(numFields * offsetsSize);
const ptr = this.readBytes(fieldNamesSegSize);
const finalPos = this.pos;
// determine the names of the fields
this.pos = offsetsPos;
let offset;
for (let i = arrStartPos; i < arrStartPos + numFields; i++) {
if (offsetsSize === 2) {
offset = this.readUInt16BE();
} else {
offset = this.readUInt32BE();
}
// get the field name object
let temp;
if (fieldNamesSize === 1) {
// Short Field Name
temp = ptr.readUInt8(offset);
} else {
// Long Field Name
temp = ptr.readUInt16BE(offset);
}
this.fieldNames[i] = ptr.subarray(offset + fieldNamesSize, offset + temp + fieldNamesSize).toString();
}
this.pos = finalPos;
}
//---------------------------------------------------------------------------
// decode()

@@ -240,10 +289,12 @@ //

const version = this.readUInt8();
if (version !== constants.TNS_JSON_VERSION) {
if (version !== constants.TNS_JSON_VERSION_MAX_FNAME_255 &&
version !== constants.TNS_JSON_VERSION_MAX_FNAME_65535) {
errors.throwErr(errors.ERR_OSON_VERSION_NOT_SUPPORTED, version);
}
const flags = this.readUInt16BE();
const primaryFlags = this.readUInt16BE();
this.relativeOffsets = primaryFlags & constants.TNS_JSON_FLAG_REL_OFFSET_MODE;
// scalar values are much simpler
if (flags & constants.TNS_JSON_FLAG_IS_SCALAR) {
if (flags & constants.TNS_JSON_FLAG_TREE_SEG_UINT32) {
if (primaryFlags & constants.TNS_JSON_FLAG_IS_SCALAR) {
if (primaryFlags & constants.TNS_JSON_FLAG_TREE_SEG_UINT32) {
this.skipBytes(4);

@@ -256,27 +307,42 @@ } else {

// determine the number of field names
let numFieldNames;
if (flags & constants.TNS_JSON_FLAG_NUM_FNAMES_UINT32) {
numFieldNames = this.readUInt32BE();
// determine the number of short field names
let numShortFieldNames;
if (primaryFlags & constants.TNS_JSON_FLAG_NUM_FNAMES_UINT32) {
numShortFieldNames = this.readUInt32BE();
this.fieldIdLength = 4;
} else if (flags & constants.TNS_JSON_FLAG_NUM_FNAMES_UINT16) {
numFieldNames = this.readUInt16BE();
} else if (primaryFlags & constants.TNS_JSON_FLAG_NUM_FNAMES_UINT16) {
numShortFieldNames = this.readUInt16BE();
this.fieldIdLength = 2;
} else {
numFieldNames = this.readUInt8();
numShortFieldNames = this.readUInt8();
this.fieldIdLength = 1;
}
// determine the size of the field names segment
let fieldNameOffsetsSize, fieldNamesSegSize;
if (flags & constants.TNS_JSON_FLAG_FNAMES_SEG_UINT32) {
fieldNameOffsetsSize = 4;
fieldNamesSegSize = this.readUInt32BE();
// determine the size of the short field names segment
let shortFieldNameOffsetsSize, shortFieldNamesSegSize;
if (primaryFlags & constants.TNS_JSON_FLAG_FNAMES_SEG_UINT32) {
shortFieldNameOffsetsSize = 4;
shortFieldNamesSegSize = this.readUInt32BE();
} else {
fieldNameOffsetsSize = 2;
fieldNamesSegSize = this.readUInt16BE();
shortFieldNameOffsetsSize = 2;
shortFieldNamesSegSize = this.readUInt16BE();
}
// if the version indicates that field names > 255 bytes exist, parse
// the information about that segment
let longFieldNameOffsetsSize, longFieldNamesSegSize;
let numLongFieldNames = 0;
if (version === constants.TNS_JSON_VERSION_MAX_FNAME_65535) {
const secondaryFlags = this.readUInt16BE();
if (secondaryFlags & constants.TNS_JSON_FLAG_SEC_FNAMES_SEG_UINT16) {
longFieldNameOffsetsSize = 2;
} else {
longFieldNameOffsetsSize = 4;
}
numLongFieldNames = this.readUInt32BE();
longFieldNamesSegSize = this.readUInt32BE();
}
// skip the size of the tree segment
if (flags & constants.TNS_JSON_FLAG_TREE_SEG_UINT32) {
if (primaryFlags & constants.TNS_JSON_FLAG_TREE_SEG_UINT32) {
this.skipBytes(4);

@@ -290,33 +356,14 @@ } else {

// skip the hash id array
let hashIdSize;
if (flags & constants.TNS_JSON_FLAG_HASH_ID_UINT8) {
hashIdSize = 1;
} else if (flags & constants.TNS_JSON_FLAG_HASH_ID_UINT16) {
hashIdSize = 2;
} else {
hashIdSize = 4;
this.fieldNames = new Array(numShortFieldNames + numLongFieldNames);
// if there are any short names, read them now
if (numShortFieldNames > 0) {
this._getFieldNames(0, numShortFieldNames,
shortFieldNameOffsetsSize, shortFieldNamesSegSize, 1);
}
this.skipBytes(numFieldNames * hashIdSize);
// skip over the field name offsets and field names
let fieldNameOffsetsPos = this.pos;
this.skipBytes(numFieldNames * fieldNameOffsetsSize);
const fieldNamesPos = this.pos;
this.skipBytes(fieldNamesSegSize);
// determine the names of the fields
this.fieldNames = new Array(numFieldNames);
for (let i = 0; i < numFieldNames; i++) {
let offset = fieldNamesPos;
if (flags & constants.TNS_JSON_FLAG_FNAMES_SEG_UINT32) {
offset += this.buf.readUInt32BE(fieldNameOffsetsPos);
fieldNameOffsetsPos += 4;
} else {
offset += this.buf.readUInt16BE(fieldNameOffsetsPos);
fieldNameOffsetsPos += 2;
}
const len = this.buf[offset];
const name = this.buf.subarray(offset + 1, offset + len + 1).toString();
this.fieldNames[i] = name;
// if there are any long names, read them now
if (numLongFieldNames > 0) {
this._getFieldNames(numShortFieldNames, numLongFieldNames,
longFieldNameOffsetsSize, longFieldNamesSegSize, 2);
}

@@ -335,14 +382,18 @@

constructor(name) {
constructor(name, maxFieldNameSize) {
this.name = name;
this.nameBytes = Buffer.from(name);
if (this.nameBytes.length > 255) {
errors.throwErr(errors.ERR_OSON_FIELD_NAME_LIMITATION);
if (this.nameBytes.length > maxFieldNameSize) {
errors.throwErr(errors.ERR_OSON_FIELD_NAME_LIMITATION, maxFieldNameSize);
}
this.hashId = BigInt(0x811C9DC5);
const multiplier = BigInt(16777619);
const mask = BigInt(0xffffffff);
// BigInt constants for calculating Hash ID for the OSON Field Name
const INITIAL_HASHID = 0x811C9DC5n;
const HASH_MULTIPLIER = 16777619n;
const HASH_MASK = 0xffffffffn;
this.hashId = INITIAL_HASHID;
for (let i = 0; i < this.nameBytes.length; i++) {
const c = BigInt(this.nameBytes[i]);
this.hashId = ((this.hashId ^ c) * multiplier) & mask;
this.hashId = ((this.hashId ^ c) * HASH_MULTIPLIER) & HASH_MASK;
}

@@ -356,37 +407,21 @@ this.hashId = Number(this.hashId) & 0xff;

constructor(value) {
constructor() {
super();
this.fieldNamesMap = new Map();
this.fieldNames = [];
this._examineNode(value);
this._processFieldNames();
}
//---------------------------------------------------------------------------
// _exmaineNode()
// addName()
//
// Examines the value. If it contains fields, unique names are retained. The
// values are then examined to see if they also contain fields. Arrays are
// examined to determine they contain elements that contain fields.
// Adds a name to the field names segment.
//---------------------------------------------------------------------------
_examineNode(value) {
if (Array.isArray(value)) {
for (const element of value) {
this._examineNode(element);
}
} else if (value && Array.isArray(value.fields)) {
for (let i = 0; i < value.fields.length; i++) {
const name = value.fields[i];
const element = value.values[i];
if (!this.fieldNamesMap.has(name)) {
const fieldName = new OsonFieldName(name);
this.fieldNamesMap.set(name, fieldName);
this.fieldNames.push(fieldName);
fieldName.offset = this.pos;
this.writeUInt8(fieldName.nameBytes.length);
this.writeBytes(fieldName.nameBytes);
}
this._examineNode(element);
}
addName(fieldName) {
fieldName.offset = this.pos;
if (fieldName.nameBytes.length <= 255) {
this.writeUInt8(fieldName.nameBytes.length);
} else {
this.writeUInt16BE(fieldName.nameBytes.length);
}
this.writeBytes(fieldName.nameBytes);
this.fieldNames.push(fieldName);
}

@@ -399,3 +434,3 @@

//---------------------------------------------------------------------------
_processFieldNames() {
_processFieldNames(fieldIdOffset) {
this.fieldNames.sort((a, b) => {

@@ -417,3 +452,3 @@ if (a.hashId < b.hashId)

for (let i = 0; i < this.fieldNames.length; i++) {
this.fieldNames[i].fieldId = i + 1;
this.fieldNames[i].fieldId = fieldIdOffset + i + 1;
}

@@ -438,3 +473,3 @@ if (this.fieldNames.length < 256) {

//---------------------------------------------------------------------------
_encodeArray(value, fnamesSeg) {
_encodeArray(value, encoder) {
this._encodeContainer(constants.TNS_JSON_TYPE_ARRAY, value.length);

@@ -447,3 +482,3 @@ const len = value.length * 4;

offsetsBufPos += 4;
this.encodeNode(element, fnamesSeg);
this.encodeNode(element, encoder);
}

@@ -480,15 +515,15 @@ }

//---------------------------------------------------------------------------
_encodeObject(value, fnamesSeg) {
_encodeObject(value, encoder) {
const numChildren = value.values.length;
this._encodeContainer(constants.TNS_JSON_TYPE_OBJECT, numChildren);
const len = numChildren * (fnamesSeg.fieldIdSize + 4);
const pos = this.reserveBytes(len);
let fieldIdOffset = pos;
let valueOffset = pos + (numChildren * fnamesSeg.fieldIdSize);
let fieldIdOffset = this.pos;
let valueOffset = this.pos + (numChildren * encoder.fieldIdSize);
const finalOffset = valueOffset + numChildren * 4;
this.reserveBytes(finalOffset - this.pos);
for (let i = 0; i < value.fields.length; i++) {
const fieldName = fnamesSeg.fieldNamesMap.get(value.fields[i]);
if (fnamesSeg.fieldIdSize == 1) {
const fieldName = encoder.fieldNamesMap.get(value.fields[i]);
if (encoder.fieldIdSize == 1) {
this.buf[fieldIdOffset] = fieldName.fieldId;
} else if (fnamesSeg.fieldIdSize == 2) {
} else if (encoder.fieldIdSize == 2) {
this.buf.writeUInt16BE(fieldName.fieldId, fieldIdOffset);

@@ -499,5 +534,5 @@ } else {

this.buf.writeUInt32BE(this.pos, valueOffset);
fieldIdOffset += fnamesSeg.fieldIdSize;
fieldIdOffset += encoder.fieldIdSize;
valueOffset += 4;
this.encodeNode(value.values[i], fnamesSeg);
this.encodeNode(value.values[i], encoder);
}

@@ -511,3 +546,3 @@ }

//---------------------------------------------------------------------------
encodeNode(value, fnamesSeg) {
encodeNode(value, encoder) {

@@ -549,3 +584,3 @@ // handle null

// handle dates
} else if (util.isDate(value)) {
} else if (util.types.isDate(value)) {
if (value.getUTCMilliseconds() === 0) {

@@ -572,3 +607,3 @@ this.writeUInt8(constants.TNS_JSON_TYPE_TIMESTAMP7);

} else if (Array.isArray(value)) {
this._encodeArray(value, fnamesSeg);
this._encodeArray(value, encoder);

@@ -584,5 +619,10 @@ // handle vectors

} else if (value instanceof types.JsonId) {
this.writeUInt8(constants.TNS_JSON_TYPE_ID);
this.writeUInt8(value.length);
this.writeBytes(Buffer.from(value.buffer));
// handle objects
} else {
this._encodeObject(value, fnamesSeg);
this._encodeObject(value, encoder);
}

@@ -594,5 +634,117 @@

/**
* Class used for encoding
*/
class OsonEncoder extends GrowableBuffer {
//---------------------------------------------------------------------------
// _addFieldName()
//
// Add a field with the given name.
//---------------------------------------------------------------------------
_addFieldName(name) {
const fieldName = new OsonFieldName(name, this.maxFieldNameSize);
this.fieldNamesMap.set(name, fieldName);
if (fieldName.nameBytes.length <= 255) {
this.shortFieldNamesSeg.addName(fieldName);
} else {
if (!this.longFieldNamesSeg) {
this.longFieldNamesSeg = new OsonFieldNamesSegment();
}
this.longFieldNamesSeg.addName(fieldName);
}
}
//---------------------------------------------------------------------------
// _examineNode()
//
// Examines the value. If it contains fields, unique names are retained. The
// values are then examined to see if they also contain fields. Arrays are
// examined to determine they contain elements that contain fields.
//---------------------------------------------------------------------------
_examineNode(value) {
if (Array.isArray(value)) {
for (const element of value) {
this._examineNode(element);
}
} else if (value && Array.isArray(value.fields)) {
for (let i = 0; i < value.fields.length; i++) {
const name = value.fields[i];
const element = value.values[i];
if (!this.fieldNamesMap.has(name)) {
this._addFieldName(name);
}
this._examineNode(element);
}
}
}
//---------------------------------------------------------------------------
// _writeExtendedHeader()
//
// Write the extended header containing information about the short and long
// field name segments.
//---------------------------------------------------------------------------
_writeExtendedHeader() {
// write number of short field names
if (this.fieldIdSize === 1) {
this.writeUInt8(this.shortFieldNamesSeg.fieldNames.length);
} else if (this.fieldIdSize === 2) {
this.writeUInt16BE(this.shortFieldNamesSeg.fieldNames.length);
} else {
this.writeUInt32BE(this.shortFieldNamesSeg.fieldNames.length);
}
// write size of short field names segment
if (this.shortFieldNamesSeg.pos < 65536) {
this.writeUInt16BE(this.shortFieldNamesSeg.pos);
} else {
this.writeUInt32BE(this.shortFieldNamesSeg.pos);
}
// write fields for long field names segment, if applicable
if (this.longFieldNamesSeg) {
let secondaryFlags = 0;
if (this.longFieldNamesSeg.pos < 65536) {
secondaryFlags = constants.TNS_JSON_FLAG_SEC_FNAMES_SEG_UINT16;
}
this.writeUInt16BE(secondaryFlags);
this.writeUInt32BE(this.longFieldNamesSeg.fieldNames.length);
this.writeUInt32BE(this.longFieldNamesSeg.pos);
}
}
//---------------------------------------------------------------------------
// _writeFieldNamesSeg()
//
// Write the contents of the field names segment to the buffer.
//---------------------------------------------------------------------------
_writeFieldNamesSeg(fieldNamesSeg) {
// write array of hash ids
for (const fieldName of fieldNamesSeg.fieldNames) {
if (fieldName.nameBytes.length <= 255) {
this.writeUInt8(fieldName.hashId);
} else {
this.writeUInt16BE(fieldName.hashId);
}
}
// write array of field name offsets for the short field names
for (const fieldName of fieldNamesSeg.fieldNames) {
if (fieldNamesSeg.pos < 65536) {
this.writeUInt16BE(fieldName.offset);
} else {
this.writeUInt32BE(fieldName.offset);
}
}
// write field names
if (fieldNamesSeg.pos > 0) {
this.writeBytes(fieldNamesSeg.buf.subarray(0, fieldNamesSeg.pos));
}
}
//---------------------------------------------------------------------------
// encode()

@@ -602,26 +754,51 @@ //

//---------------------------------------------------------------------------
encode(value) {
encode(value, maxFieldNameSize) {
// determine flags to use
let fnamesSeg;
this.maxFieldNameSize = maxFieldNameSize;
// determine the flags to use
let flags = constants.TNS_JSON_FLAG_INLINE_LEAF;
if (Array.isArray(value) || (value && Array.isArray(value.fields))) {
// examine all values recursively to determine the unique set of field
// names and whether they need to be added to the long field names
// segment (> 255 bytes) or short field names segment (<= 255 bytes)
this.fieldNamesMap = new Map();
this.shortFieldNamesSeg = new OsonFieldNamesSegment();
this._examineNode(value);
// perform processing of field names segments and determine the total
// number of unique field names in the value
let totalNumFieldNames = 0;
if (this.shortFieldNamesSeg) {
this.shortFieldNamesSeg._processFieldNames(0);
totalNumFieldNames += this.shortFieldNamesSeg.fieldNames.length;
}
if (this.longFieldNamesSeg) {
this.longFieldNamesSeg._processFieldNames(totalNumFieldNames);
totalNumFieldNames += this.longFieldNamesSeg.fieldNames.length;
}
// determine remaining flags and field id size
flags |= constants.TNS_JSON_FLAG_HASH_ID_UINT8 |
constants.TNS_JSON_FLAG_TINY_NODES_STAT;
fnamesSeg = new OsonFieldNamesSegment(value);
if (fnamesSeg.fieldNames.length > 65535) {
if (totalNumFieldNames > 65535) {
flags |= constants.TNS_JSON_FLAG_NUM_FNAMES_UINT32;
} else if (fnamesSeg.fieldNames.length > 255) {
this.fieldIdSize = 4;
} else if (totalNumFieldNames > 255) {
flags |= constants.TNS_JSON_FLAG_NUM_FNAMES_UINT16;
this.fieldIdSize = 2;
} else {
this.fieldIdSize = 1;
}
if (fnamesSeg.pos > 65535) {
if (this.shortFieldNamesSeg.pos > 65535) {
flags |= constants.TNS_JSON_FLAG_FNAMES_SEG_UINT32;
}
} else {
// if the value is a simple scalar
flags |= constants.TNS_JSON_FLAG_IS_SCALAR;
}
// encode values into the tree segment
// encode values into the OSON tree segment
const treeSeg = new OsonTreeSegment();
treeSeg.encodeNode(value, fnamesSeg);
treeSeg.encodeNode(value, this);
if (treeSeg.pos > 65535) {

@@ -635,24 +812,12 @@ flags |= constants.TNS_JSON_FLAG_TREE_SEG_UINT32;

this.writeUInt8(constants.TNS_JSON_MAGIC_BYTE_3);
this.writeUInt8(constants.TNS_JSON_VERSION);
if (this.longFieldNamesSeg) {
this.writeUInt8(constants.TNS_JSON_VERSION_MAX_FNAME_65535);
} else {
this.writeUInt8(constants.TNS_JSON_VERSION_MAX_FNAME_255);
}
this.writeUInt16BE(flags);
// write extended header (when value is not scalar)
if (fnamesSeg) {
// write number of field names
if (fnamesSeg.fieldNames.length < 256) {
this.writeUInt8(fnamesSeg.fieldNames.length);
} else if (fnamesSeg.fieldNames.length < 65536) {
this.writeUInt16BE(fnamesSeg.fieldNames.length);
} else {
this.writeUInt32BE(fnamesSeg.fieldNames.length);
}
// write size of field names segment
if (fnamesSeg.pos < 65536) {
this.writeUInt16BE(fnamesSeg.pos);
} else {
this.writeUInt32BE(fnamesSeg.pos);
}
if (this.shortFieldNamesSeg) {
this._writeExtendedHeader();
}

@@ -668,3 +833,3 @@

// write remainder of header and any data (when value is not scalar)
if (fnamesSeg) {
if (this.shortFieldNamesSeg) {

@@ -674,21 +839,7 @@ // write number of "tiny" nodes (always zero)

// write array of hash ids
for (const fieldName of fnamesSeg.fieldNames) {
this.writeUInt8(fieldName.hashId);
// write the field names segments
this._writeFieldNamesSeg(this.shortFieldNamesSeg);
if (this.longFieldNamesSeg) {
this._writeFieldNamesSeg(this.longFieldNamesSeg);
}
// write array of field name offsets
for (const fieldName of fnamesSeg.fieldNames) {
if (fnamesSeg.pos < 65536) {
this.writeUInt16BE(fieldName.offset);
} else {
this.writeUInt32BE(fieldName.offset);
}
}
// write field names
if (fnamesSeg.pos > 0) {
this.writeBytes(fnamesSeg.buf.subarray(0, fnamesSeg.pos));
}
}

@@ -695,0 +846,0 @@

@@ -57,10 +57,3 @@ // Copyright (c) 2024, Oracle and/or its affiliates.

const vectorFormat = this.readUInt8();
let numElements;
if (flags & constants.TNS_VECTOR_FLAG_DIM_UINT8) {
numElements = this.readUInt8();
} else if (flags & constants.TNS_VECTOR_FLAG_DIM_UINT32) {
numElements = this.readUInt32BE();
} else {
numElements = this.readUInt16BE();
}
const numElements = this.readUInt32BE();
let elementSize, result;

@@ -121,10 +114,4 @@ if (vectorFormat === constants.VECTOR_FORMAT_FLOAT32) {

// Let server generate the norm (TNS_VECTOR_FLAG_NORMSRC)
let flags = constants.TNS_VECTOR_FLAG_NORM
const flags = constants.TNS_VECTOR_FLAG_NORM
| constants.TNS_VECTOR_FLAG_NORMSRC;
const numElements = value.length;
if (numElements < 256) {
flags |= constants.TNS_VECTOR_FLAG_DIM_UINT8;
} else if (numElements > 65535) {
flags |= constants.TNS_VECTOR_FLAG_DIM_UINT32;
}

@@ -136,9 +123,3 @@ // write header

this.writeUInt8(vectorFormat);
if (numElements < 256) {
this.writeUInt8(numElements);
} else if (numElements < 65536) {
this.writeUInt16BE(numElements);
} else {
this.writeUInt32BE(numElements);
}
this.writeUInt32BE(value.length);
this.reserveBytes(8);

@@ -145,0 +126,0 @@

@@ -127,2 +127,12 @@ // Copyright (c) 2015, 2023, Oracle and/or its affiliates.

function _isPrivilege(value) {
// Privileges are mutually exclusive and cannot be specified together
// except SYSPRELIM, which cannot be specified alone, it is specified in a
// combo with SYSOPER or SYSDBA. SYSPRELIM is used only for
// startup/shutdown
// If SYSPRELIM specified, clear the bit
if (value & constants.SYSPRELIM) {
value = value ^ constants.SYSPRELIM;
}
return (

@@ -135,3 +145,2 @@ value === constants.SYSASM ||

value === constants.SYSOPER ||
value === constants.SYSPRELIM ||
value === constants.SYSRAC

@@ -837,2 +846,3 @@ );

Connection,
JsonId: types.JsonId,
Lob,

@@ -839,0 +849,0 @@ Pool,

@@ -684,3 +684,3 @@ // Copyright (c) 2016, 2024, Oracle and/or its affiliates.

errors.assertParamPropUnsignedInt(options, 1, "poolMin");
errors.assertParamPropUnsignedInt(options, 1, "poolMax");
errors.assertParamPropUnsignedIntNonZero(options, 1, "poolMax");
errors.assertParamPropUnsignedInt(options, 1, "poolMaxPerShard");

@@ -693,2 +693,8 @@ errors.assertParamPropUnsignedInt(options, 1, "poolIncrement");

// poolMax must be greater than or equal to poolMin
if (options.poolMin > options.poolMax) {
errors.throwErr(errors.ERR_INVALID_NUMBER_OF_CONNECTIONS, options.poolMax,
options.poolMin);
}
// reconfiguration can happen only when status is OPEN

@@ -695,0 +701,0 @@ this._checkPoolOpen(false);

@@ -66,2 +66,3 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

this.fetchTypeHandler = undefined;
this._JsonId = types.JsonId;
}

@@ -68,0 +69,0 @@

@@ -53,4 +53,2 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

const connectionCookies = new Map();
class ThinConnectionImpl extends ConnectionImpl {

@@ -187,4 +185,11 @@

message.batchErrors = options.batchErrors;
if (statement.isPlSql && statement.requiresFullExecute) {
// if a PL/SQL statement requires a full execute, perform only a single
// iteration in order to allow the determination of input/output binds
// to be completed; after that, an execution of the remaining iterations
// can be performed.
if (statement.isPlSql && (statement.cursorId === 0 ||
statement.requiresFullExecute)) {
message.numExecs = 1;
message.noImplicitRelease = true;
await this._protocol._processMessage(message);

@@ -194,2 +199,3 @@ statement.requiresFullExecute = false;

message.offset = 1;
message.noImplicitRelease = false;
}

@@ -594,22 +600,2 @@ if (message.numExecs > 0) {

//---------------------------------------------------------------------------
// getConnectionCookieByUUID()
//
// It fetches from map which keeps keyname as UUID+ServiceName.
// UUID identifies the CDB instance and ServiceName identifies the
// entity within a PDB which uniquely identifies a pdb instance.
//---------------------------------------------------------------------------
getConnectionCookieByUUID(uuid) {
let cookie;
if (uuid) {
const key = uuid + ((this.serviceName) ? this.serviceName : this.sid);
cookie = connectionCookies.get(key);
if (!cookie) {
cookie = {};
connectionCookies.set(key, cookie);
}
}
return cookie;
}
/**

@@ -699,33 +685,20 @@ *

try {
const cookie = this.getConnectionCookieByUUID(this.nscon.dbUUID);
this.nscon.dbUUID = null;
const protocolMessage = new messages.ProtocolMessage(this);
const dataTypeMessage = new messages.DataTypeMessage(this);
const authMessage = new messages.AuthMessage(this, params);
let sentCookie = false;
if (cookie && cookie.populated) {
const cookieMessage = new messages.ConnectionCookieMessage(this);
cookieMessage.cookie = cookie;
cookieMessage.protocolMessage = protocolMessage;
cookieMessage.dataTypeMessage = dataTypeMessage;
cookieMessage.authMessage = authMessage;
await this._protocol._processMessage(cookieMessage);
sentCookie = true;
if (this.nscon.supportsFastAuth) {
const fastAuthMessage = new messages.FastAuthMessage(this);
fastAuthMessage.protocolMessage = protocolMessage;
fastAuthMessage.dataTypeMessage = dataTypeMessage;
fastAuthMessage.authMessage = authMessage;
await this._protocol._processMessage(fastAuthMessage);
if (fastAuthMessage.reNegotiate) {
// Fast Authentication failed.
await this._protocol._processMessage(dataTypeMessage);
await this._protocol._processMessage(authMessage);
}
} else {
await this._protocol._processMessage(protocolMessage);
}
if (!sentCookie || !cookie.populated) {
await this._protocol._processMessage(dataTypeMessage);
// Does OSESSKEY for non-token Authentication else OAUTH
await this._protocol._processMessage(authMessage);
if (cookie && !cookie.populated) {
cookie.protocolVersion = protocolMessage.serverVersion;
cookie.serverBanner = protocolMessage.serverBanner;
cookie.charsetID = this._protocol.caps.charSetID;
cookie.ncharsetID = this._protocol.caps.nCharsetId;
cookie.flags = protocolMessage.serverFlags;
cookie.compileCaps = Buffer.from(protocolMessage.serverCompileCaps);
cookie.runtimeCaps = Buffer.from(protocolMessage.serverRunTimeCaps);
cookie.populated = true;
}
}

@@ -930,6 +903,4 @@ if (!params.token) { // non-token Authentication

_getStatement(sql, cacheStatement = false) {
if (this._drcpEstablishSession) {
cacheStatement = false;
}
return this.statementCache.getStatement(sql, cacheStatement);
return this.statementCache.getStatement(sql, cacheStatement,
this._drcpEstablishSession);
}

@@ -1086,3 +1057,3 @@

getTransactionInProgress() {
return this._protocol.txnInProgress === constants.TNS_TXN_IN_PROGRESS;
return this._protocol.txnInProgress;
}

@@ -1089,0 +1060,0 @@

@@ -108,2 +108,3 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

this._isDRCPEnabled = false;
this._implicitPool = null;
this.eventEmitter = new EventEmitter();

@@ -389,7 +390,7 @@ // listener to remove dead or idle connections

//---------------------------------------------------------------------------
// _getNumConns()
// _getNumConnsToCreate()
//
// get number of connections need to be created
//---------------------------------------------------------------------------
_getNumConns() {
_getNumConnsToCreate() {
const usedConns = this._freeConnectionList.length + this._usedConnectionList.size;

@@ -420,7 +421,15 @@ // less connections in the pool than poolMin? restore to poolMin

while (!this._poolCloseWaiter) {
// get count for connections to be created
const numConns = this._getNumConns();
// eliminate connections that exceed the poolMax (this should only happen
// after a reconfiguration has taken place where the maximum number of
// connections is reduced)
let numToDestroy = this._poolMax - this.getConnectionsOpen();
while (numToDestroy > 0 && this._freeConnectionList.length > 0) {
const connToBeRemoved = this._freeConnectionList.shift();
this.eventEmitter.emit('_removePoolConnection', connToBeRemoved);
numToDestroy--;
}
const numToCreate = this._getNumConnsToCreate();
// connection creation is going on serially and not concurrently
for (let i = 0; i < numConns; i++) {
for (let i = 0; i < numToCreate; i++) {
try {

@@ -570,4 +579,10 @@ // get deobfuscated value

conn._newSession = false;
this._freeConnectionList.push(conn);
if ((this._freeConnectionList.length + this._usedConnectionList.size)
< this._poolMax) {
this._freeConnectionList.push(conn);
} else {
this.eventEmitter.emit('_removePoolConnection', conn);
}
}
this._setScheduler();

@@ -585,4 +600,45 @@ }

}
//---------------------------------------------------------------------------
// reconfigure()
//
// Reconfigures the pool with new parameters
//---------------------------------------------------------------------------
reconfigure(params) {
if (params.poolIncrement !== undefined) {
this._poolIncrement = params.poolIncrement;
}
if (params.poolTimeout !== undefined &&
this._poolTimeout !== params.poolTimeout) {
this._poolTimeout = params.poolTimeout;
// clear scheduled job
if (this._schedulerJob) {
clearTimeout(this._schedulerJob);
this._schedulerJob = null;
}
}
if (params.poolPingInterval !== undefined) {
this._poolPingInterval = params.poolPingInterval;
}
if (params.stmtCacheSize !== undefined) {
this._stmtCacheSize = params.stmtCacheSize;
}
if (params.poolMax !== undefined) {
this._poolMax = params.poolMax;
}
if (params.poolMin !== undefined) {
this._poolMin = params.poolMin;
}
if (this.bgWaiter) {
this.bgWaiter();
}
}
}
module.exports = ThinPoolImpl;

@@ -39,4 +39,4 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

constructor(protocolVersion) {
this.protocolVersion = protocolVersion;
constructor(nscon) {
this.protocolVersion = nscon.sAtts.version;
this.ttcFieldVersion = constants.TNS_CCAP_FIELD_VERSION_MAX;

@@ -48,3 +48,3 @@ this.supports12cLogon = true;

this.runtimeCaps = Buffer.alloc(constants.TNS_RCAP_MAX);
this.initCompileCaps();
this.initCompileCaps(nscon);
this.initRuntimeCaps();

@@ -54,3 +54,3 @@ this.maxStringSize = 0;

adjustForServerCompileCaps(serverCaps) {
adjustForServerCompileCaps(serverCaps, nscon) {
if (serverCaps[constants.TNS_CCAP_FIELD_VERSION] < this.ttcFieldVersion) {

@@ -61,2 +61,9 @@ this.ttcFieldVersion = serverCaps[constants.TNS_CCAP_FIELD_VERSION];

}
if ((this.ttcFieldVersion < constants.TNS_CCAP_FIELD_VERSION_23_4
&& nscon.endOfRequestSupport)) {
// endOfRequestSupport used only from 23.4 onwards and not for 23.3
this.compileCaps[constants.TNS_CCAP_TTC4]
^= constants.TNS_CCAP_END_OF_REQUEST;
nscon.endOfRequestSupport = false;
}
}

@@ -72,3 +79,3 @@

initCompileCaps() {
initCompileCaps(nscon) {
this.compileCaps[constants.TNS_CCAP_SQL_VERSION] =

@@ -112,2 +119,7 @@ constants.TNS_CCAP_SQL_VERSION_MAX;

constants.TNS_CCAP_INBAND_NOTIFICATION;
if (nscon.endOfRequestSupport) {
this.compileCaps[constants.TNS_CCAP_TTC4] |= constants.TNS_CCAP_END_OF_REQUEST;
}
this.compileCaps[constants.TNS_CCAP_CTB_FEATURE_BACKPORT] =
constants.TNS_CCAP_CTB_IMPLICIT_POOL;
this.compileCaps[constants.TNS_CCAP_TTC5] =

@@ -114,0 +126,0 @@ constants.TNS_CCAP_VECTOR_SUPPORT;

@@ -436,3 +436,4 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

TNS_MSG_TYPE_RENEGOTIATE: 28,
TNS_MSG_TYPE_COOKIE: 30,
TNS_MSG_TYPE_END_OF_REQUEST: 29,
TNS_MSG_TYPE_FAST_AUTH: 34,

@@ -468,2 +469,3 @@ // parameter keyword numbers,

TNS_EXEC_OPTION_BATCH_ERRORS: 0x80000,
TNS_EXEC_OPTION_NO_IMPL_REL: 0x200000,

@@ -563,2 +565,3 @@ // server side piggyback op codes

TNS_CCAP_LOGON_TYPES: 4,
TNS_CCAP_CTB_FEATURE_BACKPORT: 5,
TNS_CCAP_FIELD_VERSION: 7,

@@ -631,5 +634,7 @@ TNS_CCAP_SERVER_DEFINE_CONV: 8,

TNS_CCAP_INBAND_NOTIFICATION: 0x04,
TNS_CCAP_END_OF_REQUEST: 0x20,
TNS_CCAP_CLIENT_FN_MAX: 12,
TNS_CCAP_LOB2_QUASI: 0x01,
TNS_CCAP_LOB2_2GB_PREFETCH: 0x04,
TNS_CCAP_CTB_IMPLICIT_POOL: 0x08,
TNS_CCAP_VECTOR_SUPPORT: 0x08,

@@ -658,2 +663,6 @@

// end of call status flags
TNS_EOCS_FLAGS_TXN_IN_PROGRESS: 0x00000002,
TNS_EOCS_FLAGS_SESS_RELEASE: 0x00008000,
// other constants

@@ -668,5 +677,5 @@ TNS_ESCAPE_CHAR: 253,

TNS_TDU: 65535,
TNS_TXN_IN_PROGRESS: 0x00000002,
TNS_MAX_CONNECT_DATA: 230,
TNS_MAX_UROWID_LENGTH: 3950,
TNS_SERVER_CONVERTS_CHARS: 0x01, // server does charset conversion

@@ -744,4 +753,7 @@ // drcp release mode

// Network Header flags for Data packet
TNS_DATA_FLAGS_END_OF_REQUEST: 0x2000,
TNS_BASE64_ALPHABET_ARRAY: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'),
TNS_EXTENT_OID: Buffer.from('00000000000000000000000000010001', 'hex')
};

@@ -184,3 +184,3 @@ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.

}
buf.writeKeyValue("AUTH_TERMINAL", "unknown");
buf.writeKeyValue("AUTH_TERMINAL", cInfo.terminal);
buf.writeKeyValue("AUTH_PROGRAM_NM", cInfo.program);

@@ -187,0 +187,0 @@ buf.writeKeyValue("AUTH_MACHINE", cInfo.hostName);

@@ -45,6 +45,5 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

this.flushOutBinds = false;
this.endOfResponse = false;
this.endToEndSeqNum = 0;
this.errorOccurred = false;
this.flushOutBinds = false;
this.processedError = false;
this.warning = undefined;

@@ -165,3 +164,3 @@ }

}
this.processedError = true;
this.endOfResponse = !this.connection.nscon.endOfRequestSupport;
}

@@ -183,6 +182,2 @@

hasMoreData(buf) {
return buf.numBytesLeft() > 0 && !this.flushOutBinds;
}
decode(buf) {

@@ -193,4 +188,4 @@ this.process(buf);

process(buf) {
this.endOfResponse = false;
this.flushOutBinds = false;
this.processedError = false;
do {

@@ -200,3 +195,3 @@ this.savePoint(buf);

this.processMessage(buf, messageType);
} while (this.hasMoreData(buf));
} while (!this.endOfResponse);
}

@@ -216,2 +211,3 @@

this.endToEndSeqNum = buf.readUB2();
this.endOfResponse = !this.connection.nscon.endOfRequestSupport;
} else if (messageType === constants.TNS_MSG_TYPE_PARAMETER) {

@@ -221,2 +217,4 @@ this.processReturnParameter(buf);

this.processServerSidePiggyBack(buf);
} else if (messageType === constants.TNS_MSG_TYPE_END_OF_REQUEST) {
this.endOfResponse = true;
} else {

@@ -292,3 +290,3 @@ errors.throwErr(errors.ERR_UNEXPECTED_MESSAGE_TYPE, messageType, buf.pos, buf.packetNum);

if (this.connection._drcpEstablishSession) {
this.connection.statementCache.clearOpenCursors();
this.connection.statementCache.clearCursors();
}

@@ -295,0 +293,0 @@ }

@@ -51,2 +51,3 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

}
this.endOfResponse = !this.connection.nscon.endOfRequestSupport;
} else {

@@ -53,0 +54,0 @@ super.processMessage(buf, messageType);

@@ -71,2 +71,6 @@ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.

if (this.noImplicitRelease) {
dmlOptions |= constants.TNS_EXEC_OPTION_NO_IMPL_REL;
}
if (!stmt.requiresDefine && !this.parseOnly && params) {

@@ -78,3 +82,3 @@ numParams = params.length;

} else if (!this.parseOnly && stmt.sql) {
dmlOptions = constants.TNS_EXEC_OPTION_IMPLICIT_RESULTSET;
dmlOptions |= constants.TNS_EXEC_OPTION_IMPLICIT_RESULTSET;
options |= constants.TNS_EXEC_OPTION_EXECUTE;

@@ -81,0 +85,0 @@ }

@@ -31,2 +31,3 @@ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.

const MessageWithData = require("./withData.js");
const errors = require("../../../errors.js");

@@ -55,2 +56,5 @@ /**

this.writeFunctionHeader(buf);
if (this.statement.cursorId === 0) {
errors.throwErr(errors.ERR_CURSOR_HAS_BEEN_CLOSED);
}
buf.writeUB4(this.statement.cursorId);

@@ -57,0 +61,0 @@ buf.writeUB4(this.options.fetchArraySize);

@@ -40,3 +40,3 @@ // Copyright (c) 2023, Oracle and/or its affiliates.

const SessionReleaseMessage = require('./sessionRelease.js');
const ConnectionCookieMessage = require('./connectionCookie.js');
const FastAuthMessage = require('./fastAuth.js');

@@ -46,3 +46,3 @@ module.exports = {

CommitMessage,
ConnectionCookieMessage,
FastAuthMessage,
DataTypeMessage,

@@ -49,0 +49,0 @@ ExecuteMessage,

@@ -56,2 +56,3 @@ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.

this.processProtocolInfo(buf);
this.endOfResponse = !this.connection.nscon.endOfRequestSupport;
} else {

@@ -79,3 +80,10 @@ super.processMessage(buf, messageType);

this.serverCompileCaps = Buffer.from(serverCompileCaps);
buf.caps.adjustForServerCompileCaps(this.serverCompileCaps);
buf.caps.adjustForServerCompileCaps(this.serverCompileCaps, this.connection.nscon);
// Set the maximum OSON field name size
if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_23_1) {
this.connection._osonMaxFieldNameSize = 65535;
} else {
this.connection._osonMaxFieldNameSize = 255;
}
}

@@ -82,0 +90,0 @@ const serverRunTimeCaps = buf.readBytesWithLength();

@@ -88,2 +88,3 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

this.flushOutBinds = true;
this.endOfResponse = true;
} else if (messageType === constants.TNS_MSG_TYPE_ERROR) {

@@ -96,6 +97,2 @@ this.processErrorInfo(buf);

hasMoreData() {
return !this.processedError && !this.flushOutBinds;
}
processErrorInfo(buf) {

@@ -857,3 +854,3 @@ super.processErrorInfo(buf);

} else if (oraTypeNum === constants.TNS_DATA_TYPE_JSON) {
buf.writeOson(value);
buf.writeOson(value, this.connection._osonMaxFieldNameSize);
} else if (oraTypeNum === constants.TNS_DATA_TYPE_VECTOR) {

@@ -860,0 +857,0 @@ buf.writeVector(value);

@@ -38,2 +38,5 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

const TNS_BASE64_ALPHABET_ARRAY = Buffer.from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 'utf8');
const FAST_AUTH_END_OF_RPC_VALUE = 0x800;
const FAST_AUTH_END_OF_RPC_OFFSET = 0x8;
const MSG_TYPE_OFFSET = 11;

@@ -294,4 +297,10 @@ /**

async waitForPackets() {
const packet = await this.nsi.recvPacket();
/**
* Read packets from network.
* If checkRequestBoundary is passed as true, it
* would read all packets until end of request
* boundary is seen in nwk header.
*/
async waitForPackets(checkRequestBoundary = false) {
let packet = await this.nsi.recvPacket();
if (!this.savedPackets) {

@@ -303,2 +312,20 @@ this.savedPackets = [packet];

}
if (checkRequestBoundary && this.nsi.endOfRequestSupport) {
while (packet.type === constants.TNS_PACKET_TYPE_DATA) {
// End Marker
if ((packet.buf.readUInt16BE(8) &
constants.TNS_DATA_FLAGS_END_OF_REQUEST)) {
break;
}
// Single Byte 1D packet
if (packet.buf.length === MSG_TYPE_OFFSET &&
packet.buf[MSG_TYPE_OFFSET - 1] ===
constants.TNS_MSG_TYPE_END_OF_REQUEST) {
break;
}
packet = await this.nsi.recvPacket();
this.savedPackets.push(packet);
}
}
this.startPacket(this.savedPackets[this.savedPacketPos++]);

@@ -501,2 +528,6 @@ }

this.startPacket();
} else {
// Write End of RPC bit in last packet used only for fastAuth Message.
this.buf.writeUInt16BE(FAST_AUTH_END_OF_RPC_VALUE,
FAST_AUTH_END_OF_RPC_OFFSET);
}

@@ -552,5 +583,5 @@ if (!this.nsi.ntAdapter) {

*/
writeOson(value) {
writeOson(value, osonMaxFieldSize) {
const encoder = new oson.OsonEncoder();
const buf = encoder.encode(value);
const buf = encoder.encode(value, osonMaxFieldSize);
this.writeQLocator(buf.length);

@@ -557,0 +588,0 @@ this.writeBytesWithLength(buf);

@@ -1,2 +0,2 @@

// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.

@@ -52,3 +52,3 @@ //-----------------------------------------------------------------------------

*/
this.caps = new Capabilities(conn.nscon.sAtts.version);
this.caps = new Capabilities(conn.nscon);
this.writeBuf = new WritePacket(conn.nscon, this.caps, this);

@@ -71,7 +71,7 @@ this.readBuf = new ReadPacket(conn.nscon, this.caps);

message.preProcess();
await this.readBuf.waitForPackets();
await this.readBuf.waitForPackets(true);
while (true) { // eslint-disable-line
if (this.nsi.isBreak) {
await this.resetMessage();
delete this.readBuf.savedBuffers;
delete this.readBuf.savedPackets;
await this.readBuf.waitForPackets();

@@ -169,3 +169,8 @@ }

}
this.txnInProgress = message.callStatus & constants.TNS_TXN_IN_PROGRESS;
this.txnInProgress = Boolean(message.callStatus & constants.TNS_EOCS_FLAGS_TXN_IN_PROGRESS);
// processes the call status flags returned by the server.
if (message.callStatus & constants.TNS_EOCS_FLAGS_SESS_RELEASE) {
message.connection.statementCache.clearCursors();
}
if (message.errorOccurred) {

@@ -172,0 +177,0 @@ if (callTimeoutExpired) {

@@ -55,26 +55,19 @@ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.

// obfuscate value and clear memory for Buffers as they are from Buffer pool
// and are possible to stay longer
// obfuscate value
function setObfuscatedValue(value) {
const buf = crypto.randomBytes(Buffer.byteLength(value));
const bytes = Buffer.from(value, 'utf8');
const len = Buffer.byteLength(value);
const arr = [];
for (let i = 0; i < len; i++) {
arr.push(buf[i] ^ bytes[i]);
const valueBytes = Buffer.from(value);
const obfuscatedBytes = crypto.randomBytes(valueBytes.length);
for (let i = 0; i < valueBytes.length; i++) {
valueBytes[i] = obfuscatedBytes[i] ^ valueBytes[i];
}
bytes.fill(0);
return {obfuscatedValue: buf, value: arr};
return {obfuscatedValue: obfuscatedBytes, value: valueBytes};
}
// returns the Deobfuscated value, after removing the obfuscation
// returns the deobfuscated value, after removing the obfuscation
// and clear memory of temporary Buffers coming from Buffer pool
function getDeobfuscatedValue(value, obfuscatedValue) {
const arr = [];
for (let i = 0; i < value.length; i++) {
arr.push(value[i] ^ obfuscatedValue[i]);
function getDeobfuscatedValue(valueBytes, obfuscatedBytes) {
const buf = Buffer.from(valueBytes);
for (let i = 0; i < valueBytes.length; i++) {
buf[i] = valueBytes[i] ^ obfuscatedBytes[i];
}
const buf = Buffer.from(arr);
arr.fill(0);
const retVal = buf.toString();

@@ -81,0 +74,0 @@ buf.fill(0);

@@ -1,2 +0,2 @@

// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.

@@ -110,3 +110,4 @@ //-----------------------------------------------------------------------------

TNS_VERSION_MINIMUM: 300,
TNS_VERSION_MIN_UUID: 319,
TNS_VERSION_MIN_DATA_FLAGS: 318,
TNS_VERSION_MIN_END_OF_RESPONSE: 319,
TNS_UUID_OFFSET: 45,

@@ -147,2 +148,4 @@

NSGPCHKSCMD: 0x01000000, // Support for Poll and Check logic
TNS_ACCEPT_FLAG_HAS_END_OF_REQUEST: 0x02000000,
TNS_ACCEPT_FLAG_FAST_AUTH: 0x10000000, // Support Fast Auth

@@ -149,0 +152,0 @@ /* Redirect packet */

@@ -1,2 +0,2 @@

// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.

@@ -167,2 +167,3 @@ //-----------------------------------------------------------------------------

const serviceTag = this.urlProps.get("SERVICE_TAG");
const poolBoundary = this.urlProps.get("POOL_BOUNDARY");

@@ -186,2 +187,4 @@ const parts = [];

parts.push(`(CONNECTION_ID_PREFIX=${connectionIdPrefix})`);
if (poolBoundary)
parts.push(`(POOL_BOUNDARY=${poolBoundary})`);
return `(CONNECT_DATA=${parts.join("")})`;

@@ -216,6 +219,6 @@ }

const addressLists = hostInfo.split(";");
for (const addressList in addressLists) {
for (const addressList of addressLists) {
let addressNodeCount = 0;
const addressListBuilder = new Array();
for (const match of addressLists[addressList].matchAll(HOSTNAMES_PATTERN)) {
for (const match of addressList.matchAll(HOSTNAMES_PATTERN)) {
const hostnames = (match.groups.hostnames).split(',');

@@ -226,4 +229,4 @@ let port = match.groups.port;

}
for (const hname in hostnames) {
addressListBuilder.push(this.getAddrStr(hostnames[hname], port, protocol, proxyInfo));
for (const hname of hostnames) {
addressListBuilder.push(this.getAddrStr(hname, port, protocol, proxyInfo));
addressNodeCount++;

@@ -462,4 +465,5 @@ }

aliasMap.set("connection_id_prefix", "CONNECTION_ID_PREFIX");
aliasMap.set("pool_boundary", "POOL_BOUNDARY");
return aliasMap;
}
}module.exports = EZConnectResolver;

@@ -489,3 +489,3 @@ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.

addresses = await dnsPromises.lookup(this.host, options);
for (const addr in addresses) {
for (const addr of addresses) {
const co = new ConnOption();

@@ -503,3 +503,3 @@ co.hostname = this.host;

co.CNdata.push(this.toString());
co.host = addresses[addr].address;
co.host = addr.address;
co.addr = this.addr;

@@ -782,3 +782,4 @@ cs.getcurrentDescription().addConnectOption(co);

}
const cid = `(CID=(PROGRAM=${cInfo.program})(HOST=${cInfo.hostName})(USER=${cInfo.userName}))`;
const pgmName = "\"'" + cInfo.program + "'\"";
const cid = `(CID=(PROGRAM=${pgmName})(HOST=${cInfo.hostName})(USER=${cInfo.userName}))`;
cOpts[i].CNdata.push(NavSchemaObject.CD);

@@ -785,0 +786,0 @@ cOpts[i].CNdata.push(this.connectData);

@@ -62,3 +62,3 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

return [serverVal, connClass, svcname, poolPurity, sid, addressNode ];
return [serverVal, connClass, svcname, poolPurity, sid, addressNode];
}

@@ -87,2 +87,8 @@

errors.throwErr(errors.ERR_TNS_ENTRY_NOT_FOUND, connStr, configDir ? configDir + '/tnsnames.ora' : process.env.TNS_ADMIN + '/tnsnames.ora');
if (resolvedVal.rhsType == 1) {
const rString = resolvedVal.atom;
if ((rString.indexOf(':') != -1) || (rString.indexOf('/') != -1)) {
return new EzConnect(rString).getResolvedUrl();
}
}
resolvedVal = resolvedVal.getListElement(0);

@@ -359,4 +365,9 @@ }

Packet.AcceptPacket(packet, this.sAtts);
this.dbUUID = packet.dbUUID;
packet.dbUUID = null;
if (this.sAtts.version >= constants.TNS_VERSION_MIN_END_OF_RESPONSE
&& (packet.flags & constants.TNS_ACCEPT_FLAG_HAS_END_OF_REQUEST)) {
this.endOfRequestSupport = true;
}
if (packet.flags & constants.TNS_ACCEPT_FLAG_FAST_AUTH) {
this.supportsFastAuth = true;
}
break;

@@ -363,0 +374,0 @@ case constants.NSPTRF: /* REFUSE */

@@ -249,7 +249,4 @@ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.

/* UUID - CDB Instance ID */
if (sAtts.version >= constants.TNS_VERSION_MIN_UUID) {
packet.dbUUID = packet.buf.subarray(constants.TNS_UUID_OFFSET,
constants.TNS_UUID_OFFSET + 16);
packet.dbUUID = packet.dbUUID.toString('base64');
if (sAtts.version >= constants.TNS_VERSION_MIN_DATA_FLAGS) {
packet.flags = packet.buf.readUInt32BE(constants.NSPACFL2);
}

@@ -256,0 +253,0 @@ }

@@ -31,2 +31,3 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

const constants = require('../constants');
const errors = require('../errors');

@@ -363,2 +364,3 @@ /**

this.bufferRowCount = 0;
this.pendingClear = false;
this.statementType = constants.STMT_TYPE_UNKNOWN;

@@ -500,2 +502,8 @@ }

if (this.bindInfoDict.has(info.bindName)) {
if (this.isReturning) {
const origInfo = this.bindInfoDict.get(info.bindName)[0];
if (!origInfo.isReturnBind) {
errors.throwErr(errors.ERR_DML_RETURNING_DUP_BINDS, name);
}
}
this.bindInfoDict.get(info.bindName).push(info);

@@ -534,4 +542,32 @@ } else {

}
//---------------------------------------------------------------------------
// _clearAllState
//
// clear all state associated with the cursor
//---------------------------------------------------------------------------
_clearAllState() {
this.cursorId = 0;
this.requiresDefine = false;
this.noPrefetch = false;
this.requiresFullExecute = false;
this.queryVars = [];
this.numQueryVars = 0;
this.bufferRowCount = 0;
this.bufferRowIndex = 0;
}
//---------------------------------------------------------------------------
// _clearState
//
// clear some state associated with the cursor
//---------------------------------------------------------------------------
_clearState() {
this.cursorId = 0;
this.requiresDefine = false;
this.noPrefetch = false;
this.requiresFullExecute = false;
}
}
module.exports.Statement = Statement;

@@ -74,3 +74,3 @@ // Copyright (c) 2024, Oracle and/or its affiliates.

//---------------------------------------------------------------------------
//clearOpenCursors() {
//clearCursors() {
// Clears the list of open cursors and removes the list of cursors that

@@ -80,14 +80,31 @@ // need to be closed. This is required when a DRCP session change has

//---------------------------------------------------------------------------
clearOpenCursors() {
clearCursors() {
const newOpenCursors = new Set();
for (const stmt of this._openCursors) {
stmt.cursorId = 0;
if (stmt.inUse) {
if (stmt.inUse || stmt.returnToCache) {
stmt.pendingClear = true;
newOpenCursors.add(stmt);
}
stmt._clearState();
}
this._openCursors = newOpenCursors;
this._cursorsToClose.clear();
}
//---------------------------------------------------------------------------
//clearPendingState() {
// Clears state for statment with pending clear flag set and not in use.
// This will clear all state for open cursors.
// Called after rows processing is completed.
//---------------------------------------------------------------------------
clearPendingStatus() {
for (const stmt of this._openCursors) {
if (stmt.pendingClear && !stmt.inUse) {
stmt._clearAllState();
stmt.pendingClear = false;
}
}
}
//---------------------------------------------------------------------------
// get_statement()

@@ -99,10 +116,6 @@ // Get a statement from the statement cache, or prepare a new statement

//---------------------------------------------------------------------------
getStatement(sql, cacheStatement = false) {
getStatement(sql, cacheStatement = false, forceNew = false) {
let stmt = null;
if (sql) {
stmt = this._cachedStatements.get(sql);
if (!cacheStatement) {
this._openCursors.add(stmt);
this._cachedStatements.delete(sql);
}
}

@@ -120,5 +133,12 @@ if (!stmt) {

this._openCursors.add(stmt);
} else if (stmt.inUse || !cacheStatement) {
} else if (forceNew || stmt.inUse) {
if (!cacheStatement) {
this._addCursorToClose(stmt);
this._cachedStatements.delete(sql);
}
stmt = stmt._copy();
this._openCursors.add(stmt);
} else if (!cacheStatement) {
this._cachedStatements.delete(sql);
stmt.returnToCache = false;
} else {

@@ -128,2 +148,3 @@ this._cachedStatements.delete(sql);

}
this._openCursors.add(stmt);
stmt.inUse = true;

@@ -154,5 +175,7 @@ return stmt;

statement.inUse = false;
} else if (statement.cursorId !== 0) {
} else {
this._addCursorToClose(statement);
}
// clear all state for statement which is having flag set and not in use
this.clearPendingStatus();
}

@@ -159,0 +182,0 @@

@@ -1,2 +0,2 @@

// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.

@@ -257,3 +257,3 @@ //-----------------------------------------------------------------------------

checkCredentials,
normalizePrivateKey
normalizePrivateKey,
};

@@ -92,3 +92,3 @@ // Copyright (c) 2023, 2024, Oracle and/or its affiliates.

typeof value === 'boolean' || Buffer.isBuffer(value) ||
util.isDate(value) || nodbUtil.isVectorValue(value))
util.types.isDate(value) || nodbUtil.isVectorValue(value))
return value;

@@ -109,2 +109,8 @@

// JsonId is a special type to represent autogenerated id
// for SODA documents.
if (value instanceof types.JsonId) {
return value;
}
// all other objects are transformed to an object with two arrays (fields

@@ -171,3 +177,3 @@ // and values)

// handle numbers
} else if (typeof value === 'number') {
} else if (typeof value === 'number' || typeof value === 'bigint') {
checkType(info, options,

@@ -189,3 +195,3 @@ types.DB_TYPE_NUMBER,

// handle dates
} else if (util.isDate(value)) {
} else if (util.types.isDate(value)) {
checkType(info, options,

@@ -192,0 +198,0 @@ types.DB_TYPE_TIMESTAMP,

@@ -335,2 +335,9 @@ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.

// It abstracts the autogenerated SODA Document key.
class JsonId extends Uint8Array {
toJSON() {
return (Buffer.from(this.buffer).toString('hex'));
}
}
module.exports = {

@@ -372,3 +379,4 @@ DbType,

getTypeByNum,
getTypeByOraTypeNum
getTypeByOraTypeNum,
JsonId
};

@@ -234,3 +234,3 @@ // Copyright (c) 2016, 2023, Oracle and/or its affiliates.

typeof element === 'number' || Buffer.isBuffer(element) ||
util.isDate(element);
util.types.isDate(element);
if (!ok)

@@ -237,0 +237,0 @@ return false;

@@ -33,5 +33,5 @@ // Copyright (c) 2023, 2024, Oracle and/or its affiliates.

VERSION_MAJOR: 6,
VERSION_MINOR: 4,
VERSION_MINOR: 5,
VERSION_PATCH: 0,
VERSION_SUFFIX: ''
};
{
"name": "oracledb",
"version": "6.4.0",
"version": "6.5.0",
"description": "A Node.js module for Oracle Database access from JavaScript and TypeScript",

@@ -5,0 +5,0 @@ "license": "(Apache-2.0 OR UPL-1.0)",

@@ -1,2 +0,2 @@

# node-oracledb version 6.4.0
# node-oracledb version 6.5.0

@@ -7,3 +7,3 @@ The node-oracledb add-on for Node.js powers high performance Oracle Database

Use node-oracledb 6.4.0 to connect Node.js 14.6, or later, to Oracle
Use node-oracledb 6.5.0 to connect Node.js 14.6, or later, to Oracle
Database. Older versions of node-oracledb may work with older versions of

@@ -10,0 +10,0 @@ Node.js.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc