From d19c0757dc341b278513314d62dcdae95b7d0e21 Mon Sep 17 00:00:00 2001 From: Fabrice Fontaine Date: Fri, 9 Mar 2012 10:38:34 +0100 Subject: [PATCH] SF Bug Tracker id 3499781 - msvc doesn't have snprintf Submitted: Yoichi NAKAYAMA ( yoichi ) - 2012-03-08 10:18:39 PST 97a17ff5add73c97844e2fa74456bab4df0800f1 commit breaks build on windows/msvc since there is no snprintf. Note: * Some existing sources use _snprintf when WIN32 is defined, but its behavior is a bit different from C99 snprintf. * snprintf does terminate the buffer, so the commit (use buffer size minus 1 as argument) changes the behavior at the boundary. * Truncation might be better than crash in some cases. But it may result in not good. (forward port of commit e722d8c375dc50b855b41cd56e2fc3d70af4201e) --- ChangeLog | 17 ++++ upnp/src/api/upnptools.c | 19 +++- upnp/src/gena/gena_ctrlpt.c | 17 +++- upnp/src/gena/gena_device.c | 28 +++-- upnp/src/genlib/net/http/httpreadwrite.c | 34 ++++--- upnp/src/genlib/net/http/webserver.c | 40 ++++++-- upnp/src/genlib/net/uri/uri.c | 6 +- upnp/src/soap/soap_device.c | 2 +- upnp/src/ssdp/ssdp_ctrlpt.c | 23 ++--- upnp/src/ssdp/ssdp_device.c | 124 +++++++++++++++-------- upnp/src/ssdp/ssdp_server.c | 12 ++- upnp/src/urlconfig/urlconfig.c | 2 + 12 files changed, 231 insertions(+), 93 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7fbdfee..5212ca9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -318,6 +318,23 @@ Version 1.8.0 Version 1.6.16 ******************************************************************************* +2012-03-08 Fabrice Fontaine + + SF Bug Tracker id 3499781 - msvc doesn't have snprintf + + Submitted: Yoichi NAKAYAMA ( yoichi ) - 2012-03-08 10:18:39 PST + + 97a17ff5add73c97844e2fa74456bab4df0800f1 commit breaks build on + windows/msvc since there is no snprintf. + + Note: + * Some existing sources use _snprintf when WIN32 is defined, but its + behavior is a bit different from C99 snprintf. + * snprintf does terminate the buffer, so the commit (use buffer size + minus 1 as argument) changes the behavior at the boundary. + * Truncation might be better than crash in some cases. But it may + result in not good. + 2012-03-08 Marcelo Roberto Jimenez SF Bug Tracker id 3499878 - UpnpUnSubscribeAsync(): ‘retVal’ may be used uninitialized diff --git a/upnp/src/api/upnptools.c b/upnp/src/api/upnptools.c index 8029794..326dd9b 100644 --- a/upnp/src/api/upnptools.c +++ b/upnp/src/api/upnptools.c @@ -56,6 +56,9 @@ /*! Maximum action header buffer length. */ #define HEADER_LENGTH 2000 +#ifdef WIN32 + #define snprintf _snprintf +#endif /*! * \brief Structure to maintain a error code and string associated with the @@ -222,14 +225,18 @@ static int addToAction( memset(ActBuff, 0, HEADER_LENGTH); if (response) { - snprintf(ActBuff, HEADER_LENGTH - 1, + rc = snprintf(ActBuff, HEADER_LENGTH, "\r\n", ActionName, ServType, ActionName); } else { - snprintf(ActBuff, HEADER_LENGTH - 1, + rc = snprintf(ActBuff, HEADER_LENGTH, "\r\n", ActionName, ServType, ActionName); } + if (rc < 0 || (unsigned int) rc >= HEADER_LENGTH) { + free(ActBuff); + return UPNP_E_OUTOF_MEMORY; + } rc = ixmlParseBufferEx(ActBuff, ActionDoc); free(ActBuff); @@ -284,6 +291,7 @@ static IXML_Document *makeAction( IXML_Node *node; IXML_Element *Ele; IXML_Node *Txt = NULL; + int rc = 0; if (ActionName == NULL || ServType == NULL) { return NULL; @@ -296,15 +304,16 @@ static IXML_Document *makeAction( memset(ActBuff, 0, HEADER_LENGTH); if (response) { - snprintf(ActBuff, HEADER_LENGTH - 1, + rc = snprintf(ActBuff, HEADER_LENGTH, "\r\n", ActionName, ServType, ActionName); } else { - snprintf(ActBuff, HEADER_LENGTH - 1, + rc = snprintf(ActBuff, HEADER_LENGTH, "\r\n", ActionName, ServType, ActionName); } - if (ixmlParseBufferEx(ActBuff, &ActionDoc) != IXML_SUCCESS) { + if (rc < 0 || (unsigned int) rc >= HEADER_LENGTH || + ixmlParseBufferEx(ActBuff, &ActionDoc) != IXML_SUCCESS) { free(ActBuff); return NULL; } diff --git a/upnp/src/gena/gena_ctrlpt.c b/upnp/src/gena/gena_ctrlpt.c index 9e53a99..9b41702 100644 --- a/upnp/src/gena/gena_ctrlpt.c +++ b/upnp/src/gena/gena_ctrlpt.c @@ -53,6 +53,9 @@ #include "uuid.h" #include "upnpapi.h" +#ifdef WIN32 + #define snprintf _snprintf +#endif extern ithread_mutex_t GlobalClientSubscribeMutex; @@ -283,6 +286,7 @@ static int gena_subscribe( membuffer request; uri_type dest_url; http_parser_t response; + int rc = 0; memset(timeout_str, 0, sizeof(timeout_str)); UpnpString_clear(sid); @@ -294,11 +298,13 @@ static int gena_subscribe( if (*timeout < 0) { strncpy(timeout_str, "infinite", sizeof(timeout_str) - 1); } else if(*timeout < CP_MINIMUM_SUBSCRIPTION_TIME) { - snprintf(timeout_str, sizeof(timeout_str) - 1, + rc = snprintf(timeout_str, sizeof(timeout_str), "%d", CP_MINIMUM_SUBSCRIPTION_TIME); } else { - snprintf(timeout_str, sizeof(timeout_str) - 1, "%d", *timeout); + rc = snprintf(timeout_str, sizeof(timeout_str), "%d", *timeout); } + if (rc < 0 || (unsigned int) rc >= sizeof(timeout_str)) + return UPNP_E_OUTOF_MEMORY; /* parse url */ return_code = http_FixStrUrl( @@ -514,6 +520,7 @@ int genaSubscribe( UpnpString *ActualSID = UpnpString_new(); UpnpString *EventURL = UpnpString_new(); struct Handle_Info *handle_info; + int rc = 0; memset(temp_sid, 0, sizeof(temp_sid)); memset(temp_sid2, 0, sizeof(temp_sid2)); @@ -550,7 +557,11 @@ int genaSubscribe( /* generate client SID */ uuid_create(&uid ); uuid_unpack(&uid, temp_sid); - snprintf(temp_sid2, sizeof(temp_sid2) - 1, "uuid:%s", temp_sid); + rc = snprintf(temp_sid2, sizeof(temp_sid2), "uuid:%s", temp_sid); + if (rc < 0 || (unsigned int) rc >= sizeof(temp_sid2)) { + return_code = UPNP_E_OUTOF_MEMORY; + goto error_handler; + } UpnpString_set_String(out_sid, temp_sid2); /* create event url */ diff --git a/upnp/src/gena/gena_device.c b/upnp/src/gena/gena_device.c index 4f77b16..8bc554e 100644 --- a/upnp/src/gena/gena_device.c +++ b/upnp/src/gena/gena_device.c @@ -50,6 +50,10 @@ #include "upnpapi.h" #include "uuid.h" +#ifdef WIN32 + #define snprintf _snprintf +#endif + /*! * \brief Unregisters a device. * @@ -413,6 +417,7 @@ static char *AllocGenaHeaders( char *headers = NULL; size_t headers_size = 0; int line = 0; + int rc = 0; headers_size = strlen(HEADER_LINE_1 ) + @@ -425,7 +430,8 @@ static char *AllocGenaHeaders( line = __LINE__; goto ExitFunction; } - sprintf(headers, "%s%s%"PRIzu"%s%s%s", + memset(headers, 0, headers_size); + rc = snprintf(headers, headers_size, "%s%s%"PRIzu"%s%s%s", HEADER_LINE_1, HEADER_LINE_2A, strlen(propertySet) + 1, @@ -434,7 +440,7 @@ static char *AllocGenaHeaders( HEADER_LINE_4); ExitFunction: - if (headers == NULL) { + if (headers == NULL || rc < 0 || (unsigned int) rc >= headers_size) { UpnpPrintf(UPNP_ALL, GENA, __FILE__, line, "AllocGenaHeaders(): Error UPNP_E_OUTOF_MEMORY\n"); } @@ -1074,17 +1080,22 @@ static int respond_ok( int return_code; char timeout_str[100]; int upnp_timeout = UPNP_TIMEOUT; + int rc = 0; memset( timeout_str, 0, sizeof( timeout_str ) ); http_CalcResponseVersion( request->major_version, request->minor_version, &major, &minor ); if( time_out >= 0 ) { - snprintf( timeout_str, sizeof ( timeout_str ) - 1, - "TIMEOUT: Second-%d", time_out ); + rc = snprintf( timeout_str, sizeof ( timeout_str ), + "TIMEOUT: Second-%d", time_out ); } else { strncpy( timeout_str, "TIMEOUT: Second-infinite", - sizeof ( timeout_str ) - 1 ); + sizeof ( timeout_str ) - 1); + } + if (rc < 0 || (unsigned int) rc >= sizeof ( timeout_str ) ) { + error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request ); + return UPNP_E_OUTOF_MEMORY; } membuffer_init( &response ); @@ -1216,6 +1227,7 @@ void gena_process_subscription_request( char *event_url_path = NULL; memptr callback_hdr; memptr timeout_hdr; + int rc = 0; UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "Subscription Request Received:\n"); @@ -1347,10 +1359,12 @@ void gena_process_subscription_request( uuid_create(&uid); uuid_unpack(&uid, temp_sid); memset(sub->sid, 0, sizeof(sub->sid)); - snprintf(sub->sid, sizeof(sub->sid) - 1, "uuid:%s", temp_sid); + rc = snprintf(sub->sid, sizeof(sub->sid), "uuid:%s", temp_sid); /* respond OK */ - if (respond_ok(info, time_out, sub, request) != UPNP_E_SUCCESS) { + if (rc < 0 || (unsigned int) rc >= sizeof(sub->sid) || + (respond_ok(info, time_out, + sub, request) != UPNP_E_SUCCESS)) { freeSubscriptionList(sub); HandleUnlock(); goto exit_function; diff --git a/upnp/src/genlib/net/http/httpreadwrite.c b/upnp/src/genlib/net/http/httpreadwrite.c index 2a4ed20..a58819b 100644 --- a/upnp/src/genlib/net/http/httpreadwrite.c +++ b/upnp/src/genlib/net/http/httpreadwrite.c @@ -59,6 +59,7 @@ #ifdef WIN32 #include #define fseeko fseek + #define snprintf _snprintf #else #include #include @@ -511,7 +512,7 @@ int http_SendMessage(SOCKINFO *info, int *TimeOut, const char *fmt, ...) memset(Chunk_Header, 0, sizeof(Chunk_Header)); snprintf(Chunk_Header, - sizeof(Chunk_Header) - strlen ("\r\n") - 1, + sizeof(Chunk_Header) - strlen ("\r\n"), "%" PRIzx, num_read); /*itoa(num_read,Chunk_Header,16); */ strncat(Chunk_Header, "\r\n", strlen ("\r\n")); @@ -1439,6 +1440,7 @@ int http_MakeMessage(membuffer *buf, int http_major_version, const char *weekday_str = "Sun\0Mon\0Tue\0Wed\0Thu\0Fri\0Sat"; const char *month_str = "Jan\0Feb\0Mar\0Apr\0May\0Jun\0" "Jul\0Aug\0Sep\0Oct\0Nov\0Dec"; + int rc = 0; memset(tempbuf, 0, sizeof(tempbuf)); va_start(argp, fmt); @@ -1482,15 +1484,17 @@ int http_MakeMessage(membuffer *buf, int http_major_version, } else if (c == 'd') { /* integer */ num = (size_t)va_arg(argp, int); - snprintf(tempbuf, sizeof(tempbuf) - 1, "%" PRIzu, num); - if (membuffer_append(buf, tempbuf, strlen(tempbuf))) + rc = snprintf(tempbuf, sizeof(tempbuf), "%" PRIzu, num); + if (rc < 0 || (unsigned int) rc >= sizeof(tempbuf) || + membuffer_append(buf, tempbuf, strlen(tempbuf))) goto error_handler; } else if (c == 'h') { /* off_t */ bignum = (off_t) va_arg(argp, off_t); - snprintf(tempbuf, sizeof(tempbuf) - 1, "%" PRId64, + rc = snprintf(tempbuf, sizeof(tempbuf), "%" PRId64, (int64_t) bignum); - if (membuffer_append(buf, tempbuf, strlen(tempbuf))) + if (rc < 0 || (unsigned int) rc >= sizeof(tempbuf) || + membuffer_append(buf, tempbuf, strlen(tempbuf))) goto error_handler; } else if (c == 't' || c == 'D') { /* date */ @@ -1507,13 +1511,14 @@ int http_MakeMessage(membuffer *buf, int http_major_version, } assert(loc_time); date = gmtime(loc_time); - snprintf(tempbuf, sizeof(tempbuf) - 1, + rc = snprintf(tempbuf, sizeof(tempbuf), "%s%s, %02d %s %d %02d:%02d:%02d GMT%s", start_str, &weekday_str[date->tm_wday * 4], date->tm_mday, &month_str[date->tm_mon * 4], date->tm_year + 1900, date->tm_hour, date->tm_min, date->tm_sec, end_str); - if (membuffer_append(buf, tempbuf, strlen(tempbuf))) + if (rc < 0 || (unsigned int) rc >= sizeof(tempbuf) || + membuffer_append(buf, tempbuf, strlen(tempbuf))) goto error_handler; } else if (c == 'L') { /* Add CONTENT-LANGUAGE header only if WEB_SERVER_CONTENT_LANGUAGE */ @@ -1564,21 +1569,24 @@ int http_MakeMessage(membuffer *buf, int http_major_version, /* e.g.: 'HTTP/1.1 200 OK' code */ status_code = (int)va_arg(argp, int); assert(status_code > 0); - snprintf(tempbuf, sizeof(tempbuf) - 1, "HTTP/%d.%d %d ", + rc = snprintf(tempbuf, sizeof(tempbuf), "HTTP/%d.%d %d ", http_major_version, http_minor_version, status_code); /* str */ status_msg = http_get_code_text(status_code); - if (http_MakeMessage(buf, http_major_version, http_minor_version, + if (rc < 0 || (unsigned int) rc >= sizeof(tempbuf) || + http_MakeMessage(buf, http_major_version, http_minor_version, "ssc", tempbuf, status_msg) != 0) goto error_handler; } else if (c == 'B') { /* body of a simple reply */ status_code = (int)va_arg(argp, int); - snprintf(tempbuf, sizeof(tempbuf) - 1, "%s%d %s%s", + rc = snprintf(tempbuf, sizeof(tempbuf), "%s%d %s%s", "

", status_code, http_get_code_text(status_code), "

"); + if (rc < 0 || (unsigned int) rc >= sizeof(tempbuf)) + goto error_handler; bignum = (off_t)strlen(tempbuf); if (http_MakeMessage(buf, http_major_version, http_minor_version, "NTcs", bignum, /* content-length */ @@ -1795,6 +1803,7 @@ int http_OpenHttpGetEx( int errCode = UPNP_E_SUCCESS; /* char rangeBuf[SIZE_RANGE_BUFFER]; */ struct SendInstruction rangeBuf; + int rc = 0; membuffer_init(&request); @@ -1814,9 +1823,10 @@ int http_OpenHttpGetEx( break; } memset(&rangeBuf, 0, sizeof(rangeBuf)); - snprintf(rangeBuf.RangeHeader, - sizeof(rangeBuf.RangeHeader) - 1, + rc = snprintf(rangeBuf.RangeHeader, sizeof(rangeBuf.RangeHeader), "Range: bytes=%d-%d\r\n", lowRange, highRange); + if (rc < 0 || (unsigned int) rc >= sizeof(rangeBuf.RangeHeader)) + break; membuffer_init(&request); errCode = MakeGetMessageEx(url_str, &request, &url, &rangeBuf); if (errCode != UPNP_E_SUCCESS) diff --git a/upnp/src/genlib/net/http/webserver.c b/upnp/src/genlib/net/http/webserver.c index e096c90..171c8c0 100644 --- a/upnp/src/genlib/net/http/webserver.c +++ b/upnp/src/genlib/net/http/webserver.c @@ -62,6 +62,10 @@ #include #include +#ifdef WIN32 + #define snprintf _snprintf +#endif + /*! * Response Types. */ @@ -302,6 +306,7 @@ static UPNP_INLINE int get_content_type( int ctype_found = FALSE; char *temp = NULL; size_t length = 0; + int rc = 0; UpnpFileInfo_set_ContentType(fileInfo, NULL); /* get ext */ @@ -319,7 +324,11 @@ static UPNP_INLINE int get_content_type( if (!temp) return UPNP_E_OUTOF_MEMORY; memset(temp, 0, length); - sprintf(temp, "%s/%s", type, subtype); + rc = snprintf(temp, length, "%s/%s", type, subtype); + if (rc < 0 || (unsigned int) rc >= length) { + free(temp); + return UPNP_E_OUTOF_MEMORY; + } UpnpFileInfo_set_ContentType(fileInfo, temp); free(temp); if (!UpnpFileInfo_get_ContentType(fileInfo)) @@ -766,6 +775,7 @@ static int CreateHTTPRangeResponseHeader( off_t FirstByte, LastByte; char *RangeInput; char *Ptr; + int rc = 0; Instr->IsRangeActive = 1; Instr->ReadSendSize = FileLength; @@ -801,32 +811,40 @@ static int CreateHTTPRangeResponseHeader( Instr->RangeOffset = FirstByte; Instr->ReadSendSize = LastByte - FirstByte + 1; /* Data between two range. */ - snprintf(Instr->RangeHeader, - sizeof(Instr->RangeHeader) - 1, + rc = snprintf(Instr->RangeHeader, + sizeof(Instr->RangeHeader), "CONTENT-RANGE: bytes %" PRId64 "-%" PRId64 "/%" PRId64 "\r\n", (int64_t)FirstByte, (int64_t)LastByte, (int64_t)FileLength); + if (rc < 0 || (unsigned int) rc >= sizeof(Instr->RangeHeader)) { + free(RangeInput); + return UPNP_E_OUTOF_MEMORY; + } } else if (FirstByte >= 0 && LastByte == -1 && FirstByte < FileLength) { Instr->RangeOffset = FirstByte; Instr->ReadSendSize = FileLength - FirstByte; memset(Instr->RangeHeader, 0, sizeof(Instr->RangeHeader)); - snprintf(Instr->RangeHeader, - sizeof(Instr->RangeHeader) - 1, + rc = snprintf(Instr->RangeHeader, + sizeof(Instr->RangeHeader), "CONTENT-RANGE: bytes %" PRId64 "-%" PRId64 "/%" PRId64 "\r\n", (int64_t)FirstByte, (int64_t)(FileLength - 1), (int64_t)FileLength); + if (rc < 0 || (unsigned int) rc >= sizeof(Instr->RangeHeader)) { + free(RangeInput); + return UPNP_E_OUTOF_MEMORY; + } } else if (FirstByte == -1 && LastByte > 0) { if (LastByte >= FileLength) { Instr->RangeOffset = 0; Instr->ReadSendSize = FileLength; - snprintf(Instr->RangeHeader, - sizeof(Instr->RangeHeader) - 1, + rc = snprintf(Instr->RangeHeader, + sizeof(Instr->RangeHeader), "CONTENT-RANGE: bytes 0-%" PRId64 "/%" PRId64 "\r\n", (int64_t)(FileLength - 1), @@ -834,14 +852,18 @@ static int CreateHTTPRangeResponseHeader( } else { Instr->RangeOffset = FileLength - LastByte; Instr->ReadSendSize = LastByte; - snprintf(Instr->RangeHeader, - sizeof(Instr->RangeHeader) - 1, + rc = snprintf(Instr->RangeHeader, + sizeof(Instr->RangeHeader), "CONTENT-RANGE: bytes %" PRId64 "-%" PRId64 "/%" PRId64 "\r\n", (int64_t)(FileLength - LastByte + 1), (int64_t)FileLength, (int64_t)FileLength); } + if (rc < 0 || (unsigned int) rc >= sizeof(Instr->RangeHeader)) { + free(RangeInput); + return UPNP_E_OUTOF_MEMORY; + } } else { free(RangeInput); return HTTP_REQUEST_RANGE_NOT_SATISFIABLE; diff --git a/upnp/src/genlib/net/uri/uri.c b/upnp/src/genlib/net/uri/uri.c index 0c3a629..397f765 100644 --- a/upnp/src/genlib/net/uri/uri.c +++ b/upnp/src/genlib/net/uri/uri.c @@ -44,6 +44,9 @@ #include #endif #endif +#ifdef WIN32 + #define snprintf _snprintf +#endif #include @@ -612,7 +615,8 @@ char *resolve_rel_url(char *base_url, char *rel_url) out_finger++; if( rel.hostport.text.size > 0 ) { - snprintf( out_finger, strlen( rel_url ), "%s", rel_url ); + snprintf( out_finger, strlen( rel_url ) + 1, "%s", + rel_url ); } else { if( base.hostport.text.size > 0 ) { memcpy( out_finger, "//", 2 ); diff --git a/upnp/src/soap/soap_device.c b/upnp/src/soap/soap_device.c index 168cc9c..5e11ca1 100644 --- a/upnp/src/soap/soap_device.c +++ b/upnp/src/soap/soap_device.c @@ -195,7 +195,7 @@ static void send_error_response( membuffer headers; memset(err_code_str, 0, sizeof(err_code_str)); - snprintf(err_code_str, sizeof(err_code_str) - 1, "%d", error_code); + snprintf(err_code_str, sizeof(err_code_str), "%d", error_code); /* calc body len */ content_length = (off_t) (strlen(start_body) + strlen(err_code_str) + strlen(mid_body) + strlen(err_msg) + diff --git a/upnp/src/ssdp/ssdp_ctrlpt.c b/upnp/src/ssdp/ssdp_ctrlpt.c index 41dcc99..cebee93 100644 --- a/upnp/src/ssdp/ssdp_ctrlpt.c +++ b/upnp/src/ssdp/ssdp_ctrlpt.c @@ -58,6 +58,7 @@ #ifdef WIN32 #include +#define snprintf _snprintf #endif /* WIN32 */ /*! @@ -331,23 +332,22 @@ static void CreateClientRequestPacket( strcpy(RqstBuf, "M-SEARCH * HTTP/1.1\r\n"); if (AddressFamily == AF_INET) { - snprintf(TempBuf, sizeof(TempBuf) - 1, "HOST: %s:%d\r\n", - SSDP_IP, SSDP_PORT); + snprintf(TempBuf, sizeof(TempBuf), "HOST: %s:%d\r\n", SSDP_IP, + SSDP_PORT); } else if (AddressFamily == AF_INET6) { - snprintf(TempBuf, sizeof(TempBuf) - 1, "HOST: [%s]:%d\r\n", + snprintf(TempBuf, sizeof(TempBuf), "HOST: [%s]:%d\r\n", SSDP_IPV6_LINKLOCAL, SSDP_PORT); } strcat(RqstBuf, TempBuf); strcat(RqstBuf, "MAN: \"ssdp:discover\"\r\n"); if (Mx > 0) { - snprintf(TempBuf, sizeof(TempBuf) - 1, "MX: %d\r\n", Mx); + snprintf(TempBuf, sizeof(TempBuf), "MX: %d\r\n", Mx); strcat(RqstBuf, TempBuf); } if (SearchTarget != NULL) { - snprintf(TempBuf, sizeof(TempBuf) - 1, "ST: %s\r\n", - SearchTarget); + snprintf(TempBuf, sizeof(TempBuf), "ST: %s\r\n", SearchTarget); strcat(RqstBuf, TempBuf); } strcat(RqstBuf, "\r\n"); @@ -371,21 +371,20 @@ static void CreateClientRequestPacketUlaGua( memset(TempBuf, 0, sizeof(TempBuf)); strcpy(RqstBuf, "M-SEARCH * HTTP/1.1\r\n"); if (AddressFamily == AF_INET) { - snprintf(TempBuf, sizeof(TempBuf) - 1, "HOST: %s:%d\r\n", - SSDP_IP, SSDP_PORT); + snprintf(TempBuf, sizeof(TempBuf), "HOST: %s:%d\r\n", SSDP_IP, + SSDP_PORT); } else if (AddressFamily == AF_INET6) { - snprintf(TempBuf, sizeof(TempBuf) - 1, "HOST: [%s]:%d\r\n", + snprintf(TempBuf, sizeof(TempBuf), "HOST: [%s]:%d\r\n", SSDP_IPV6_SITELOCAL, SSDP_PORT); } strcat(RqstBuf, TempBuf); strcat(RqstBuf, "MAN: \"ssdp:discover\"\r\n"); if (Mx > 0) { - snprintf(TempBuf, sizeof(TempBuf) - 1, "MX: %d\r\n", Mx); + snprintf(TempBuf, sizeof(TempBuf), "MX: %d\r\n", Mx); strcat(RqstBuf, TempBuf); } if (SearchTarget) { - snprintf(TempBuf, sizeof(TempBuf) - 1, "ST: %s\r\n", - SearchTarget); + snprintf(TempBuf, sizeof(TempBuf), "ST: %s\r\n", SearchTarget); strcat(RqstBuf, TempBuf); } strcat(RqstBuf, "\r\n"); diff --git a/upnp/src/ssdp/ssdp_device.c b/upnp/src/ssdp/ssdp_device.c index 46c3ae2..43a6e0a 100644 --- a/upnp/src/ssdp/ssdp_device.c +++ b/upnp/src/ssdp/ssdp_device.c @@ -56,6 +56,10 @@ #include #include +#ifdef WIN32 + #define snprintf _snprintf +#endif + #define MSGTYPE_SHUTDOWN 0 #define MSGTYPE_ADVERTISEMENT 1 #define MSGTYPE_REPLY 2 @@ -435,7 +439,8 @@ int DeviceAdvertisement(char *DevType, int RootDev, char *Udn, char *Location, /* char Mil_Nt[LINE_SIZE] */ char Mil_Usn[LINE_SIZE]; char *msgs[3]; - int ret_code = UPNP_E_SUCCESS; + int ret_code = UPNP_E_OUTOF_MEMORY; + int rc = 0; UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, "In function DeviceAdvertisement\n"); @@ -462,8 +467,10 @@ int DeviceAdvertisement(char *DevType, int RootDev, char *Udn, char *Location, /* If deviceis a root device , here we need to send 3 advertisement * or reply */ if (RootDev) { - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, - "%s::upnp:rootdevice", Udn); + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::upnp:rootdevice", + Udn); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; CreateServicePacket(MSGTYPE_ADVERTISEMENT, "upnp:rootdevice", Mil_Usn, Location, Duration, &msgs[0], AddressFamily, PowerState, SleepPeriod, @@ -473,16 +480,15 @@ int DeviceAdvertisement(char *DevType, int RootDev, char *Udn, char *Location, CreateServicePacket(MSGTYPE_ADVERTISEMENT, Udn, Udn, Location, Duration, &msgs[1], AddressFamily, PowerState, SleepPeriod, RegistrationState); - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, "%s::%s", Udn, DevType); + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::%s", Udn, DevType); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; CreateServicePacket(MSGTYPE_ADVERTISEMENT, DevType, Mil_Usn, Location, Duration, &msgs[2], AddressFamily, PowerState, SleepPeriod, RegistrationState); /* check error */ if ((RootDev && msgs[0] == NULL) || msgs[1] == NULL || msgs[2] == NULL) { - free(msgs[0]); - free(msgs[1]); - free(msgs[2]); - return UPNP_E_OUTOF_MEMORY; + goto error_handler; } /* send packets */ if (RootDev) { @@ -495,6 +501,8 @@ int DeviceAdvertisement(char *DevType, int RootDev, char *Udn, char *Location, ret_code = NewRequestHandler((struct sockaddr *)&__ss, 2, &msgs[1]); } + +error_handler: /* free msgs */ free(msgs[0]); free(msgs[1]); @@ -507,11 +515,12 @@ int SendReply(struct sockaddr *DestAddr, char *DevType, int RootDev, char *Udn, char *Location, int Duration, int ByType, int PowerState, int SleepPeriod, int RegistrationState) { - int ret_code; + int ret_code = UPNP_E_OUTOF_MEMORY; char *msgs[2]; int num_msgs; char Mil_Usn[LINE_SIZE]; int i; + int rc = 0; msgs[0] = NULL; msgs[1] = NULL; @@ -520,8 +529,10 @@ int SendReply(struct sockaddr *DestAddr, char *DevType, int RootDev, /* one msg for root device */ num_msgs = 1; - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, "%s::upnp:rootdevice", + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::upnp:rootdevice", Udn); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; CreateServicePacket(MSGTYPE_REPLY, "upnp:rootdevice", Mil_Usn, Location, Duration, &msgs[0], DestAddr->sa_family, PowerState, @@ -537,8 +548,10 @@ int SendReply(struct sockaddr *DestAddr, char *DevType, int RootDev, DestAddr->sa_family, PowerState, SleepPeriod, RegistrationState); } else { - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, "%s::%s", Udn, + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::%s", Udn, DevType); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; CreateServicePacket(MSGTYPE_REPLY, DevType, Mil_Usn, Location, Duration, &msgs[0], DestAddr->sa_family, PowerState, @@ -548,12 +561,13 @@ int SendReply(struct sockaddr *DestAddr, char *DevType, int RootDev, /* check error */ for (i = 0; i < num_msgs; i++) { if (msgs[i] == NULL) { - free(msgs[0]); - return UPNP_E_OUTOF_MEMORY; + goto error_handler; } } /* send msgs */ ret_code = NewRequestHandler(DestAddr, num_msgs, msgs); + +error_handler: for (i = 0; i < num_msgs; i++) { if (msgs[i] != NULL) free(msgs[i]); @@ -567,7 +581,8 @@ int DeviceReply(struct sockaddr *DestAddr, char *DevType, int RootDev, int SleepPeriod, int RegistrationState) { char *szReq[3], Mil_Nt[LINE_SIZE], Mil_Usn[LINE_SIZE]; - int RetVal; + int RetVal = UPNP_E_OUTOF_MEMORY; + int rc = 0; szReq[0] = NULL; szReq[1] = NULL; @@ -578,30 +593,36 @@ int DeviceReply(struct sockaddr *DestAddr, char *DevType, int RootDev, if (RootDev) { /* 3 replies for root device */ strncpy(Mil_Nt, "upnp:rootdevice", sizeof(Mil_Nt) - 1); - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, "%s::upnp:rootdevice", - Udn); + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::upnp:rootdevice", Udn); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; CreateServicePacket(MSGTYPE_REPLY, Mil_Nt, Mil_Usn, Location, Duration, &szReq[0], DestAddr->sa_family, PowerState, SleepPeriod, RegistrationState); } - snprintf(Mil_Nt, sizeof(Mil_Nt) - 1, "%s", Udn); - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, "%s", Udn); + rc = snprintf(Mil_Nt, sizeof(Mil_Nt), "%s", Udn); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Nt)) + goto error_handler; + snprintf(Mil_Usn, sizeof(Mil_Usn), "%s", Udn); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; CreateServicePacket(MSGTYPE_REPLY, Mil_Nt, Mil_Usn, Location, Duration, &szReq[1], DestAddr->sa_family, PowerState, SleepPeriod, RegistrationState); - snprintf(Mil_Nt, sizeof(Mil_Nt) - 1, "%s", DevType); - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, "%s::%s", Udn, DevType); + rc = snprintf(Mil_Nt, sizeof(Mil_Nt), "%s", DevType); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Nt)) + goto error_handler; + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::%s", Udn, DevType); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; CreateServicePacket(MSGTYPE_REPLY, Mil_Nt, Mil_Usn, Location, Duration, &szReq[2], DestAddr->sa_family, PowerState, SleepPeriod, RegistrationState); /* check error */ if ((RootDev && szReq[0] == NULL) || szReq[1] == NULL || szReq[2] == NULL) { - free(szReq[0]); - free(szReq[1]); - free(szReq[2]); - return UPNP_E_OUTOF_MEMORY; + goto error_handler; } /* send replies */ if (RootDev) { @@ -609,6 +630,8 @@ int DeviceReply(struct sockaddr *DestAddr, char *DevType, int RootDev, } else { RetVal = NewRequestHandler(DestAddr, 2, &szReq[1]); } + +error_handler: /* free */ free(szReq[0]); free(szReq[1]); @@ -623,13 +646,15 @@ int ServiceAdvertisement(char *Udn, char *ServType, char *Location, { char Mil_Usn[LINE_SIZE]; char *szReq[1]; - int RetVal = UPNP_E_SUCCESS; + int RetVal = UPNP_E_OUTOF_MEMORY; struct sockaddr_storage __ss; struct sockaddr_in *DestAddr4 = (struct sockaddr_in *)&__ss; struct sockaddr_in6 *DestAddr6 = (struct sockaddr_in6 *)&__ss; + int rc = 0; memset(&__ss, 0, sizeof(__ss)); memset(Mil_Usn, 0, sizeof(Mil_Usn)); + szReq[0] = NULL; if (AddressFamily == AF_INET) { DestAddr4->sin_family = AF_INET; inet_pton(AF_INET, SSDP_IP, &DestAddr4->sin_addr); @@ -645,16 +670,20 @@ int ServiceAdvertisement(char *Udn, char *ServType, char *Location, UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__, "Invalid device address family.\n"); } - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1,"%s::%s", Udn, ServType); + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::%s", Udn, ServType); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; /* CreateServiceRequestPacket(1,szReq[0],Mil_Nt,Mil_Usn, * Server,Location,Duration); */ CreateServicePacket(MSGTYPE_ADVERTISEMENT, ServType, Mil_Usn, Location, Duration, &szReq[0], AddressFamily, PowerState, SleepPeriod, RegistrationState); if (szReq[0] == NULL) { - return UPNP_E_OUTOF_MEMORY; + goto error_handler; } RetVal = NewRequestHandler((struct sockaddr *)&__ss, 1, szReq); + +error_handler: free(szReq[0]); return RetVal; @@ -666,17 +695,22 @@ int ServiceReply(struct sockaddr *DestAddr, char *ServType, char *Udn, { char Mil_Usn[LINE_SIZE]; char *szReq[1]; - int RetVal; + int RetVal = UPNP_E_OUTOF_MEMORY; + int rc = 0; memset(Mil_Usn, 0, sizeof(Mil_Usn)); szReq[0] = NULL; - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, "%s::%s", Udn, ServType); + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::%s", Udn, ServType); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; CreateServicePacket(MSGTYPE_REPLY, ServType, Mil_Usn, Location, Duration, &szReq[0], DestAddr->sa_family, PowerState, SleepPeriod, RegistrationState); if (szReq[0] == NULL) - return UPNP_E_OUTOF_MEMORY; + goto error_handler; RetVal = NewRequestHandler(DestAddr, 1, szReq); + +error_handler: free(szReq[0]); return RetVal; @@ -691,10 +725,12 @@ int ServiceShutdown(char *Udn, char *ServType, char *Location, int Duration, struct sockaddr_storage __ss; struct sockaddr_in *DestAddr4 = (struct sockaddr_in *)&__ss; struct sockaddr_in6 *DestAddr6 = (struct sockaddr_in6 *)&__ss; - int RetVal = UPNP_E_SUCCESS; + int RetVal = UPNP_E_OUTOF_MEMORY; + int rc = 0; memset(&__ss, 0, sizeof(__ss)); memset(Mil_Usn, 0, sizeof(Mil_Usn)); + szReq[0] = NULL; if (AddressFamily == AF_INET) { DestAddr4->sin_family = AF_INET; inet_pton(AF_INET, SSDP_IP, &DestAddr4->sin_addr); @@ -711,15 +747,19 @@ int ServiceShutdown(char *Udn, char *ServType, char *Location, int Duration, "Invalid device address family.\n"); } /* sprintf(Mil_Nt,"%s",ServType); */ - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, "%s::%s", Udn, ServType); + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::%s", Udn, ServType); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; /* CreateServiceRequestPacket(0,szReq[0],Mil_Nt,Mil_Usn, * Server,Location,Duration); */ CreateServicePacket(MSGTYPE_SHUTDOWN, ServType, Mil_Usn, Location, Duration, &szReq[0], AddressFamily, PowerState, SleepPeriod, RegistrationState); if (szReq[0] == NULL) - return UPNP_E_OUTOF_MEMORY; + goto error_handler; RetVal = NewRequestHandler((struct sockaddr *)&__ss, 1, szReq); + +error_handler: free(szReq[0]); return RetVal; @@ -734,7 +774,8 @@ int DeviceShutdown(char *DevType, int RootDev, char *Udn, char *_Server, struct sockaddr_in6 *DestAddr6 = (struct sockaddr_in6 *)&__ss; char *msgs[3]; char Mil_Usn[LINE_SIZE]; - int ret_code = UPNP_E_SUCCESS; + int ret_code = UPNP_E_OUTOF_MEMORY; + int rc = 0; msgs[0] = NULL; msgs[1] = NULL; @@ -758,8 +799,10 @@ int DeviceShutdown(char *DevType, int RootDev, char *Udn, char *_Server, } /* root device has one extra msg */ if (RootDev) { - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, "%s::upnp:rootdevice", + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::upnp:rootdevice", Udn); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; CreateServicePacket(MSGTYPE_SHUTDOWN, "upnp:rootdevice", Mil_Usn, Location, Duration, &msgs[0], AddressFamily, PowerState, SleepPeriod, @@ -771,16 +814,15 @@ int DeviceShutdown(char *DevType, int RootDev, char *Udn, char *_Server, CreateServicePacket(MSGTYPE_SHUTDOWN, Udn, Udn, Location, Duration, &msgs[1], AddressFamily, PowerState, SleepPeriod, RegistrationState); - snprintf(Mil_Usn, sizeof(Mil_Usn) - 1, "%s::%s", Udn, DevType); + rc = snprintf(Mil_Usn, sizeof(Mil_Usn), "%s::%s", Udn, DevType); + if (rc < 0 || (unsigned int) rc >= sizeof(Mil_Usn)) + goto error_handler; CreateServicePacket(MSGTYPE_SHUTDOWN, DevType, Mil_Usn, Location, Duration, &msgs[2], AddressFamily, PowerState, SleepPeriod, RegistrationState); /* check error */ if ((RootDev && msgs[0] == NULL) || msgs[1] == NULL || msgs[2] == NULL) { - free(msgs[0]); - free(msgs[1]); - free(msgs[2]); - return UPNP_E_OUTOF_MEMORY; + goto error_handler; } /* send packets */ if (RootDev) { @@ -793,6 +835,8 @@ int DeviceShutdown(char *DevType, int RootDev, char *Udn, char *_Server, ret_code = NewRequestHandler((struct sockaddr *)&__ss, 2, &msgs[1]); } + +error_handler: /* free msgs */ free(msgs[0]); free(msgs[1]); diff --git a/upnp/src/ssdp/ssdp_server.c b/upnp/src/ssdp/ssdp_server.c index a284c7e..c954077 100644 --- a/upnp/src/ssdp/ssdp_server.c +++ b/upnp/src/ssdp/ssdp_server.c @@ -40,6 +40,7 @@ #ifndef WIN32 #include + #define snprintf _snprintf #endif /* WIN32 */ #include "config.h" @@ -456,6 +457,7 @@ int unique_service_name(char *cmd, SsdpEvent *Evt) char *ptr3 = NULL; int CommandFound = 0; size_t n = 0; + int rc = 0; if (strstr(cmd, "uuid:schemas") != NULL) { ptr1 = strstr(cmd, ":device"); @@ -469,8 +471,10 @@ int unique_service_name(char *cmd, SsdpEvent *Evt) return -1; if (ptr3 != NULL) { memset(Evt->UDN, 0, sizeof(Evt->UDN)); - snprintf(Evt->UDN, sizeof(Evt->UDN) - 1, - "uuid:%s", ptr3 + 1); + rc = snprintf(Evt->UDN, sizeof(Evt->UDN), "uuid:%s", + ptr3 + 1); + if (rc < 0 || (unsigned int) rc >= sizeof(Evt->UDN)) + return -1; } else return -1; @@ -480,8 +484,10 @@ int unique_service_name(char *cmd, SsdpEvent *Evt) strncpy(TempBuf, ptr1, n); TempBuf[n] = '\0'; memset(Evt->DeviceType, 0, sizeof(Evt->DeviceType)); - snprintf(Evt->DeviceType, sizeof(Evt->DeviceType) - 1, + rc = snprintf(Evt->DeviceType, sizeof(Evt->DeviceType), "urn%s", TempBuf); + if (rc < 0 || (unsigned int) rc >= sizeof(Evt->DeviceType)) + return -1; } else return -1; return 0; diff --git a/upnp/src/urlconfig/urlconfig.c b/upnp/src/urlconfig/urlconfig.c index a8c025a..00ac1df 100644 --- a/upnp/src/urlconfig/urlconfig.c +++ b/upnp/src/urlconfig/urlconfig.c @@ -135,6 +135,7 @@ static UPNP_INLINE int calc_alias( return UPNP_E_OUTOF_MEMORY; memset(alias_temp, 0, new_alias_len + 1); strncpy(alias_temp, rootPath, root_len); + alias_temp[root_len] = '\0'; strncat(alias_temp, temp_str, strlen(temp_str)); strncat(alias_temp, aliasPtr, strlen(aliasPtr)); @@ -175,6 +176,7 @@ static UPNP_INLINE int calc_descURL( if (len > (LINE_SIZE - 1)) return UPNP_E_URL_TOO_BIG; strncpy(descURL, http_scheme, strlen(http_scheme)); + descURL[strlen(http_scheme)] = '\0'; strncat(descURL, ipPortStr, strlen(ipPortStr)); strncat(descURL, alias, strlen(alias)); descURL[len] = '\0';