Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check that cb is a function, not non-empty #17

Merged
merged 1 commit into from
Aug 5, 2016
Merged

Conversation

sam-github
Copy link
Contributor

This triggers a bug on node 6.x, see haraka/Haraka#1546 and #16, and this seems to work on older nodes as well as 6.

@bnoordhuis, does this look correct to you? I'm somewhat confused by nodejs/nan#104.

@sam-github sam-github added the #wip label Aug 4, 2016
@sam-github
Copy link
Contributor Author

diff --git a/core.cc b/core.cc
index e4904e3..4786530 100644
--- a/core.cc
+++ b/core.cc
@@ -30,7 +30,7 @@ class Worker: public Nan::AsyncWorker {
         void HandleOKCallback() {
             Nan::HandleScope scope;

-            if(callback->GetFunction()->IsFunction())
+            if(callback)
                 callback->Call(0, NULL);
         };

@@ -80,7 +80,10 @@ NAN_METHOD(SysLog) {

     int priority = info[0]->Int32Value();
     char* message = NULL;
-    Nan::Callback *callback = new Nan::Callback(info[2].As<Function>());
+    Nan::Callback *callback = NULL;
+
+    if (info[2]->IsFunction())
+        callback = new Nan::Callback(info[2].As<Function>());

     if(node::Buffer::HasInstance(info[1])) {
         message = dupBuf(info[1]);
@@ -90,7 +93,7 @@ NAN_METHOD(SysLog) {

     if (message) {
         Nan::AsyncQueueWorker(new Worker(callback, priority, message));
-    } else if(callback->GetFunction()->IsFunction()) {
+    } else if(callback) {
         callback->Call(0, NULL);
     }

also seems to work.

@sam-github sam-github self-assigned this Aug 4, 2016
@@ -30,7 +30,7 @@ class Worker: public Nan::AsyncWorker {
void HandleOKCallback() {
Nan::HandleScope scope;

if(!callback->IsEmpty())
if(callback->GetFunction()->IsFunction())
callback->Call(0, NULL);
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just omit HandleOKCallback, callback->Call(0, NULL) is the default implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default implementation doesn't check to see if callback is NULL, so it segfaults if there is no callback

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but that is why you should check the result of IsFunction() before creating the Nan::Callback instance. Blindly casting the function argument is sliding into UB territory.

Copy link
Contributor Author

@sam-github sam-github Aug 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not following. Check my repush. callback argument is mandatory to Worker, and the default implementation of HandleOKCallback just blindly uses it.

When I check IsFunction(), I have no callback, so don't want to cast the non-existent argument to a function, or in any way create a callback, but I have to pass something in as cb argument to the constructor.

@@ -90,10 +93,12 @@ NAN_METHOD(SysLog) {

if (message) {
Nan::AsyncQueueWorker(new Worker(callback, priority, message));
} else if(!callback->IsEmpty()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if info[2]->IsFunction() is false, then there is no callback... but I have to pass something into the worker ctor, and then its default HandleOKCallback() will try to use that something. So, I think I need my own implementation... unless its possible to create a no-op Nan::Callback()? Maybe else callback = new Nan::Callback()? ... but I just tried that, it compiles, but segvs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/to @bnoordhuis ... though I think you get notifications anyhow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see now. LGTM but you can replace the info[2]->IsFunction() check below with a callback != NULL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, that's a relic of my new Nan::Callback() try, sorry.

@sam-github
Copy link
Contributor Author

Thanks for the comments, Ben, and nice to hear from you, even if only at this distance. Maybe I'll see you in Europe some day, hope its going well for you out there in the wilds of northern Holland :-)

@bnoordhuis
Copy link
Member

Thanks, Sam. You should come visit when you're in Europe, life on a farm is great!

@sam-github sam-github merged commit 7459f98 into master Aug 5, 2016
@sam-github sam-github removed the #wip label Aug 5, 2016
@sam-github sam-github deleted the check-for-function branch August 5, 2016 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants