@@ -1185,6 +1185,12 @@ void Connection::GetInBindParamsScalar(Local<Value> v8val, Bind* bind,
1185
1185
/* This has to be allocated after stmt is initialized */
1186
1186
bind->dttmarr = NULL ;
1187
1187
bind->extvalue = (long double *) malloc (sizeof ( long double ) );
1188
+ if ( !bind->extvalue )
1189
+ {
1190
+ executeBaton -> error = NJSMessages::getErrorMsg (
1191
+ errInsufficientMemory );
1192
+ goto exitGetInBindParamsScalar;
1193
+ }
1188
1194
bind->value = NULL ;
1189
1195
bind->type = dpi::DpiTimestampLTZ;
1190
1196
*(bind->len ) = 0 ;
@@ -1478,6 +1484,12 @@ void Connection::GetInBindParamsArray(Local<Array> va8vals, Bind *bind,
1478
1484
bufferSize = static_cast <size_t >(arrayElementSize *
1479
1485
bind->maxArraySize );
1480
1486
buffer = reinterpret_cast <char *>(malloc (bufferSize));
1487
+ if ( !buffer )
1488
+ {
1489
+ executeBaton->error = NJSMessages::getErrorMsg (
1490
+ errInsufficientMemory );
1491
+ goto exitGetInBindParamsArray;
1492
+ }
1481
1493
bind->value = buffer;
1482
1494
break ;
1483
1495
@@ -5373,6 +5385,12 @@ void Connection::cbDynBufferAllocate ( void *ctx, bool dmlReturning,
5373
5385
else
5374
5386
{
5375
5387
bind->value = (void *)malloc ( (size_t )(bind->maxSize ) * nRows ) ;
5388
+ if ( !bind->value )
5389
+ {
5390
+ executeBaton->error = NJSMessages::getErrorMsg (
5391
+ errInsufficientMemory );
5392
+ goto exitcbDynBufferAllocate;
5393
+ }
5376
5394
*(bind->len ) = (unsigned int )bind->maxSize ;
5377
5395
}
5378
5396
break ;
@@ -5514,7 +5532,7 @@ int Connection::cbDynBufferGet ( void *ctx, DPI_SZ_TYPE nRows,
5514
5532
rcodepp (INOUT) - pointer to specify return code (NOT USED)
5515
5533
5516
5534
RETURNS
5517
- -NONE-
5535
+ 0 on success and -1 on memory allocation failures.
5518
5536
5519
5537
NOTE:
5520
5538
The callback is called repeteatedly for the same row with iter (0 based)
@@ -5523,7 +5541,7 @@ int Connection::cbDynBufferGet ( void *ctx, DPI_SZ_TYPE nRows,
5523
5541
is passed to the callback, new set of buffer(s) has to be provided and
5524
5542
initialized.
5525
5543
*/
5526
- void Connection::cbDynDefine ( void *octxp, unsigned long definePos,
5544
+ int Connection::cbDynDefine ( void *octxp, unsigned long definePos,
5527
5545
unsigned long iter, unsigned long *prevIter,
5528
5546
void **bufpp, unsigned long **alenpp,
5529
5547
void **indpp, unsigned short **rcodepp )
@@ -5532,6 +5550,8 @@ void Connection::cbDynDefine ( void *octxp, unsigned long definePos,
5532
5550
Define *define = &(executeBaton->defines [definePos]);
5533
5551
unsigned long maxLen = 0 ;
5534
5552
char **buf = (char **)define->buf ;
5553
+ char *tmp = NULL ; // to presever ptr for realloc
5554
+ int ret = 0 ;
5535
5555
5536
5556
if ( *prevIter != iter )
5537
5557
{
@@ -5545,16 +5565,28 @@ void Connection::cbDynDefine ( void *octxp, unsigned long definePos,
5545
5565
maxLen = ( ( ( unsigned long ) (**alenpp ) ) + NJS_ITER_SIZE );
5546
5566
}
5547
5567
5568
+ tmp = buf[iter]; // preserve the current memory address
5569
+
5548
5570
// allocate or reallocate buffer
5549
5571
buf[iter] = (char *) ( ( !buf[iter] ) ?
5550
5572
malloc ( maxLen ) : realloc ( buf[iter], maxLen ) ) ;
5573
+ if ( !buf[iter] )
5574
+ {
5575
+ // If realloc fails, the IN parameter requires to be freed and untouched
5576
+ // restore the pointer and return error.
5577
+ buf[iter] = tmp ;
5578
+ ret = -1 ;
5579
+ }
5580
+ else
5581
+ {
5582
+ define->len [iter] = maxLen;
5583
+ define->ind [iter] = 0 ; // default value for indicator
5551
5584
5552
- define->len [iter] = maxLen;
5553
- define->ind [iter] = 0 ; // defalt value for indicator
5554
-
5555
- *bufpp = (void *) buf[iter]; // memory for this iter
5556
- *alenpp = (unsigned long *) &(define->len [iter]) ; // size for this iter
5557
- *indpp = (void *) &(define->ind [iter]); // indicator
5585
+ *bufpp = (void *) buf[iter]; // memory for this iter
5586
+ *alenpp = (unsigned long *) &(define->len [iter]) ; // size for this iter
5587
+ *indpp = (void *) &(define->ind [iter]); // indicator
5588
+ }
5589
+ return ret ;
5558
5590
}
5559
5591
5560
5592
0 commit comments