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;