Skip to content

Commit 35594e7

Browse files
committed
Validate objects used in bind-by-position array and display NJS-044
1 parent 11d9598 commit 35594e7

File tree

5 files changed

+57
-13
lines changed

5 files changed

+57
-13
lines changed

src/njs/src/njsConnection.cpp

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ void Connection::GetBinds (Handle<Object> bindobj, eBaton* executeBaton)
662662
bind->key = ":"+std::string(str);
663663
Local<Value> val__ = bindobj->Get(Nan::New<v8::String>((char*)str.c_str(),
664664
(int) str.length()).ToLocalChecked());
665-
Connection::GetBindUnit(val__, bind, executeBaton);
665+
Connection::GetBindUnit(val__, bind, false, executeBaton);
666666
if(!executeBaton->error.empty())
667667
goto exitGetBinds;
668668
}
@@ -689,7 +689,7 @@ void Connection::GetBinds (Handle<Array> binds, eBaton* executeBaton)
689689
{
690690
Bind* bind = new Bind;
691691
Local<Value> val__ = binds->Get(index);
692-
GetBindUnit(val__, bind, executeBaton);
692+
GetBindUnit(val__, bind, true, executeBaton);
693693
if(!executeBaton->error.empty()) goto exitGetBinds;
694694
}
695695
exitGetBinds:
@@ -702,9 +702,12 @@ void Connection::GetBinds (Handle<Array> binds, eBaton* executeBaton)
702702
Processing each bind varible
703703
704704
PARAMETERS:
705-
Handle value, eBaton struct
705+
val - handle value
706+
bind - one bind structure to initialize
707+
array - array input or JSON input
708+
executeBaton - eBaton structure
706709
*/
707-
void Connection::GetBindUnit (Local<Value> val, Bind* bind,
710+
void Connection::GetBindUnit (Local<Value> val, Bind* bind, bool array,
708711
eBaton* executeBaton)
709712
{
710713
Nan::HandleScope scope;
@@ -713,6 +716,46 @@ void Connection::GetBindUnit (Local<Value> val, Bind* bind,
713716
if(val->IsObject() && !val->IsDate() && !Buffer::HasInstance(val))
714717
{
715718
Local<Object> bind_unit = val->ToObject();
719+
720+
if ( array )
721+
{
722+
// In case of array binds, JSON objects are expected to be unnamed.
723+
// Named json object gets confused as we look for "dir", "type",
724+
// "maxSize" key words, but "name" will not match.
725+
// Array binds syntax
726+
// [ id, name, {type : oracledb.STRING, dir : oracledb.BIND_OUT}]
727+
// the 3rd parameter is unnamed JSON object.
728+
// [ id, n, { a: { type : oracledb.STRING, dir : oracledb.BIND_OUT} }]
729+
// will fail now.
730+
Local<Array> keys = bind_unit->GetOwnPropertyNames ();
731+
if ( keys->Length () > 0 )
732+
{
733+
bool valid = false;
734+
735+
for ( unsigned int index = 0; !valid && ( index < keys->Length ()) ;
736+
index ++ )
737+
{
738+
std::string key;
739+
740+
Local<String> temp = keys->Get (index).As<String> ();
741+
NJSString ( key, temp );
742+
743+
if ( ( key.compare ( "dir" ) == 0 ) ||
744+
( key.compare ( "type" ) == 0 ) ||
745+
( key.compare ( "maxSize" ) == 0 ) )
746+
{
747+
valid = true;
748+
}
749+
}
750+
751+
if ( !valid )
752+
{
753+
executeBaton->error = NJSMessages::getErrorMsg ( errNamedJSON );
754+
goto exitGetBindUnit;
755+
}
756+
}
757+
}
758+
716759
NJS_GET_UINT_FROM_JSON ( dir, executeBaton->error,
717760
bind_unit, "dir", 1, exitGetBindUnit );
718761
NJS_GET_UINT_FROM_JSON ( bind->type, executeBaton->error,

src/njs/src/njsConnection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ class Connection: public Nan::ObjectWrap
357357
static void GetOptions (Handle<Object> options, eBaton* executeBaton);
358358
static void GetBinds (Handle<Object> bindobj, eBaton* executeBaton);
359359
static void GetBinds (Handle<Array> bindarray, eBaton* executeBaton);
360-
static void GetBindUnit (Local<Value> bindtypes, Bind* bind,
360+
static void GetBindUnit (Local<Value> bindtypes, Bind* bind, bool array,
361361
eBaton* executeBaton);
362362
static void GetInBindParams(Local<Value> v8val, Bind *bind, eBaton *executeBaton, BindType bindType);
363363
static void GetInBindParamsScalar(Local<Value> v8val, Bind *bind, eBaton *executeBaton, BindType bindType);

src/njs/src/njsMessages.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,12 @@ static const char *errMsg[] =
7777
"NJS-038: maxArraySize value should be greater than 0", // errInvalidValueArrayBind
7878
"NJS-039: empty array is not allowed for IN bind", // errEmptyArray
7979
"NJS-040: connection request timeout", // errConnRequestTimeout
80+
8081
"NJS-041: cannot convert ResultSet to QueryStream after invoking methods", // errCannotConvertRsToStream
8182
"NJS-042: cannot invoke ResultSet methods after converting to QueryStream", // errCannotInvokeRsMethods
8283
"NJS-043: ResultSet already converted to QueryStream", // errResultSetAlreadyConverted
84+
"NJS-044: named JSON object is not expected in this context", // errNamedJSON
85+
8386
};
8487

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

src/njs/src/njsMessages.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ typedef enum
7979
errCannotConvertRsToStream,
8080
errCannotInvokeRsMethods,
8181
errResultSetAlreadyConverted,
82+
errNamedJSON,
8283

8384
// New ones should be added here
8485

test/binding.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -400,25 +400,22 @@ describe('4. binding.js', function() {
400400
);
401401
})
402402

403-
it.skip('4.2.2 array binding with mixing JSON should throw an error', function(done) {
403+
it('4.2.2 array binding with mixing JSON should throw an error', function(done) {
404404
connection.execute(
405405
insert,
406406
param2,
407407
options,
408408
function(err, result) {
409-
should.exist(err); // pending to fix
410-
result.rowsAffected.should.be.exactly(1);
411-
//result.outBinds[0].should.eql([1]);
412-
//console.log(result);
409+
should.exist(err);
410+
(err.message).should.startWith('NJS-044');
411+
// NJS-044: named JSON object is not expected in this context
413412
connection.execute(
414413
"SELECT * FROM nodb_binding",
415414
[],
416415
options,
417416
function(err, result) {
418417
should.not.exist(err);
419-
//console.log(result);
420-
result.rows[0].ID.should.be.exactly(2);
421-
result.rows[0].NAME.should.eql('changjie');
418+
(result.rows).should.be.eql([]);
422419
done();
423420
}
424421
);

0 commit comments

Comments
 (0)