@@ -522,12 +522,9 @@ static int ctx_want_write(lua_State *L)
522522 return 1 ;
523523}
524524
525- static void ctx_on_connect (
526- struct mosquitto * mosq ,
527- void * obj ,
528- int rc )
529- {
530- ctx_t * ctx = obj ;
525+ static int ctx_on_connect_safe (lua_State * L ) {
526+ int ref = lua_tointeger (L , 1 );
527+ int rc = lua_tointeger (L , 2 );
531528 bool success = false;
532529 char * str = "reserved for future use" ;
533530
@@ -562,22 +559,37 @@ static void ctx_on_connect(
562559 break ;
563560 }
564561
565- lua_rawgeti (ctx -> L , LUA_REGISTRYINDEX , ctx -> on_connect );
562+ lua_rawgeti (L , LUA_REGISTRYINDEX , ref );
566563
567- lua_pushboolean (ctx -> L , success );
568- lua_pushinteger (ctx -> L , rc );
569- lua_pushstring (ctx -> L , str );
564+ lua_pushboolean (L , success );
565+ lua_pushinteger (L , rc );
566+ lua_pushstring (L , str );
570567
571- lua_call (ctx -> L , 3 , 0 );
572- }
568+ lua_call (L , 3 , 0 );
573569
570+ return 0 ;
571+ }
574572
575- static void ctx_on_disconnect (
573+ static void ctx_on_connect (
576574 struct mosquitto * mosq ,
577575 void * obj ,
578576 int rc )
579577{
580578 ctx_t * ctx = obj ;
579+ lua_State * L = ctx -> L ;
580+ lua_pushcfunction (L , ctx_on_connect_safe );
581+ lua_pushinteger (L , ctx -> on_connect );
582+ lua_pushinteger (L , rc );
583+ if (LUA_OK != lua_pcall (L , 2 , 0 , 0 )) {
584+ /* pop error message */
585+ lua_pop (L , 1 );
586+ }
587+ }
588+
589+
590+ static int ctx_on_disconnect_safe (lua_State * L ) {
591+ int ref = lua_tointeger (L , 1 );
592+ int rc = lua_tointeger (L , 2 );
581593 bool success = true;
582594 char * str = "client-initiated disconnect" ;
583595
@@ -586,13 +598,31 @@ static void ctx_on_disconnect(
586598 str = "unexpected disconnect" ;
587599 }
588600
589- lua_rawgeti (ctx -> L , LUA_REGISTRYINDEX , ctx -> on_disconnect );
601+ lua_rawgeti (L , LUA_REGISTRYINDEX , ref );
590602
591- lua_pushboolean (ctx -> L , success );
592- lua_pushinteger (ctx -> L , rc );
593- lua_pushstring (ctx -> L , str );
603+ lua_pushboolean (L , success );
604+ lua_pushinteger (L , rc );
605+ lua_pushstring (L , str );
594606
595- lua_call (ctx -> L , 3 , 0 );
607+ lua_call (L , 3 , 0 );
608+
609+ return 0 ;
610+ }
611+
612+ static void ctx_on_disconnect (
613+ struct mosquitto * mosq ,
614+ void * obj ,
615+ int rc )
616+ {
617+ ctx_t * ctx = obj ;
618+ lua_State * L = ctx -> L ;
619+ lua_pushcfunction (L , ctx_on_disconnect_safe );
620+ lua_pushinteger (L , ctx -> on_disconnect );
621+ lua_pushinteger (L , rc );
622+ if (LUA_OK != lua_pcall (L , 2 , 0 , 0 )) {
623+ /* pop error message */
624+ lua_pop (L , 1 );
625+ }
596626}
597627
598628static void ctx_on_publish (
@@ -601,10 +631,31 @@ static void ctx_on_publish(
601631 int mid )
602632{
603633 ctx_t * ctx = obj ;
634+ lua_State * L = ctx -> L ;
635+ lua_rawgeti (L , LUA_REGISTRYINDEX , ctx -> on_publish );
636+ lua_pushinteger (L , mid );
637+ if (LUA_OK != lua_pcall (L , 1 , 0 , 0 )) {
638+ /* pop error message */
639+ lua_pop (L , 1 );
640+ }
641+ }
642+
643+ static int ctx_on_message_safe (lua_State * L ) {
644+ int ref = lua_tointeger (L , 1 );
645+ const struct mosquitto_message * msg = lua_touserdata (L , 2 );
646+
647+ /* push registered Lua callback function onto the stack */
648+ lua_rawgeti (L , LUA_REGISTRYINDEX , ref );
649+ /* push function args */
650+ lua_pushinteger (L , msg -> mid );
651+ lua_pushstring (L , msg -> topic );
652+ lua_pushlstring (L , msg -> payload , msg -> payloadlen );
653+ lua_pushinteger (L , msg -> qos );
654+ lua_pushboolean (L , msg -> retain );
655+
656+ lua_call (L , 5 , 0 ); /* args: mid, topic, payload, qos, retain */
604657
605- lua_rawgeti (ctx -> L , LUA_REGISTRYINDEX , ctx -> on_publish );
606- lua_pushinteger (ctx -> L , mid );
607- lua_call (ctx -> L , 1 , 0 );
658+ return 0 ;
608659}
609660
610661static void ctx_on_message (
@@ -613,17 +664,14 @@ static void ctx_on_message(
613664 const struct mosquitto_message * msg )
614665{
615666 ctx_t * ctx = obj ;
616-
617- /* push registered Lua callback function onto the stack */
618- lua_rawgeti (ctx -> L , LUA_REGISTRYINDEX , ctx -> on_message );
619- /* push function args */
620- lua_pushinteger (ctx -> L , msg -> mid );
621- lua_pushstring (ctx -> L , msg -> topic );
622- lua_pushlstring (ctx -> L , msg -> payload , msg -> payloadlen );
623- lua_pushinteger (ctx -> L , msg -> qos );
624- lua_pushboolean (ctx -> L , msg -> retain );
625-
626- lua_call (ctx -> L , 5 , 0 ); /* args: mid, topic, payload, qos, retain */
667+ lua_State * L = ctx -> L ;
668+ lua_pushcfunction (L , ctx_on_message_safe );
669+ lua_pushinteger (L , ctx -> on_message );
670+ lua_pushlightuserdata (L , (void * )msg );
671+ if (LUA_OK != lua_pcall (L , 2 , 0 , 0 )) {
672+ /* pop error message */
673+ lua_pop (L , 1 );
674+ }
627675}
628676
629677static void ctx_on_subscribe (
@@ -634,16 +682,24 @@ static void ctx_on_subscribe(
634682 const int * granted_qos )
635683{
636684 ctx_t * ctx = obj ;
685+ lua_State * L = ctx -> L ;
637686 int i ;
638687
639- lua_rawgeti (ctx -> L , LUA_REGISTRYINDEX , ctx -> on_subscribe );
640- lua_pushinteger (ctx -> L , mid );
688+ if (!lua_checkstack (L , qos_count + 2 )) {
689+ /* can't allocate enough stack space */
690+ return ;
691+ }
641692
693+ lua_rawgeti (L , LUA_REGISTRYINDEX , ctx -> on_subscribe );
694+ lua_pushinteger (L , mid );
642695 for (i = 0 ; i < qos_count ; i ++ ) {
643- lua_pushinteger (ctx -> L , granted_qos [i ]);
696+ lua_pushinteger (L , granted_qos [i ]);
644697 }
645698
646- lua_call (ctx -> L , qos_count + 1 , 0 );
699+ if (LUA_OK != lua_pcall (L , qos_count + 1 , 0 , 0 )) {
700+ /* pop error message */
701+ lua_pop (L , 1 );
702+ }
647703}
648704
649705static void ctx_on_unsubscribe (
@@ -652,10 +708,28 @@ static void ctx_on_unsubscribe(
652708 int mid )
653709{
654710 ctx_t * ctx = obj ;
711+ lua_State * L = ctx -> L ;
712+ lua_rawgeti (L , LUA_REGISTRYINDEX , ctx -> on_unsubscribe );
713+ lua_pushinteger (L , mid );
714+ if (LUA_OK != lua_pcall (L , 1 , 0 , 0 )) {
715+ /* pop error message */
716+ lua_pop (L , 1 );
717+ }
718+ }
719+
720+ static int ctx_on_log_safe (lua_State * L ) {
721+ int ref = lua_tointeger (L , 1 );
722+ int level = lua_tointeger (L , 2 );
723+ const char * str = lua_touserdata (L , 3 );
724+
725+ lua_rawgeti (L , LUA_REGISTRYINDEX , ref );
726+
727+ lua_pushinteger (L , level );
728+ lua_pushstring (L , str );
655729
656- lua_rawgeti ( ctx -> L , LUA_REGISTRYINDEX , ctx -> on_unsubscribe );
657- lua_pushinteger ( ctx -> L , mid );
658- lua_call ( ctx -> L , 1 , 0 ) ;
730+ lua_call ( L , 2 , 0 );
731+
732+ return 0 ;
659733}
660734
661735static void ctx_on_log (
@@ -665,13 +739,15 @@ static void ctx_on_log(
665739 const char * str )
666740{
667741 ctx_t * ctx = obj ;
668-
669- lua_rawgeti (ctx -> L , LUA_REGISTRYINDEX , ctx -> on_log );
670-
671- lua_pushinteger (ctx -> L , level );
672- lua_pushstring (ctx -> L , str );
673-
674- lua_call (ctx -> L , 2 , 0 );
742+ lua_State * L = ctx -> L ;
743+ lua_pushcfunction (L , ctx_on_log_safe );
744+ lua_pushinteger (L , ctx -> on_log );
745+ lua_pushinteger (L , level );
746+ lua_pushlightuserdata (L , (void * )str );
747+ if (LUA_OK != lua_pcall (L , 3 , 0 , 0 )) {
748+ /* pop error message */
749+ lua_pop (L , 1 );
750+ }
675751}
676752
677753static int callback_type_from_string (const char * );
0 commit comments