Bug Summary

File:root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/ice/ice_parser.cpp
Warning:line 551, column 17
Potential leak of memory pointed to by 'component_id'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ice_parser.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/third_party/nICEr/nicer_nicer -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/third_party/nICEr/nicer_nicer -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D _FILE_OFFSET_BITS=64 -D CHROMIUM_BUILD -D USE_LIBJPEG_TURBO=1 -D USE_NSS=1 -D ENABLE_ONE_CLICK_SIGNIN -D GTK_DISABLE_SINGLE_INCLUDES=1 -D _ISOC99_SOURCE=1 -D ENABLE_REMOTING=1 -D ENABLE_WEBRTC=1 -D ENABLE_CONFIGURATION_POLICY -D ENABLE_INPUT_SPEECH -D ENABLE_NOTIFICATIONS -D ENABLE_GPU=1 -D ENABLE_EGLIMAGE=1 -D USE_SKIA=1 -D ENABLE_TASK_MANAGER=1 -D ENABLE_WEB_INTENTS=1 -D ENABLE_EXTENSIONS=1 -D ENABLE_PLUGIN_INSTALLATION=1 -D ENABLE_PROTECTOR_SERVICE=1 -D ENABLE_SESSION_SERVICE=1 -D ENABLE_THEMES=1 -D ENABLE_BACKGROUND=1 -D ENABLE_AUTOMATION=1 -D ENABLE_PRINTING=1 -D ENABLE_CAPTIVE_PORTAL_DETECTION=1 -D SANITY_CHECKS -D USE_TURN -D USE_ICE -D USE_RFC_3489_BACKWARDS_COMPATIBLE -D USE_STUN_PEDANTIC -D NR_SOCKET_IS_VOID_PTR -D restrict= -D R_PLATFORM_INT_TYPES=<stdint.h> -D R_DEFINED_INT2=int16_t -D R_DEFINED_UINT2=uint16_t -D R_DEFINED_INT4=int32_t -D R_DEFINED_UINT4=uint32_t -D R_DEFINED_INT8=int64_t -D R_DEFINED_UINT8=uint64_t -D LINUX -D HAVE_LIBM=1 -D HAVE_STRDUP=1 -D HAVE_STRLCPY=1 -D HAVE_SYS_TIME_H=1 -D HAVE_VFPRINTF=1 -D NEW_STDIORETSIGTYPE=void -D TIME_WITH_SYS_TIME_H=1 -D __UNUSED__=__attribute__((unused)) -D DYNAMIC_ANNOTATIONS_ENABLED=1 -D WTF_USE_DYNAMIC_ANNOTATIONS=1 -D _DEBUG -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/third_party/nICEr/nicer_nicer -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/event -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/log -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/registry -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/share -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/util -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/port/generic/include -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/crypto -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/ice -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/net -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/stun -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/util -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/port/linux/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -Wno-parentheses -Wno-format -Wno-format-security -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c++ /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/ice/ice_parser.cpp
1/*
2Copyright (c) 2007, Adobe Systems, Incorporated
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are
7met:
8
9* Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12* Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16* Neither the name of Adobe Systems, Network Resonance nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#include <csi_platform.h>
34#include <sys/types.h>
35#ifdef WIN32
36#include <winsock2.h>
37#else
38#include <sys/socket.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41#include <strings.h>
42#endif
43#include <string.h>
44#include <assert.h>
45#include <ctype.h>
46#include <charconv>
47#include "nr_api.h"
48#include "ice_ctx.h"
49#include "ice_candidate.h"
50#include "ice_reg.h"
51
52static void
53skip_whitespace(const char **str)
54{
55 const char *c = *str;
56 while (*c == ' ')
57 ++c;
58
59 *str = c;
60}
61
62static void
63fast_forward(const char **str, int skip)
64{
65 const char *c = *str;
66 while (*c != '\0' && skip-- > 0)
67 ++c;
68
69 *str = c;
70}
71
72static void
73skip_to_past_space(const char **str)
74{
75 const char *c = *str;
76 while (*c != ' ' && *c != '\0')
77 ++c;
78
79 *str = c;
80
81 skip_whitespace(str);
82}
83
84static int
85grab_token(const char **str, char **out)
86{
87 int _status;
88 const char *c = *str;
89 int len;
90 char *tmp;
91
92 while (*c != ' ' && *c != '\0')
12
Assuming the condition is false
93 ++c;
94
95 len = c - *str;
96
97 tmp = (char*)malloc(len + 1);
13
Memory is allocated
98 if (!tmp) {
14
Assuming 'tmp' is non-null
15
Taking false branch
99 *out = 0;
100 ABORT(R_NO_MEMORY)do { int _r=1; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
101 }
102
103 memcpy(tmp, *str, len);
104 tmp[len] = '\0';
105
106 *str = c;
107 *out = tmp;
108
109 _status = 0;
110abort:
111 return _status;
112}
113
114/* RFC 8839 section 5.1: ice-char = ALPHA / DIGIT / "+" / "/". */
115static int
116is_ice_char(unsigned char c)
117{
118 return ((c >= 'A' && c <= 'Z') ||
119 (c >= 'a' && c <= 'z') ||
120 (c >= '0' && c <= '9') ||
121 c == '+' || c == '/');
122}
123
124/* RFC 8839 section 5.1: foundation = 1*32ice-char. */
125static int
126validate_foundation(const char *foundation)
127{
128 size_t len = strlen(foundation);
129 size_t i;
130 if (len < 1 || len > 32)
131 return R_BAD_DATA7;
132 for (i = 0; i < len; ++i) {
133 if (!is_ice_char(foundation[i]))
134 return R_BAD_DATA7;
135 }
136 return 0;
137}
138
139/* Parse a decimal unsigned int from |*str|, range-check it to
140 * [min, max], and require that the next character be a space or end of
141 * string. On success, advances |*str| to that terminator. */
142static int
143parse_uint(const char **str, unsigned int min, unsigned int max,
144 unsigned int *out)
145{
146 const char *end = *str + strlen(*str);
147 unsigned int result;
148 auto [ptr, ec] = std::from_chars(*str, end, result);
149 if (ec != std::errc{} || result < min || result > max) {
150 return R_BAD_DATA7;
151 }
152
153 /* Reject trailing non-space cruft like "100abc"; the next character
154 * must terminate the token. */
155 if (*ptr != ' ' && *ptr != '\0') {
156 return R_BAD_DATA7;
157 }
158
159 *str = ptr;
160 *out = result;
161 return 0;
162}
163
164int
165nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,const char *orig,nr_ice_media_stream *stream,const char* resolved_address,nr_ice_candidate **candp)
166{
167 int r,_status;
168 nr_ice_candidate *cand=0;
169
170 if(!(cand=R_NEW(nr_ice_candidate)(nr_ice_candidate*)calloc(1,sizeof(nr_ice_candidate))))
171 ABORT(R_NO_MEMORY)do { int _r=1; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
172
173 if(!(cand->label=strdup(orig)))
174 ABORT(R_NO_MEMORY)do { int _r=1; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
175
176 cand->ctx=ctx;
177 cand->isock=0;
178 cand->state=NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED9;
179 cand->stream=stream;
180
181 if ((r=nr_ice_parse_candidate_attribute(orig, resolved_address, cand)))
182 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
183
184 nr_ice_candidate_compute_codeword(cand);
185
186 *candp=cand;
187
188 _status=0;
189 abort:
190 if (_status){
191 r_log(LOG_ICE,LOG_WARNING4,"ICE(%s): Error parsing attribute: %s",ctx->label,orig);
192 nr_ice_candidate_destroy(&cand);
193 }
194
195 return(_status);
196}
197
198int
199nr_ice_parse_candidate_attribute(const char* orig, const char* resolved_address, struct nr_ice_candidate_parsedbits *bits)
200{
201 int r,_status;
202 const char* str = orig;
203 char *connection_address=0;
204 unsigned int port;
205 int i;
206 unsigned int component_id;
207 char *rel_addr=0;
208 unsigned char transport;
209 const char* ip = nullptr;
210 const char* domain_name = nullptr;
211
212 /* Skip a= if present */
213 if (!strncmp(str, "a=", 2))
214 str += 2;
215
216 /* Candidate attr */
217 if (strncasecmp(str, "candidate:", 10))
218 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
219
220 fast_forward(&str, 10);
221 if (*str == '\0')
222 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
223
224 /* Foundation */
225 if ((r=grab_token(&str, &bits->foundation)))
226 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
227
228 if ((r=validate_foundation(bits->foundation)))
229 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
230
231 if (*str == '\0')
232 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
233
234 skip_whitespace(&str);
235 if (*str == '\0')
236 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
237
238 /* component */
239 if ((r=parse_uint(&str, 1, 256, &component_id)))
240 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
241
242 bits->component_id = (UCHAR)component_id;
243
244 skip_whitespace(&str);
245 if (*str == '\0')
246 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
247
248 /* Protocol */
249 if (!strncasecmp(str, "UDP", 3))
250 transport=IPPROTO_UDPIPPROTO_UDP;
251 else if (!strncasecmp(str, "TCP", 3))
252 transport=IPPROTO_TCPIPPROTO_TCP;
253 else
254 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
255
256 fast_forward(&str, 3);
257 if (*str == '\0')
258 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
259
260 skip_whitespace(&str);
261 if (*str == '\0')
262 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
263
264 /* priority. RFC 8839 says this is a positive integer between 1 and
265 * 2^31 - 1 inclusive. */
266 if ((r=parse_uint(&str, 1, 0x7FFFFFFFu, &bits->priority)))
267 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
268
269 skip_whitespace(&str);
270 if (*str == '\0')
271 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
272
273 /* Peer address/port */
274 if ((r=grab_token(&str, &connection_address)))
275 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
276
277 if (*str == '\0')
278 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
279
280 skip_whitespace(&str);
281 if (*str == '\0')
282 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
283
284 if ((r=parse_uint(&str, 0, 65535, &port)))
285 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
286
287 skip_whitespace(&str);
288
289 ip = resolved_address ? resolved_address : connection_address;
290 domain_name = resolved_address ? connection_address : nullptr;
291
292 if ((r=nr_str_port_to_transport_addr(ip,domain_name,port,transport,&bits->addr))) {
293 // Ok, maybe this is a candidate with a domain name that just hasn't been
294 // resolved.
295 if ((r=nr_str_port_to_transport_addr(nullptr, connection_address, port,transport,&bits->addr))) {
296 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
297 }
298 }
299
300 /* Transfer the raw connection_address text to bits so callers can
301 * surface the original (non-normalized) form. */
302 bits->raw_addr = connection_address;
303 connection_address = 0;
304
305 if (*str == '\0')
306 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
307
308 /* Type */
309 if (strncasecmp("typ", str, 3))
310 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
311
312 fast_forward(&str, 3);
313 if (*str == '\0')
314 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
315
316 skip_whitespace(&str);
317 if (*str == '\0')
318 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
319
320 assert(nr_ice_candidate_type_names[0] == 0)(static_cast <bool> (nr_ice_candidate_type_names[0] == 0
) ? void (0) : __assert_fail ("nr_ice_candidate_type_names[0] == 0"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
;
321
322 for (i = 1; nr_ice_candidate_type_names[i]; ++i) {
323 if(!strncasecmp(nr_ice_candidate_type_names[i], str, strlen(nr_ice_candidate_type_names[i]))) {
324 bits->type=(nr_ice_candidate_type)i;
325 break;
326 }
327 }
328 if (nr_ice_candidate_type_names[i] == 0)
329 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
330
331 fast_forward(&str, strlen(nr_ice_candidate_type_names[i]));
332
333 /* Look for the other side's raddr, rport */
334 /* raddr, rport */
335 switch (bits->type) {
336 case HOST:
337 break;
338 case SERVER_REFLEXIVE:
339 case PEER_REFLEXIVE:
340 case RELAYED:
341
342 skip_whitespace(&str);
343 if (*str == '\0')
344 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
345
346 if (strncasecmp("raddr", str, 5))
347 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
348
349 fast_forward(&str, 5);
350 if (*str == '\0')
351 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
352
353 skip_whitespace(&str);
354 if (*str == '\0')
355 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
356
357 if ((r=grab_token(&str, &rel_addr)))
358 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
359
360 if (*str == '\0')
361 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
362
363 skip_whitespace(&str);
364 if (*str == '\0')
365 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
366
367 if (strncasecmp("rport", str, 5))
368 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
369
370 fast_forward(&str, 5);
371 if (*str == '\0')
372 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
373
374 skip_whitespace(&str);
375 if (*str == '\0')
376 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
377
378 if ((r=parse_uint(&str, 0, 65535, &port)))
379 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
380
381 skip_whitespace(&str);
382
383 if (r=nr_str_port_to_transport_addr(rel_addr, nullptr, port,transport,&bits->base)) {
384 // Ok, rel_addr must not be an IP address.
385 if (r=nr_str_port_to_transport_addr(nullptr, rel_addr,port,transport,&bits->base)) {
386 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
387 }
388 }
389
390 /* Transfer the raw rel-addr text to bits so callers can surface
391 * the original (non-normalized) form. */
392 bits->raw_raddr = rel_addr;
393 rel_addr = 0;
394
395 /* it's expected to be at EOD at this point */
396
397 break;
398 default:
399 ABORT(R_INTERNAL)do { int _r=3; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
400 break;
401 }
402
403 skip_whitespace(&str);
404
405 if (transport == IPPROTO_TCPIPPROTO_TCP && bits->type != RELAYED) {
406 /* Parse tcptype extension per RFC 6544 S 4.5 */
407 if (strncasecmp("tcptype ", str, 8))
408 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
409
410 fast_forward(&str, 8);
411 skip_whitespace(&str);
412
413 for (i = 1; nr_ice_candidate_tcp_type_names[i]; ++i) {
414 if(!strncasecmp(nr_ice_candidate_tcp_type_names[i], str, strlen(nr_ice_candidate_tcp_type_names[i]))) {
415 bits->tcp_type=(nr_socket_tcp_type)i;
416 fast_forward(&str, strlen(nr_ice_candidate_tcp_type_names[i]));
417 break;
418 }
419 }
420
421 if (bits->tcp_type == 0)
422 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
423
424 if (*str && *str != ' ')
425 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
426 }
427 /* Ignore extensions per RFC 5245 S 15.1 */
428
429 _status=0;
430 abort:
431 free(connection_address);
432 free(rel_addr);
433 return(_status);
434}
435
436int
437nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr)
438{
439 int r,_status;
440 const char *orig = 0;
441 const char *str;
442
443 orig = str = attr;
444
445 if (!strncasecmp(str, "ice-ufrag:", 10)) {
446 fast_forward(&str, 10);
447 if (*str == '\0')
448 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
449
450 skip_whitespace(&str);
451 if (*str == '\0')
452 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
453
454 free(stream->ufrag);
455 if ((r=grab_token(&str, &stream->ufrag)))
456 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
457 }
458 else if (!strncasecmp(str, "ice-pwd:", 8)) {
459 fast_forward(&str, 8);
460 if (*str == '\0')
461 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
462
463 skip_whitespace(&str);
464 if (*str == '\0')
465 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
466
467 free(stream->pwd);
468 if ((r=grab_token(&str, &stream->pwd)))
469 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
470 }
471 else {
472 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
473 }
474
475 skip_whitespace(&str);
476
477 /* RFC 5245 grammar doesn't have an extension point for ice-pwd or
478 ice-ufrag: if there's anything left on the line, we treat it as bad. */
479 if (str[0] != '\0') {
480 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
481 }
482
483 _status=0;
484 abort:
485 if (_status) {
486 if (orig)
487 r_log(LOG_ICE,LOG_WARNING4,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig);
488 }
489
490 return(_status);
491}
492
493int
494nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int attr_ct)
495{
496 int r,_status;
497 int i;
498 const char *orig = 0;
499 const char *str;
500 char *component_id = 0;
501 char *connection_address = 0;
502 unsigned int port;
503 in_addr_t addr;
504 char *ice_option_tag = 0;
505
506 for(i=0;i<attr_ct;i++){
1
Assuming 'i' is < 'attr_ct'
2
Loop condition is true. Entering loop body
6
Assuming 'i' is < 'attr_ct'
7
Loop condition is true. Entering loop body
507 orig = str = attrs[i];
508
509 component_id = 0;
510 connection_address = 0;
511 ice_option_tag = 0;
512
513 if (!strncasecmp(str, "remote-candidates:", 18)) {
3
Taking true branch
8
Taking true branch
514 fast_forward(&str, 18);
515 skip_whitespace(&str);
516
517 while (*str != '\0') {
4
Loop condition is false. Execution continues on line 604
9
Assuming the condition is true
10
Loop condition is true. Entering loop body
518 if ((r=grab_token(&str, &component_id)))
11
Calling 'grab_token'
16
Returned allocated memory via 2nd parameter
17
Assuming 'r' is 0
18
Taking false branch
519 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
520
521 if (*str == '\0')
19
Taking false branch
522 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
523
524 skip_whitespace(&str);
525 if (*str == '\0')
20
Assuming the condition is false
21
Taking false branch
526 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
527
528 if ((r=grab_token(&str, &connection_address)))
22
Assuming 'r' is 0
23
Taking false branch
529 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
530
531 if (*str == '\0')
24
Taking false branch
532 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
533
534 addr = inet_addr(connection_address);
535 if (addr == INADDR_NONE((in_addr_t) 0xffffffff))
25
Assuming 'addr' is not equal to INADDR_NONE
26
Taking false branch
536 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
537
538 skip_whitespace(&str);
539 if (*str == '\0')
27
Assuming the condition is false
28
Taking false branch
540 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
541
542 if (sscanf(str, "%u", &port) != 1)
29
Assuming the condition is false
543 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
544
545 if (port < 1 || port > 0x0FFFF)
30
Assuming 'port' is >= 1
31
Assuming 'port' is <= 65535
32
Taking false branch
546 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
547
548 skip_to_past_space(&str);
549
550 component_id = 0; /* prevent free */
551 free(connection_address);
33
Potential leak of memory pointed to by 'component_id'
552 connection_address = 0; /* prevent free */
553 }
554 }
555 else if (!strncasecmp(str, "ice-lite", 8)) {
556 pctx->peer_lite = 1;
557 pctx->controlling = 1;
558
559 fast_forward(&str, 8);
560 }
561 else if (!strncasecmp(str, "ice-mismatch", 12)) {
562 pctx->peer_ice_mismatch = 1;
563
564 fast_forward(&str, 12);
565 }
566 else if (!strncasecmp(str, "ice-ufrag:", 10)) {
567 fast_forward(&str, 10);
568 if (*str == '\0')
569 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
570
571 skip_whitespace(&str);
572 if (*str == '\0')
573 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
574 }
575 else if (!strncasecmp(str, "ice-pwd:", 8)) {
576 fast_forward(&str, 8);
577 if (*str == '\0')
578 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
579
580 skip_whitespace(&str);
581 if (*str == '\0')
582 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
583 }
584 else if (!strncasecmp(str, "ice-options:", 12)) {
585 fast_forward(&str, 12);
586 skip_whitespace(&str);
587
588 while (*str != '\0') {
589 if ((r=grab_token(&str, &ice_option_tag)))
590 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
591
592 skip_whitespace(&str);
593
594 //TODO: for now, just throw away; later put somewhere
595 free(ice_option_tag);
596
597 ice_option_tag = 0; /* prevent free */
598 }
599 }
600 else {
601 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
602 }
603
604 skip_whitespace(&str);
605
606 /* RFC 5245 grammar doesn't have an extension point for any of the
607 preceding attributes: if there's anything left on the line, we
608 treat it as bad data. */
609 if (str[0] != '\0') {
5
Taking false branch
610 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
611 }
612 }
613
614 _status=0;
615 abort:
616 if (_status) {
617 if (orig)
618 r_log(LOG_ICE,LOG_WARNING4,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig);
619 }
620
621 free(connection_address);
622 free(component_id);
623 free(ice_option_tag);
624 return(_status);
625}
626