Skip to content

Commit 28bdbbe

Browse files
committed
Fixed a crash while reading a LOB from a closed connection. Also add char set ratio optimization for CLOB
1 parent 8828cf9 commit 28bdbbe

File tree

3 files changed

+113
-23
lines changed

3 files changed

+113
-23
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## node-oracledb v1.2.0 (DD Mon YYYY)
44

5+
- Optimized CLOB memory allocation to account for different database-to-client character set expansions.
6+
7+
- Fixed a crash while reading a LOB from a closed connection
8+
59
- Improved installer messages for Oracle client header and library detection on Linux, OS X and Solaris.
610

711
## node-oracledb v1.1.0 (3 Sep 2015)

src/njs/src/njsIntLob.cpp

Lines changed: 108 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Persistent<FunctionTemplate> ILob::iLobTemplate_s;
8787
*/
8888

8989
ILob::ILob():
90-
lobLocator_(NULL), dpiconn_(NULL), svch_(NULL), errh_(NULL),
90+
lobLocator_(NULL), njsconn_(NULL), dpiconn_(NULL), svch_(NULL), errh_(NULL),
9191
isValid_(false), state_(INACTIVE), buf_(NULL), bufSize_(0), chunkSize_(0),
9292
length_(0), offset_(1), amountRead_(0)
9393
{
@@ -200,30 +200,41 @@ void ILob::setILob(eBaton *executeBaton, ProtoILob *protoILob)
200200
// exceptions.
201201
try
202202
{
203-
lobLocator_ = protoILob->lobLocator_;
203+
// Lob details
204+
lobLocator_ = protoILob->lobLocator_;
204205
protoILob->lobLocator_ = NULL;
205-
206-
fetchType_ = protoILob->fetchType_;
206+
fetchType_ = protoILob->fetchType_;
207207

208-
dpiconn_ = executeBaton->dpiconn;
209-
svch_ = executeBaton->dpiconn->getSvch();
210-
211-
errh_ = protoILob->errh_;
212-
protoILob->errh_ = NULL;
213-
214-
length_ = protoILob->length_;
215-
216-
chunkSize_ = protoILob->chunkSize_;
217-
bufSize_ = chunkSize_;
218-
// we can move the allocation of buf_ to the
219-
// worker thread also by alloating the buf_ in
220-
// ProtoILob.
208+
// connection
209+
njsconn_ = executeBaton->njsconn;
210+
dpiconn_ = executeBaton->dpiconn;
211+
svch_ = executeBaton->dpiconn->getSvch();
212+
213+
// error
214+
errh_ = protoILob->errh_;
215+
protoILob->errh_ = NULL;
216+
217+
// LOB meta data
218+
length_ = protoILob->length_;
219+
chunkSize_ = protoILob->chunkSize_;
220+
bufSize_ = chunkSize_;
221+
222+
/*
223+
* we can move the allocation of buf_ to the worker thread also by
224+
* allocating the buf_ in ProtoILob.
225+
*/
221226
if (fetchType_ == DpiClob)
222-
buf_ = new char[bufSize_ * 4]; // accommodate multi-byte charsets
227+
{
228+
// accommodate multi-byte charsets
229+
buf_ = new char[bufSize_ * dpiconn_->getByteExpansionRatio()];
230+
}
223231
else
232+
{
224233
buf_ = new char[bufSize_];
234+
}
225235

226-
isValid_ = true;
236+
// Now the ILob object is valid
237+
isValid_ = true;
227238
}
228239

229240
catch (dpi::Exception &e)
@@ -337,6 +348,14 @@ NAN_METHOD(ILob::Release)
337348
NanScope();
338349

339350
ILob *iLob = ObjectWrap::Unwrap<ILob>(args.This());
351+
string msg;
352+
353+
if( !iLob->njsconn_->isValid() )
354+
{
355+
msg = NJSMessages::getErrorMsg ( errInvalidConnection );
356+
NJS_SET_EXCEPTION( msg.c_str(), (int) msg.length() );
357+
NanReturnUndefined ();
358+
}
340359

341360
iLob->cleanup();
342361

@@ -368,7 +387,7 @@ void ILob::lobPropertyException(ILob *iLob,
368387
string property)
369388
{
370389
NanScope();
371-
string msg;
390+
string msg;
372391

373392
if (iLob->isValid_)
374393
msg = NJSMessages::getErrorMsg(err, property.c_str());
@@ -400,6 +419,14 @@ NAN_PROPERTY_GETTER(ILob::GetChunkSize)
400419
NanScope();
401420

402421
ILob *iLob = ObjectWrap::Unwrap<ILob>(args.Holder());
422+
string msg;
423+
424+
if( !iLob->njsconn_->isValid() )
425+
{
426+
msg = NJSMessages::getErrorMsg ( errInvalidConnection );
427+
NJS_SET_EXCEPTION( msg.c_str(), (int) msg.length() );
428+
NanReturnUndefined ();
429+
}
403430

404431
try
405432
{
@@ -464,6 +491,14 @@ NAN_PROPERTY_GETTER(ILob::GetLength)
464491
NanScope();
465492

466493
ILob *iLob = ObjectWrap::Unwrap<ILob>(args.Holder());
494+
string msg;
495+
496+
if( !iLob->njsconn_->isValid() )
497+
{
498+
msg = NJSMessages::getErrorMsg ( errInvalidConnection );
499+
NJS_SET_EXCEPTION( msg.c_str(), (int) msg.length() );
500+
NanReturnUndefined ();
501+
}
467502

468503
try
469504
{
@@ -527,6 +562,14 @@ NAN_PROPERTY_GETTER(ILob::GetPieceSize)
527562
NanScope();
528563

529564
ILob *iLob = ObjectWrap::Unwrap<ILob>(args.Holder());
565+
string msg;
566+
567+
if( !iLob->njsconn_->isValid() )
568+
{
569+
msg = NJSMessages::getErrorMsg ( errInvalidConnection );
570+
NJS_SET_EXCEPTION( msg.c_str(), (int) msg.length() );
571+
NanReturnUndefined ();
572+
}
530573

531574
try
532575
{
@@ -565,21 +608,34 @@ NAN_SETTER(ILob::SetPieceSize)
565608
NanScope();
566609

567610
ILob *iLob = ObjectWrap::Unwrap<ILob>(args.Holder());
611+
string msg;
568612

569613
NJS_SET_PROP_UINT(iLob->bufSize_, value, "pieceSize");
570614

571615
if (iLob->state_ == ACTIVE)
572616
{
573-
string msg = NJSMessages::getErrorMsg(errBusyLob);
617+
msg = NJSMessages::getErrorMsg(errBusyLob);
574618

575619
NJS_SET_EXCEPTION(msg.c_str(), (int)msg.length());
620+
return;
621+
}
622+
623+
if( !iLob->njsconn_->isValid() )
624+
{
625+
msg = NJSMessages::getErrorMsg ( errInvalidConnection );
626+
NJS_SET_EXCEPTION( msg.c_str(), (int) msg.length() );
627+
return;
576628
}
577629

578630
if (iLob->buf_)
579631
delete [] iLob->buf_;
580632

581633
if (iLob->fetchType_ == DpiClob)
582-
iLob->buf_ = new char[iLob->bufSize_ * 4];// accommodate multi-byte charsets
634+
{
635+
// accommodate multi-byte charsets
636+
iLob->buf_ = new char[iLob->bufSize_ *
637+
iLob->dpiconn_->getByteExpansionRatio()];
638+
}
583639
else
584640
iLob->buf_ = new char[iLob->bufSize_];
585641
}
@@ -606,6 +662,14 @@ NAN_PROPERTY_GETTER(ILob::GetOffset)
606662
NanScope();
607663

608664
ILob *iLob = ObjectWrap::Unwrap<ILob>(args.Holder());
665+
string msg;
666+
667+
if( !iLob->njsconn_->isValid() )
668+
{
669+
msg = NJSMessages::getErrorMsg ( errInvalidConnection );
670+
NJS_SET_EXCEPTION( msg.c_str(), (int) msg.length() );
671+
NanReturnUndefined ();
672+
}
609673

610674
try
611675
{
@@ -645,6 +709,7 @@ NAN_SETTER(ILob::SetOffset)
645709

646710
ILob *iLob = ObjectWrap::Unwrap<ILob>(args.Holder());
647711
double offset = 0.0;
712+
string msg;
648713

649714
NJS_SET_PROP_UINT(offset, value, "offset");
650715

@@ -657,9 +722,17 @@ NAN_SETTER(ILob::SetOffset)
657722

658723
if (iLob->state_ == ACTIVE)
659724
{
660-
string msg = NJSMessages::getErrorMsg(errBusyLob);
725+
msg = NJSMessages::getErrorMsg(errBusyLob);
661726

662727
NJS_SET_EXCEPTION(msg.c_str(), (int)msg.length());
728+
return;
729+
}
730+
731+
if( !iLob->njsconn_->isValid() )
732+
{
733+
msg = NJSMessages::getErrorMsg ( errInvalidConnection );
734+
NJS_SET_EXCEPTION( msg.c_str(), (int) msg.length() );
735+
return;
663736
}
664737

665738
iLob->offset_ = (unsigned long long) offset;
@@ -709,6 +782,12 @@ NAN_METHOD(ILob::Read)
709782
// case of an error.
710783
iLob->state_ = ACTIVE;
711784

785+
if( !iLob->njsconn_->isValid() )
786+
{
787+
lobBaton->error = NJSMessages::getErrorMsg ( errInvalidConnection );
788+
goto exitRead;
789+
}
790+
712791
exitRead:
713792

714793
lobBaton->req.data = (void*)lobBaton;
@@ -894,6 +973,12 @@ NAN_METHOD(ILob::Write)
894973
// case of an error
895974
iLob->state_ = ACTIVE;
896975

976+
if( !iLob->njsconn_->isValid() )
977+
{
978+
lobBaton->error = NJSMessages::getErrorMsg ( errInvalidConnection );
979+
goto exitWrite;
980+
}
981+
897982
exitWrite:
898983

899984
lobBaton->req.data = (void*)lobBaton;

src/njs/src/njsIntLob.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class ILob : public ObjectWrap
198198
Descriptor *lobLocator_;
199199
unsigned short fetchType_;
200200

201+
Connection *njsconn_;
201202
dpi::Conn *dpiconn_;
202203
DpiHandle *svch_;
203204
DpiHandle *errh_;

0 commit comments

Comments
 (0)