Skip to content

Commit b4d464e

Browse files
committed
Added a check to limit the bind value size and maxSize
1 parent 989ba64 commit b4d464e

File tree

5 files changed

+41
-21
lines changed

5 files changed

+41
-21
lines changed

doc/api.md

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3714,7 +3714,7 @@ end-of-fetch at the same time.
37143714
The value of `prefetchRows` size is ignored when *not* using a
37153715
`ResultSet`.
37163716
3717-
Prefetching from REF CURSORS requires Oracle Database 11gR2 or
3717+
Prefetching from REF CURSORS requires Oracle Database 11.2 or
37183718
greater.
37193719
37203720
Prefetching can be disabled by setting `prefetchRows` to 0.
@@ -4540,7 +4540,8 @@ statement text is different and would be less efficient.
45404540
45414541
IN binds are values passed into the database. OUT binds are used to
45424542
retrieve data. IN OUT binds are passed in, and may return a different
4543-
value after the statement executes.
4543+
value after the statement executes. IN OUT binds can be used for
4544+
PL/SQL calls, but not for SQL.
45444545
45454546
OUT bind parameters for `RETURNING INTO` clauses will always return an
45464547
array of values. See [DML RETURNING Bind Parameters](#dmlreturn).
@@ -4813,7 +4814,7 @@ CURSOR is set to NULL or is not set in the PL/SQL procedure then the
48134814
returned `ResultSet` is invalid and methods like `getRows()` will
48144815
return an error when invoked.
48154816
4816-
When using Oracle Database 11gR2 or greater, then
4817+
When using Oracle Database 11.2 or greater, then
48174818
[`prefetchRows`](#propdbprefetchrows) can be used to tune the
48184819
performance of fetching REF CURSORS.
48194820
@@ -4968,28 +4969,32 @@ size used for these binds in the OUT direction is 200, so set
49684969
See [Working with CLOB and BLOB Data](#lobhandling) for examples and
49694970
more information on binding and working with LOBs.
49704971
4971-
#### Maximum Limits (Bytes) for Binding LOBs to Strings and Buffers
4972+
#### Theoretical Limits (Bytes) for Binding LOBs to Strings and Buffers
49724973
4973-
DB Type | Bind Type | Direction | Oracle Client 12c Limit<sup>*</sup> | Oracle Client 11g Limit<sup>*</sup>
4974+
DB Type | Bind Type | Direction | Oracle Client 12c Limit<sup>*</sup> | Oracle Client 11.2 Limit<sup>*</sup>
49744975
--------|-----------------|-------------|-------------------------|------------------------
4975-
CLOB | oracledb.STRING |BIND_IN | 2 GB | 64 KB
4976+
CLOB | oracledb.STRING |BIND_IN | 1 GB | 64 KB
49764977
CLOB | oracledb.STRING |BIND_OUT | 1 GB | 64 KB
49774978
CLOB | oracledb.STRING |BIND_INOUT | 32 KB | 32 KB
4978-
BLOB | oracledb.BUFFER |BIND_IN | 2 GB | 64 KB
4979-
BLOB | oracledb.BUFFER |BIND_OUT | 2 GB | 64 KB
4979+
BLOB | oracledb.BUFFER |BIND_IN | 1 GB | 64 KB
4980+
BLOB | oracledb.BUFFER |BIND_OUT | 1 GB | 64 KB
49804981
BLOB | oracledb.BUFFER |BIND_INOUT | 32 KB | 32 KB
49814982
4982-
<sup>*</sup>The largest usable data length is one byte less than the size shown.
4983-
4984-
Internally, node-oracledb uses temporary LOBs when binding Strings and
4985-
Buffers larger than 32 KB. Since temporary LOBs cannot be used for IN
4986-
OUT binds, the data size in this case is restricted to 32 KB.
4983+
<sup>*</sup>The largest usable data length is two bytes less than the
4984+
size shown for 12c and one byte less for 11.2.
49874985
49884986
In practice, the limitation on binding IN or OUT is the memory
4989-
available to Node.js. You will see the error *JavaScript heap out of
4990-
memory* when you try to create large Strings or Buffers. So, for most
4991-
large data sizes, it is recommended to bind as `oracledb.CLOB` or
4992-
`oracledb.BLOB` and use [Lob streaming](#streamsandlobs).
4987+
available to Node.js and the V8 engine. For data larger than several
4988+
megabytes, it is recommended to bind as `oracledb.CLOB` or
4989+
`oracledb.BLOB` and use [Lob streaming](#streamsandlobs). If you try
4990+
to create large Strings or Buffers in Node.js you will see errors like
4991+
*JavaScript heap out of memory*, or other space related messages.
4992+
4993+
Internally, for PL/SQL calls, node-oracledb uses temporary LOBs when
4994+
binding Strings and Buffers larger than 32 KB. Since temporary LOBs
4995+
cannot be used for IN OUT binds, the data size in this case is
4996+
restricted to 32 KB. For SQL call no temporary LOBs are used.
4997+
49934998
49944999
### <a name="plsqlindexbybinds"></a> 13.6 PL/SQL Collection Associative Array (Index-by) Bind Parameters
49955000

src/dpi/include/dpiStmt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ typedef enum
120120
#define DPI_SZ_TYPE sb8
121121
#define DPI_USZ_TYPE ub8
122122
#define DPI_BUFLEN_TYPE ub4
123-
#define DPI_MAX_BUFLEN SB4MAXVAL
123+
#define DPI_MAX_BUFLEN (1024*1024*1024 - 2) // max for binding: 1GB-2
124124
#define DPIBINDBYPOS OCIBindByPos2
125125
#define DPIBINDBYNAME OCIBindByName2
126126
#define DPIDEFINEBYPOS OCIDefineByPos2

src/njs/src/njsConnection.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,17 @@ void Connection::GetBindUnit (Local<Value> val, Bind* bind, bool array,
801801
goto exitGetBindUnit;
802802
}
803803

804+
// for INOUT and OUT bind maxSize is used, and if a large value is
805+
// specified, report error and bail out.
806+
if ( ( dir == NJS_BIND_INOUT || dir == NJS_BIND_OUT ) &&
807+
( bind->maxSize > DPI_MAX_BUFLEN ) )
808+
{
809+
executeBaton->error = NJSMessages::getErrorMsg ( errMaxValueTooLarge,
810+
"maxSize",
811+
DPI_MAX_BUFLEN, 2 );
812+
goto exitGetBindUnit;
813+
}
814+
804815
NJS_GET_UINT_FROM_JSON(bind->maxArraySize, executeBaton->error, bind_unit,
805816
"maxArraySize", 1, exitGetBindUnit);
806817

@@ -1085,7 +1096,8 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
10851096
if ( str.length () > DPI_MAX_BUFLEN )
10861097
{
10871098
executeBaton->error = NJSMessages::getErrorMsg (
1088-
errBindValueTooLarge );
1099+
errBindValueTooLarge,
1100+
DPI_MAX_BUFLEN );
10891101
goto exitGetInBindParamsScalar;
10901102
}
10911103

@@ -1234,7 +1246,8 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
12341246
if ( bufLen > DPI_MAX_BUFLEN )
12351247
{
12361248
executeBaton->error = NJSMessages::getErrorMsg (
1237-
errBindValueTooLarge ) ;
1249+
errBindValueTooLarge,
1250+
DPI_MAX_BUFLEN ) ;
12381251
goto exitGetInBindParamsScalar;
12391252
}
12401253

src/njs/src/njsMessages.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ static const char *errMsg[] =
8787
"NJS-048: operation not permitted while Lob object is active in a bind operation", // errLOBBindActive
8888
"NJS-049: cannot use bind direction IN OUT for temporary LOBs", // errTempLOBINOUTBind
8989
"NJS-050: Temporary LOBs were open when the connection was closed", // errBusyConnTEMPLOB
90-
"NJS-051: given data as bind value is too large", // errBindValueTooLarge
90+
"NJS-051: data must be shorter than %d", // errBindValueTooLarge
91+
"NJS-052: \"%s\" must be less than %d", // errMaxValueTooLarge
9192
};
9293

9394
string NJSMessages::getErrorMsg ( NJSErrorType err, ... )

src/njs/src/njsMessages.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ typedef enum
8787
errTempLOBINOUTBind,
8888
errBusyConnTEMPLOB,
8989
errBindValueTooLarge,
90+
errMaxValueTooLarge,
9091

9192
// New ones should be added here
9293

0 commit comments

Comments
 (0)