[Pkg-javascript-commits] [node-leveldown] 48/492: native layer error on null||undefined key||value

Andrew Kelley andrewrk-guest at moszumanska.debian.org
Sun Jul 6 17:13:43 UTC 2014


This is an automated email from the git hooks/post-receive script.

andrewrk-guest pushed a commit to annotated tag rocksdb-0.10.1
in repository node-leveldown.

commit 5f3685aae6830d7cc7326475745af92188ac3a1f
Author: Rod Vagg <rod at vagg.org>
Date:   Sat Sep 22 14:51:38 2012 +1000

    native layer error on null||undefined key||value
---
 src/async.cc          | 14 ++-------
 src/async.h           |  2 --
 src/database.cc       | 52 ++++++++++++++++++++++++++++---
 src/database_async.cc |  3 +-
 src/iterator_async.cc |  5 +--
 src/levelup.cc        |  9 ++++++
 src/levelup.h         |  2 ++
 test/simple-test.js   | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 150 insertions(+), 21 deletions(-)

diff --git a/src/async.cc b/src/async.cc
index bbb9642..bc3ec91 100644
--- a/src/async.cc
+++ b/src/async.cc
@@ -8,6 +8,7 @@
 
 #include "database.h"
 
+#include "levelup.h"
 #include "async.h"
 #include "batch.h"
 
@@ -18,15 +19,6 @@ using namespace leveldb;
 
 /** ASYNC BASE **/
 
-void runCallback (Persistent<Function> callback, Local<Value> argv[], int length) {
-  TryCatch try_catch;
- 
-  callback->Call(Context::GetCurrent()->Global(), length, argv);
-  if (try_catch.HasCaught()) {
-    FatalException(try_catch);
-  }
-}
-
 void AsyncWorker::WorkComplete () {
   HandleScope scope;
   if (status.ok())
@@ -38,14 +30,14 @@ void AsyncWorker::WorkComplete () {
 
 void AsyncWorker::HandleOKCallback () {
   Local<Value> argv[0];
-  runCallback(callback, argv, 0);  
+  RunCallback(callback, argv, 0);  
 }
 
 void AsyncWorker::HandleErrorCallback () {
   Local<Value> argv[] = {
       Local<Value>::New(Exception::Error(String::New(status.ToString().c_str())))
   };
-  runCallback(callback, argv, 1);
+  RunCallback(callback, argv, 1);
 }
 
 void AsyncExecute (uv_work_t* req) {
diff --git a/src/async.h b/src/async.h
index e660781..64108b5 100644
--- a/src/async.h
+++ b/src/async.h
@@ -11,8 +11,6 @@ using namespace std;
 using namespace v8;
 using namespace leveldb;
 
-void runCallback (Persistent<Function> callback, Local<Value> argv[], int length);
-
 class AsyncWorker {
 public:
   AsyncWorker (
diff --git a/src/database.cc b/src/database.cc
index d123ef1..afde696 100644
--- a/src/database.cc
+++ b/src/database.cc
@@ -141,6 +141,23 @@ Handle<Value> Database::Put (const Arguments& args) {
   HandleScope scope;
 
   Database* database = ObjectWrap::Unwrap<Database>(args.This());
+  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[3]));
+
+  if (args[0]->IsNull() || args[0]->IsUndefined()) {
+    Local<Value> argv[] = {
+      Local<Value>::New(Exception::Error(String::New("Key cannot be `null` or `undefined`")))
+    };
+    RunCallback(callback, argv, 1);
+    return Undefined();
+  }
+
+  if (args[1]->IsNull() || args[1]->IsUndefined()) {
+    Local<Value> argv[] = {
+      Local<Value>::New(Exception::Error(String::New("Value cannot be `null` or `undefined`")))
+    };
+    RunCallback(callback, argv, 1);
+    return Undefined();
+  }
 
   Persistent<Object> keyBuffer = Persistent<Object>::New(args[0]->ToObject());
   Slice key(Buffer::Data(keyBuffer), Buffer::Length(keyBuffer));
@@ -148,7 +165,6 @@ Handle<Value> Database::Put (const Arguments& args) {
   Slice value(Buffer::Data(valueBuffer), Buffer::Length(valueBuffer));
   Local<Object> optionsObj = Local<Object>::Cast(args[2]);
   bool sync = optionsObj->Has(option_sync) && optionsObj->Get(option_sync)->BooleanValue();
-  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[3]));
 
   WriteWorker* worker  = new WriteWorker(
       database
@@ -168,10 +184,20 @@ Handle<Value> Database::Get (const Arguments& args) {
   HandleScope scope;
 
   Database* database = ObjectWrap::Unwrap<Database>(args.This());
+  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
+
+  if (args[0]->IsNull() || args[0]->IsUndefined()) {
+    Local<Value> argv[] = {
+      Local<Value>::New(Exception::Error(String::New("Key cannot be `null` or `undefined`")))
+    };
+    RunCallback(callback, argv, 1);
+    return Undefined();
+  }
+
+
   Persistent<Object> keyBuffer = Persistent<Object>::New(args[0]->ToObject());
   Slice key(Buffer::Data(keyBuffer), Buffer::Length(keyBuffer));
   //Local<Object> optionsObj = Local<Object>::Cast(args[1]);
-  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
 
   ReadWorker* worker = new ReadWorker(
       database
@@ -188,11 +214,20 @@ Handle<Value> Database::Delete (const Arguments& args) {
   HandleScope scope;
 
   Database* database = ObjectWrap::Unwrap<Database>(args.This());
+  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
+
+  if (args[0]->IsNull() || args[0]->IsUndefined()) {
+    Local<Value> argv[] = {
+      Local<Value>::New(Exception::Error(String::New("Key cannot be `null` or `undefined`")))
+    };
+    RunCallback(callback, argv, 1);
+    return Undefined();
+  }
+
   Persistent<Object> keyBuffer = Persistent<Object>::New(args[0]->ToObject());
   Slice key(Buffer::Data(keyBuffer), Buffer::Length(keyBuffer));
   Local<Object> optionsObj = Local<Object>::Cast(args[1]);
   bool sync = optionsObj->Has(option_sync) && optionsObj->Get(option_sync)->BooleanValue();
-  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
 
   DeleteWorker* worker = new DeleteWorker(
       database
@@ -217,20 +252,27 @@ Handle<Value> Database::Batch (const Arguments& args) {
 
   vector<BatchOp*> operations;
   for (unsigned int i = 0; i < array->Length(); i++) {
+    if (!array->Get(i)->IsObject())
+      continue;
+
     Local<Object> obj = Local<Object>::Cast(array->Get(i));
     if (!obj->Has(str_type) || !obj->Has(str_key))
       continue;
 
+    if (!obj->Get(str_key)->IsObject())
+      continue;
     Local<Object> keyBuffer = obj->Get(str_key)->ToObject();
-    if (!keyBuffer->IsObject() || !Buffer::HasInstance(keyBuffer))
+    if (!Buffer::HasInstance(keyBuffer))
       continue;
     Slice key(Buffer::Data(keyBuffer), Buffer::Length(keyBuffer));
 
     if (obj->Get(str_type)->StrictEquals(str_del)) {
       operations.push_back(new BatchDelete(key, Persistent<Object>::New(keyBuffer)));
     } else if (obj->Get(str_type)->StrictEquals(str_put) && obj->Has(str_value)) {
+      if (!obj->Get(str_value)->IsObject())
+        continue;
       Local<Object> valueBuffer = obj->Get(str_value)->ToObject();
-      if (!valueBuffer->IsObject() || !Buffer::HasInstance(valueBuffer))
+      if (!Buffer::HasInstance(valueBuffer))
         continue;
       Slice value(Buffer::Data(valueBuffer), Buffer::Length(valueBuffer));
       operations.push_back(new BatchWrite(key, value, Persistent<Object>::New(keyBuffer), Persistent<Object>::New(valueBuffer)));
diff --git a/src/database_async.cc b/src/database_async.cc
index 7ab232a..c701701 100644
--- a/src/database_async.cc
+++ b/src/database_async.cc
@@ -8,6 +8,7 @@
 
 #include "database.h"
 
+#include "levelup.h"
 #include "async.h"
 #include "database_async.h"
 #include "batch.h"
@@ -72,7 +73,7 @@ void ReadWorker::HandleOKCallback () {
       Local<Value>::New(Null())
     , Local<Value>::New(Buffer::New((char*)value.data(), value.size())->handle_)
   };
-  runCallback(callback, argv, 2);
+  RunCallback(callback, argv, 2);
 }
 
 /** DELETE WORKER **/
diff --git a/src/iterator_async.cc b/src/iterator_async.cc
index 34a645d..0314a6a 100644
--- a/src/iterator_async.cc
+++ b/src/iterator_async.cc
@@ -8,6 +8,7 @@
 
 #include "database.h"
 
+#include "levelup.h"
 #include "async.h"
 #include "iterator_async.h"
 
@@ -29,10 +30,10 @@ void NextWorker::HandleOKCallback () {
       , Local<Value>::New(Buffer::New((char*)key.data(), key.size())->handle_)
       , Local<Value>::New(Buffer::New((char*)value.data(), value.size())->handle_)
     };
-    runCallback(callback, argv, 3);
+    RunCallback(callback, argv, 3);
   } else {
     Local<Value> argv[0];
-    runCallback(endCallback, argv, 0);
+    RunCallback(endCallback, argv, 0);
   }
 }
 
diff --git a/src/levelup.cc b/src/levelup.cc
index e9e27d6..84cbaa9 100644
--- a/src/levelup.cc
+++ b/src/levelup.cc
@@ -28,3 +28,12 @@ const char* ToCString(const v8::String::Utf8Value& value) {
 const char* ToCString(const v8::String::AsciiValue& value) {
   return *value ? *value : "<string conversion failed>";
 }
+
+void RunCallback (Persistent<Function> callback, Local<Value> argv[], int length) {
+  TryCatch try_catch;
+ 
+  callback->Call(Context::GetCurrent()->Global(), length, argv);
+  if (try_catch.HasCaught()) {
+    node::FatalException(try_catch);
+  }
+}
diff --git a/src/levelup.h b/src/levelup.h
index 83e03c1..cdb64de 100644
--- a/src/levelup.h
+++ b/src/levelup.h
@@ -15,4 +15,6 @@
 const char* ToCString(const v8::String::Utf8Value& value);
 const char* ToCString(const v8::String::AsciiValue& value);
 
+void RunCallback (v8::Persistent<v8::Function> callback, v8::Local<v8::Value> argv[], int length);
+
 #endif
diff --git a/test/simple-test.js b/test/simple-test.js
index 4890071..38bd3dc 100644
--- a/test/simple-test.js
+++ b/test/simple-test.js
@@ -445,4 +445,88 @@ buster.testCase('Basic API', {
           })
         }
     }
+
+  , 'null and undefined': {
+        'setUp': function (done) {
+          levelup(this.cleanupDirs[0] = common.nextLocation(), { createIfMissing: true }, function (err, db) {
+            refute(err) // sanity
+            this.closeableDatabases.push(db)
+            assert.isTrue(db.isOpen())
+            this.db = db
+            done()
+          }.bind(this))
+        }
+
+      , 'get() with null key causes error': function (done) {
+          this.db.get(null, function (err, value) {
+            refute(value)
+            assert.isInstanceOf(err, Error)
+            assert.isInstanceOf(err, errors.LevelUPError)
+            done()
+          })
+        }
+
+      , 'get() with undefined key causes error': function (done) {
+          this.db.get(undefined, function (err, value) {
+            refute(value)
+            assert.isInstanceOf(err, Error)
+            assert.isInstanceOf(err, errors.LevelUPError)
+            done()
+          })
+        }
+
+      , 'del() with null key causes error': function (done) {
+          this.db.del(null, function (err, value) {
+            refute(value)
+            assert.isInstanceOf(err, Error)
+            assert.isInstanceOf(err, errors.LevelUPError)
+            done()
+          })
+        }
+
+      , 'del() with undefined key causes error': function (done) {
+          this.db.del(undefined, function (err, value) {
+            refute(value)
+            assert.isInstanceOf(err, Error)
+            assert.isInstanceOf(err, errors.LevelUPError)
+            done()
+          })
+        }
+
+      , 'put() with null key causes error': function (done) {
+          this.db.put(null, 'foo', function (err, value) {
+            refute(value)
+            assert.isInstanceOf(err, Error)
+            assert.isInstanceOf(err, errors.LevelUPError)
+            done()
+          })
+        }
+
+      , 'put() with undefined key causes error': function (done) {
+          this.db.put(undefined, 'foo', function (err, value) {
+            refute(value)
+            assert.isInstanceOf(err, Error)
+            assert.isInstanceOf(err, errors.LevelUPError)
+            done()
+          })
+        }
+
+      , 'put() with null value causes error': function (done) {
+          this.db.put('foo', null, function (err, value) {
+            refute(value)
+            assert.isInstanceOf(err, Error)
+            assert.isInstanceOf(err, errors.LevelUPError)
+            done()
+          })
+        }
+
+      , 'put() with undefined value causes error': function (done) {
+          this.db.put('foo', undefined, function (err, value) {
+            refute(value)
+            assert.isInstanceOf(err, Error)
+            assert.isInstanceOf(err, errors.LevelUPError)
+            done()
+          })
+        }
+    }
 })
\ No newline at end of file

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-leveldown.git



More information about the Pkg-javascript-commits mailing list