@@ -142,21 +142,26 @@ void SSDPPlugin::finish(bool print_stats)
142142 * \param [in] ip_version IP version of the Location url being parsed.
143143 * \return Parsed port number on success, 0 otherwise.
144144 */
145- uint16_t SSDPPlugin::parse_loc_port (char *data, uint8_t ip_version)
145+ uint16_t SSDPPlugin::parse_loc_port (const char *data, unsigned data_len , uint8_t ip_version)
146146{
147147 uint16_t port;
148148 char *end_ptr = nullptr ;
149+ const void *data_mem = static_cast <const void *>(data);
149150
150151 if (ip_version == IP::v6) {
151- data = strchr (data , ' ]' );
152+ data_mem = memchr (data_mem , ' ]' , data_len );
152153 } else {
153- data = strchr (data , ' .' );
154+ data_mem = memchr (data_mem , ' .' , data_len );
154155 }
155- data = strchr (data, ' :' );
156+ if (data_mem == nullptr ) {
157+ return 0 ;
158+ }
159+ data_mem = memchr (data_mem, ' :' , data_len);
156160
157- if (data == nullptr ) {
161+ if (data_mem == nullptr ) {
158162 return 0 ;
159163 }
164+ data = static_cast <const char *>(data_mem);
160165 data++;
161166
162167 port = strtol (data, &end_ptr, 0 );
@@ -174,7 +179,7 @@ uint16_t SSDPPlugin::parse_loc_port(char *data, uint8_t ip_version)
174179 * \param [in] len Lenght of the desired header.
175180 * \return True if the header is found, otherwise false.
176181 */
177- bool SSDPPlugin::get_header_val (char **data, const char *header, const int len)
182+ bool SSDPPlugin::get_header_val (const char **data, const char *header, const int len)
178183{
179184 if (strncasecmp (*data, header, len) == 0 && (*data)[len] == ' :' ) {
180185 (*data) += len + 1 ;
@@ -193,34 +198,33 @@ bool SSDPPlugin::get_header_val(char **data, const char *header, const int len)
193198 * \param [in] payload_len Lenght of payload data
194199 * \param [in] conf Struct containing parser configuration.
195200 */
196- void SSDPPlugin::parse_headers (char *data, size_t payload_len, header_parser_conf conf)
201+ void SSDPPlugin::parse_headers (const uint8_t *data, size_t payload_len, header_parser_conf conf)
197202{
198- char *ptr = data;
199- char *old_ptr = ptr;
203+ const char *ptr = ( const char *)( data) ;
204+ const char *old_ptr = ptr;
200205 size_t len = 0 ;
201206
202207 while (*ptr != ' \0 ' && len <= payload_len) {
203208 if (*ptr == ' \n ' && *(ptr - 1 ) == ' \r ' ) {
204- *(ptr - 1 ) = ' \0 ' ;
205209 for (unsigned j = 0 , i = 0 ; j < conf.select_cnt ; j++) {
206210 i = conf.select [j];
207211 if (get_header_val (&old_ptr, conf.headers [i], strlen (conf.headers [i]))) {
208212 switch ((header_types) i) {
209213 case ST:
210214 if (get_header_val (&old_ptr, " urn" , strlen (" urn" ))) {
211215 SSDP_DEBUG_MSG (" %s\n " , old_ptr);
212- append_value (conf.ext ->st , SSDP_URN_LEN, old_ptr);
216+ append_value (conf.ext ->st , SSDP_URN_LEN, old_ptr, ptr-old_ptr );
213217 }
214218 break ;
215219 case NT:
216220 if (get_header_val (&old_ptr, " urn" , strlen (" urn" ))) {
217221 SSDP_DEBUG_MSG (" %s\n " , old_ptr);
218- append_value (conf.ext ->nt , SSDP_URN_LEN, old_ptr);
222+ append_value (conf.ext ->nt , SSDP_URN_LEN, old_ptr, ptr-old_ptr );
219223 }
220224 break ;
221225 case LOCATION:
222226 {
223- uint16_t port = parse_loc_port (old_ptr, conf.ip_version );
227+ uint16_t port = parse_loc_port (old_ptr, ptr-old_ptr, conf.ip_version );
224228
225229 if (port > 0 ) {
226230 SSDP_DEBUG_MSG (" %d <- %d\n " , conf.ext ->port , port);
@@ -230,11 +234,11 @@ void SSDPPlugin::parse_headers(char *data, size_t payload_len, header_parser_con
230234 }
231235 case USER_AGENT:
232236 SSDP_DEBUG_MSG (" %s\n " , old_ptr);
233- append_value (conf.ext ->user_agent , SSDP_USER_AGENT_LEN, old_ptr);
237+ append_value (conf.ext ->user_agent , SSDP_USER_AGENT_LEN, old_ptr, ptr-old_ptr );
234238 break ;
235239 case SERVER:
236240 SSDP_DEBUG_MSG (" %s\n " , old_ptr);
237- append_value (conf.ext ->server , SSDP_SERVER_LEN, old_ptr);
241+ append_value (conf.ext ->server , SSDP_SERVER_LEN, old_ptr, ptr-old_ptr );
238242 break ;
239243 default :
240244 break ;
@@ -259,14 +263,22 @@ void SSDPPlugin::parse_headers(char *data, size_t payload_len, header_parser_con
259263 * \param [in] entry_max Maximum length if the entry.
260264 * \param [in] value String containing the new entry.
261265 */
262- void SSDPPlugin::append_value (char *curr_entry, unsigned entry_max, char *value)
266+ void SSDPPlugin::append_value (char *curr_entry, unsigned entry_max, const char *value, unsigned value_len )
263267{
264- if (strlen (curr_entry) + strlen (value) + 1 < entry_max) {
265- if (strstr (curr_entry, value) == nullptr ) {
266- SSDP_DEBUG_MSG (" New entry\n " );
267- strcat (curr_entry, value);
268- strcat (curr_entry, " ;" );
268+ if (strlen (curr_entry) + value_len + 1 < entry_max) {
269+ // return if value already in curr_entry
270+ for (unsigned i = 0 ; i < strlen (curr_entry) - value_len; i++) {
271+ if (strlen (curr_entry) < value_len) {
272+ break ;
273+ }
274+ if (strncmp (&curr_entry[i], value, value_len) == 0 ) {
275+ return ;
276+ }
269277 }
278+
279+ SSDP_DEBUG_MSG (" New entry\n " );
280+ strncat (curr_entry, value, value_len);
281+ strcat (curr_entry, " ;" );
270282 }
271283}
272284
@@ -285,24 +297,22 @@ void SSDPPlugin::parse_ssdp_message(Flow &rec, const Packet &pkt)
285297 rec.ip_version ,
286298 static_cast <RecordExtSSDP *>(rec.get_extension (RecordExtSSDP::REGISTERED_ID))
287299 };
288- char *data = (char *) pkt.payload ;
289- size_t payload_len = pkt.payload_len ;
290300
291301 total++;
292- if (data [0 ] == ' N' ) {
302+ if (pkt. payload [0 ] == ' N' ) {
293303 notifies++;
294304 SSDP_DEBUG_MSG (" Notify #%d\n " , notifies);
295305 int notify_headers[] = { NT, LOCATION, SERVER };
296306 parse_conf.select = notify_headers;
297307 parse_conf.select_cnt = sizeof (notify_headers) / sizeof (notify_headers[0 ]);
298- parse_headers (data, payload_len, parse_conf);
299- } else if (data [0 ] == ' M' ) {
308+ parse_headers (pkt. payload , pkt. payload_len , parse_conf);
309+ } else if (pkt. payload [0 ] == ' M' ) {
300310 searches++;
301311 SSDP_DEBUG_MSG (" M-search #%d\n " , searches);
302312 int search_headers[] = { ST, USER_AGENT };
303313 parse_conf.select = search_headers;
304314 parse_conf.select_cnt = sizeof (search_headers) / sizeof (search_headers[0 ]);
305- parse_headers (data, payload_len, parse_conf);
315+ parse_headers (pkt. payload , pkt. payload_len , parse_conf);
306316 }
307317 SSDP_DEBUG_MSG (" \n " );
308318}
0 commit comments