Please find attached a patch which goes some way to fixing this issue. I've only tested it in my current configuration, so I don't know how this impacts the webserver. I've had to introduce two new functions to free structures that may be returned by the framework. Not sure how necessary they are, as I think mostly it frees up what it gives you.

This library is still significantly broken. If upstream isn't planning a version 2 this either wants fixing comprehensively by debian, documenting with warnings in very large letters, or removing all together. I think it would be a mistake to base a serious application on the current version. Either that or it's actually perfectly safe and I'm just using it 'wrong' :)

Arthur

--
Arthur Taylor, +44 (0) 1223 271512
Reciva Limited,
509 Coldhams Lane,
Cambridge,
CB1 3JS. England Fax: +44 (0) 1223 702991
diff -ur libupnp/upnp/inc/config.h ../libupnp/upnp/inc/config.h
--- libupnp/upnp/inc/config.h   2006-02-01 17:01:06.000000000 +0000
+++ ../libupnp/upnp/inc/config.h        2006-02-16 16:29:52.000000000 +0000
@@ -226,8 +226,8 @@
 #define EXCLUDE_SOAP 0
 #define EXCLUDE_GENA 0
 #define EXCLUDE_DOM  0
-#define EXCLUDE_MINISERVER 0
-#define EXCLUDE_WEB_SERVER 0
+#define EXCLUDE_MINISERVER 1
+#define EXCLUDE_WEB_SERVER 1
 #ifdef USE_JNI
 #define EXCLUDE_JNI 0
 #else
diff -ur libupnp/upnp/inc/upnp.h ../libupnp/upnp/inc/upnp.h
--- libupnp/upnp/inc/upnp.h     2006-02-01 17:01:07.000000000 +0000
+++ ../libupnp/upnp/inc/upnp.h  2006-02-16 17:04:15.000000000 +0000
@@ -669,7 +669,7 @@
   int ErrCode;
 
   /** The control URL for service. */
-  char CtrlUrl[NAME_SIZE];
+  char *pCtrlUrl;
 
   /** The DOM document describing the action. */
   IXML_Document *ActionRequest;
@@ -719,7 +719,7 @@
   int ErrCode;
 
   /** The control URL for the service. */
-  char CtrlUrl[NAME_SIZE];
+  char *pCtrlUrl;
 
   /** The name of the variable. */
   char StateVarName[NAME_SIZE];
@@ -807,7 +807,7 @@
   int ErrCode;              
 
   /** The event URL being subscribed to or removed from. */
-  char PublisherUrl[NAME_SIZE]; 
+  char *pPublisherUrl; 
 
   /** The actual subscription time (for subscriptions only). */
   int TimeOut;              
@@ -997,6 +997,9 @@
 extern "C" {
 #endif // __cplusplus
 
+void UpnpFreeSubscribeEvent(struct Upnp_Event_Subscribe *pEvt, int 
free_pointer);
+void UpnpFreeActionCompleteEvent(struct Upnp_Action_Complete *pEvt, int 
free_pointer);
+
 ///@name Initialization and Registration
 //@{
 /** Initializes the Linux SDK for UPnP Devices. This function must be called
diff -ur libupnp/upnp/src/api/upnpapi.c ../libupnp/upnp/src/api/upnpapi.c
--- libupnp/upnp/src/api/upnpapi.c      2006-02-01 17:01:14.000000000 +0000
+++ ../libupnp/upnp/src/api/upnpapi.c   2006-02-17 12:42:30.000000000 +0000
@@ -68,6 +68,8 @@
 /*
  ****************** */
 
+static void free_param( struct UpnpNonblockParam *Param);
+
 //Mutex to synchronize the subscription handling at the client side
 CLIENTONLY( ithread_mutex_t GlobalClientSubscribeMutex;
      )
@@ -290,8 +292,9 @@
     DEVICEONLY( UpnpDevice_Handle device_handle;
          )
         CLIENTONLY( UpnpClient_Handle client_handle;
-         )
-    struct Handle_Info *temp;
+            )
+         struct Handle_Info *temp;
+         
 
     DBGONLY( ThreadPoolStats stats;
          )
@@ -370,6 +373,41 @@
 
 }  /********************* End of  UpnpFinish  *************************/
 
+void 
+UpnpFreeSubscribeEvent(struct Upnp_Event_Subscribe *pEvt, int free_pointer)
+{
+  if (pEvt == NULL)
+  {
+    return;
+  }
+  if (pEvt->pPublisherUrl != NULL)
+  {
+    free( pEvt->pPublisherUrl );
+  }
+  if (free_pointer)
+  {
+    free( pEvt );
+  }
+}
+
+void 
+UpnpFreeActionCompleteEvent(struct Upnp_Action_Complete *pEvt, int 
free_pointer)
+{
+  if (pEvt == NULL)
+  {
+    return;
+  }
+  if (pEvt->pCtrlUrl != NULL)
+  {
+    free( pEvt->pCtrlUrl );
+  }
+  if (free_pointer)
+  {
+    free( pEvt );
+  }
+}
+
+
 /****************************************************************************
  * Function: UpnpGetServerPort
  *
@@ -1746,7 +1784,8 @@
 
     Param->FunName = SUBSCRIBE;
     Param->Handle = Hnd;
-    strcpy( Param->Url, EvtUrl );
+    Param->pUrl = malloc(sizeof(char) * (strlen(EvtUrl) + 1));
+    strcpy( Param->pUrl, EvtUrl );
     Param->TimeOut = TimeOut;
     Param->Fun = Fun;
     Param->Cookie = ( void * )Cookie_const;
@@ -1951,6 +1990,7 @@
 
     Param->FunName = UNSUBSCRIBE;
     Param->Handle = Hnd;
+    Param->pUrl = NULL;
     strcpy( Param->SubsId, SubsId );
     Param->Fun = Fun;
     Param->Cookie = ( void * )Cookie_const;
@@ -2101,6 +2141,7 @@
     Param->Handle = Hnd;
     strcpy( Param->SubsId, SubsId );
     Param->Fun = Fun;
+    Param->pUrl = NULL;
     Param->Cookie = ( void * )Cookie_const;
     Param->TimeOut = TimeOut;
 
@@ -2691,12 +2732,13 @@
 
     Param->FunName = ACTION;
     Param->Handle = Hnd;
-    strcpy( Param->Url, ActionURL );
+    Param->pUrl = malloc(sizeof(char) * ((strlen(ActionURL) + 1)));
+    strcpy( Param->pUrl, ActionURL );
     strcpy( Param->ServiceType, ServiceType );
 
     rc = ixmlParseBufferEx( tmpStr, &( Param->Act ) );
     if( rc != IXML_SUCCESS ) {
-        free( Param );
+        free_param( Param );
         ixmlFreeDOMString( tmpStr );
         if( rc == IXML_INSUFFICIENT_MEMORY ) {
             return UPNP_E_OUTOF_MEMORY;
@@ -2816,12 +2858,14 @@
 
     Param->FunName = ACTION;
     Param->Handle = Hnd;
-    strcpy( Param->Url, ActionURL );
+    Param->pUrl = malloc(sizeof(char) * ((strlen(ActionURL) + 1)));
+    strcpy( Param->pUrl, ActionURL );
     strcpy( Param->ServiceType, ServiceType );
     retVal = ixmlParseBufferEx( headerStr, &( Param->Header ) );
     if( retVal != IXML_SUCCESS ) {
         ixmlFreeDOMString( tmpStr );
         ixmlFreeDOMString( headerStr );
+        free_param( Param );
         if( retVal == IXML_INSUFFICIENT_MEMORY ) {
             return UPNP_E_OUTOF_MEMORY;
         } else {
@@ -2834,6 +2878,7 @@
         ixmlFreeDOMString( tmpStr );
         ixmlFreeDOMString( headerStr );
         ixmlDocument_free( Param->Header );
+        free_param( Param );
         if( retVal == IXML_INSUFFICIENT_MEMORY ) {
             return UPNP_E_OUTOF_MEMORY;
         } else {
@@ -2924,7 +2969,8 @@
 
     Param->FunName = STATUS;
     Param->Handle = Hnd;
-    strcpy( Param->Url, ActionURL );
+    Param->pUrl = malloc(sizeof(char) * (strlen(ActionURL) + 1));
+    strcpy( Param->pUrl, ActionURL );
     strcpy( Param->VarName, VarName );
     Param->Fun = Fun;
     Param->Cookie = ( void * )Cookie_const;
@@ -3265,8 +3311,24 @@
 //
 //----------------------------------------------------------------------------
 
+static void free_param(struct UpnpNonblockParam *Param)
+{
+  if (Param == NULL)
+  {
+    return;
+  }
+
+  if (Param->pUrl != NULL)
+  {
+    free( Param->pUrl );
+  }
+  free( Param );
+}
+
+
 #ifdef INCLUDE_CLIENT_APIS
 
+
 /**************************************************************************
  * Function: UpnpThreadDistribution 
  *
@@ -3290,12 +3352,14 @@
         CLIENTONLY( case SUBSCRIBE:
 {
 struct Upnp_Event_Subscribe Evt;
-Evt.ErrCode = genaSubscribe( Param->Handle, Param->Url,
+Evt.ErrCode = genaSubscribe( Param->Handle, Param->pUrl,
                             ( int * )&( Param->TimeOut ),
                             ( char * )Evt.Sid );
-strcpy( Evt.PublisherUrl, Param->Url ); Evt.TimeOut = Param->TimeOut;
+Evt.pPublisherUrl = malloc(sizeof(char) * (strlen(Param->pUrl) + 1));
+strcpy( Evt.pPublisherUrl, Param->pUrl ); Evt.TimeOut = Param->TimeOut;
 Param->Fun( UPNP_EVENT_SUBSCRIBE_COMPLETE, &Evt, Param->Cookie );
-free( Param ); break;}
+free_param( Param );
+break;}
         case UNSUBSCRIBE:
                             {
                             struct Upnp_Event_Subscribe Evt;
@@ -3303,11 +3367,13 @@
                             genaUnSubscribe( Param->Handle,
                                              Param->SubsId );
                             strcpy( ( char * )Evt.Sid, Param->SubsId );
-                            strcpy( Evt.PublisherUrl, "" );
+                            Evt.pPublisherUrl = malloc(sizeof(char) * 
(strlen("") + 1));
+                            strcpy( Evt.pPublisherUrl, "" );
                             Evt.TimeOut = 0;
                             Param->Fun( UPNP_EVENT_UNSUBSCRIBE_COMPLETE,
                                         &Evt, Param->Cookie );
-                            free( Param ); break;}
+                            free_param( Param );
+                            break;}
         case RENEW:
                             {
                             struct Upnp_Event_Subscribe Evt;
@@ -3318,7 +3384,7 @@
                             Evt.TimeOut = Param->TimeOut;
                             strcpy( ( char * )Evt.Sid, Param->SubsId );
                             Param->Fun( UPNP_EVENT_RENEWAL_COMPLETE, &Evt,
-                                        Param->Cookie ); free( Param );
+                                        Param->Cookie ); free_param( Param );
                             break;}
              )
 #endif
@@ -3331,19 +3397,21 @@
 #ifdef INCLUDE_CLIENT_APIS
 
                 Evt.ErrCode =
-                    SoapSendAction( Param->Url, Param->ServiceType,
+                    SoapSendAction( Param->pUrl, Param->ServiceType,
                                     Param->Act, &Evt.ActionResult );
 #endif
 
                 Evt.ActionRequest = Param->Act;
-                strcpy( Evt.CtrlUrl, Param->Url );
+                Evt.pCtrlUrl = malloc(sizeof(char) * (strlen(Param->pUrl) + 
1));
+                strcpy( Evt.pCtrlUrl, Param->pUrl );
 
                 Param->Fun( UPNP_CONTROL_ACTION_COMPLETE, &Evt,
                             Param->Cookie );
 
                 ixmlDocument_free( Evt.ActionRequest );
                 ixmlDocument_free( Evt.ActionResult );
-                free( Param );
+                UpnpFreeActionCompleteEvent(&Evt, 0);
+                free_param( Param );
                 break;
             }
         case STATUS:
@@ -3352,18 +3420,19 @@
 
 #ifdef INCLUDE_CLIENT_APIS
 
-                Evt.ErrCode = SoapGetServiceVarStatus( Param->Url,
+                Evt.ErrCode = SoapGetServiceVarStatus( Param->pUrl,
                                                        Param->VarName,
                                                        &( Evt.
                                                           CurrentVal ) );
 #endif
                 strcpy( Evt.StateVarName, Param->VarName );
-                strcpy( Evt.CtrlUrl, Param->Url );
+                Evt.pCtrlUrl = malloc(sizeof(char) * (strlen(Param->pUrl) + 
1));
+                strcpy( Evt.pCtrlUrl, Param->pUrl );
 
                 Param->Fun( UPNP_CONTROL_GET_VAR_COMPLETE, &Evt,
                             Param->Cookie );
                 free( Evt.CurrentVal );
-                free( Param );
+                free_param( Param );
                 break;
             }
 #endif //EXCLUDE_SOAP
@@ -4022,6 +4091,8 @@
         return UPNP_E_FINISH;
     }
 
+#if EXCLUDE_WEB_SERVER == 0
+    
     switch ( enable ) {
         case TRUE:
             if( ( retVal = web_server_init(  ) ) != UPNP_E_SUCCESS ) {
@@ -4042,6 +4113,10 @@
     }
 
     return UPNP_E_SUCCESS;
+#else
+    retVal = UPNP_E_FINISH;
+    return retVal;
+#endif
 }
 
  /**************************************************************************
diff -ur libupnp/upnp/src/gena/gena_ctrlpt.c 
../libupnp/upnp/src/gena/gena_ctrlpt.c
--- libupnp/upnp/src/gena/gena_ctrlpt.c 2006-02-01 17:01:15.000000000 +0000
+++ ../libupnp/upnp/src/gena/gena_ctrlpt.c      2006-02-17 12:24:46.000000000 
+0000
@@ -158,8 +158,8 @@
     //schedule expire event
     strcpy( RenewEventStruct->Sid, sub->sid );
     RenewEventStruct->ErrCode = UPNP_E_SUCCESS;
-    strncpy( RenewEventStruct->PublisherUrl, sub->EventURL,
-             NAME_SIZE - 1 );
+    RenewEventStruct->pPublisherUrl = malloc(sizeof(char) * 
(strlen(sub->EventURL) + 1));
+    strcpy( RenewEventStruct->pPublisherUrl, sub->EventURL );
     RenewEventStruct->TimeOut = TimeOut;
 
     //RenewEvent->EventType=UPNP_EVENT_SUBSCRIPTION_EXPIRE;
@@ -179,7 +179,7 @@
                                                 eventId ) ) ) !=
         UPNP_E_SUCCESS ) {
         free( RenewEvent );
-        free( RenewEventStruct );
+        UpnpFreeSubscribeEvent( RenewEventStruct, 1 );
         return return_code;
     }
 
diff -ur libupnp/upnp/src/genlib/util/upnp_timeout.c 
../libupnp/upnp/src/genlib/util/upnp_timeout.c
--- libupnp/upnp/src/genlib/util/upnp_timeout.c 2006-02-01 17:01:26.000000000 
+0000
+++ ../libupnp/upnp/src/genlib/util/upnp_timeout.c      2006-02-17 
10:11:45.000000000 +0000
@@ -56,7 +56,7 @@
 
     if( event ) {
         if( event->Event )
-            free( event->Event );
+            UpnpFreeSubscribeEvent( event->Event, 1 );
         free( event );
 
     }
diff -ur libupnp/upnp/src/inc/upnpapi.h ../libupnp/upnp/src/inc/upnpapi.h
--- libupnp/upnp/src/inc/upnpapi.h      2006-02-01 17:01:43.000000000 +0000
+++ ../libupnp/upnp/src/inc/upnpapi.h   2006-02-16 16:50:59.000000000 +0000
@@ -136,7 +136,7 @@
     char  DevId[NAME_SIZE];
     char  ServiceType[NAME_SIZE];
     char  ServiceVer[NAME_SIZE];
-    char  Url[NAME_SIZE];
+    char  *pUrl;
     Upnp_SID   SubsId;
     char  *Cookie;
     Upnp_FunPtr Fun;

Reply via email to