Bug Summary

File:root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/ice/ice_parser.cpp
Warning:line 537, 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_STUND_0_96 -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-09-01-224014-2642839-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,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, 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, 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
210 /* Skip a= if present */
211 if (!strncmp(str, "a=", 2))
212 str += 2;
213
214 /* Candidate attr */
215 if (strncasecmp(str, "candidate:", 10))
216 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
217
218 fast_forward(&str, 10);
219 if (*str == '\0')
220 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
221
222 /* Foundation */
223 if ((r=grab_token(&str, &bits->foundation)))
224 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
225
226 if ((r=validate_foundation(bits->foundation)))
227 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
228
229 if (*str == '\0')
230 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
231
232 skip_whitespace(&str);
233 if (*str == '\0')
234 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
235
236 /* component */
237 if ((r=parse_uint(&str, 1, 256, &component_id)))
238 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
239
240 bits->component_id = (UCHAR)component_id;
241
242 skip_whitespace(&str);
243 if (*str == '\0')
244 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
245
246 /* Protocol */
247 if (!strncasecmp(str, "UDP", 3))
248 transport=IPPROTO_UDPIPPROTO_UDP;
249 else if (!strncasecmp(str, "TCP", 3))
250 transport=IPPROTO_TCPIPPROTO_TCP;
251 else
252 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
253
254 fast_forward(&str, 3);
255 if (*str == '\0')
256 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
257
258 skip_whitespace(&str);
259 if (*str == '\0')
260 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
261
262 /* priority. RFC 8839 says this is a positive integer between 1 and
263 * 2^31 - 1 inclusive. */
264 if ((r=parse_uint(&str, 1, 0x7FFFFFFFu, &bits->priority)))
265 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
266
267 skip_whitespace(&str);
268 if (*str == '\0')
269 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
270
271 /* Peer address/port */
272 if ((r=grab_token(&str, &connection_address)))
273 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
274
275 if (*str == '\0')
276 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
277
278 skip_whitespace(&str);
279 if (*str == '\0')
280 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
281
282 if ((r=parse_uint(&str, 0, 65535, &port)))
283 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
284
285 skip_whitespace(&str);
286
287 if ((r=nr_str_port_to_transport_addr(connection_address,port,transport,&bits->addr)))
288 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
289
290 /* Transfer the raw connection_address text to bits so callers can
291 * surface the original (non-normalized) form. */
292 bits->raw_addr = connection_address;
293 connection_address = 0;
294
295 if (*str == '\0')
296 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
297
298 /* Type */
299 if (strncasecmp("typ", str, 3))
300 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
301
302 fast_forward(&str, 3);
303 if (*str == '\0')
304 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
305
306 skip_whitespace(&str);
307 if (*str == '\0')
308 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
309
310 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__
))
;
311
312 for (i = 1; nr_ice_candidate_type_names[i]; ++i) {
313 if(!strncasecmp(nr_ice_candidate_type_names[i], str, strlen(nr_ice_candidate_type_names[i]))) {
314 bits->type=(nr_ice_candidate_type)i;
315 break;
316 }
317 }
318 if (nr_ice_candidate_type_names[i] == 0)
319 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
320
321 fast_forward(&str, strlen(nr_ice_candidate_type_names[i]));
322
323 /* Look for the other side's raddr, rport */
324 /* raddr, rport */
325 switch (bits->type) {
326 case HOST:
327 break;
328 case SERVER_REFLEXIVE:
329 case PEER_REFLEXIVE:
330 case RELAYED:
331
332 skip_whitespace(&str);
333 if (*str == '\0')
334 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
335
336 if (strncasecmp("raddr", str, 5))
337 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
338
339 fast_forward(&str, 5);
340 if (*str == '\0')
341 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
342
343 skip_whitespace(&str);
344 if (*str == '\0')
345 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
346
347 if ((r=grab_token(&str, &rel_addr)))
348 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
349
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 (strncasecmp("rport", str, 5))
358 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
359
360 fast_forward(&str, 5);
361 if (*str == '\0')
362 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
363
364 skip_whitespace(&str);
365 if (*str == '\0')
366 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
367
368 if ((r=parse_uint(&str, 0, 65535, &port)))
369 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
370
371 skip_whitespace(&str);
372
373 if ((r=nr_str_port_to_transport_addr(rel_addr,port,transport,&bits->base)))
374 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
375
376 /* Transfer the raw rel-addr text to bits so callers can surface
377 * the original (non-normalized) form. */
378 bits->raw_raddr = rel_addr;
379 rel_addr = 0;
380
381 /* it's expected to be at EOD at this point */
382
383 break;
384 default:
385 ABORT(R_INTERNAL)do { int _r=3; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
386 break;
387 }
388
389 skip_whitespace(&str);
390
391 if (transport == IPPROTO_TCPIPPROTO_TCP && bits->type != RELAYED) {
392 /* Parse tcptype extension per RFC 6544 S 4.5 */
393 if (strncasecmp("tcptype ", str, 8))
394 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
395
396 fast_forward(&str, 8);
397 skip_whitespace(&str);
398
399 for (i = 1; nr_ice_candidate_tcp_type_names[i]; ++i) {
400 if(!strncasecmp(nr_ice_candidate_tcp_type_names[i], str, strlen(nr_ice_candidate_tcp_type_names[i]))) {
401 bits->tcp_type=(nr_socket_tcp_type)i;
402 fast_forward(&str, strlen(nr_ice_candidate_tcp_type_names[i]));
403 break;
404 }
405 }
406
407 if (bits->tcp_type == 0)
408 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
409
410 if (*str && *str != ' ')
411 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
412 }
413 /* Ignore extensions per RFC 5245 S 15.1 */
414
415 _status=0;
416 abort:
417 free(connection_address);
418 free(rel_addr);
419 return(_status);
420}
421
422int
423nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr)
424{
425 int r,_status;
426 const char *orig = 0;
427 const char *str;
428
429 orig = str = attr;
430
431 if (!strncasecmp(str, "ice-ufrag:", 10)) {
432 fast_forward(&str, 10);
433 if (*str == '\0')
434 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
435
436 skip_whitespace(&str);
437 if (*str == '\0')
438 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
439
440 free(stream->ufrag);
441 if ((r=grab_token(&str, &stream->ufrag)))
442 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
443 }
444 else if (!strncasecmp(str, "ice-pwd:", 8)) {
445 fast_forward(&str, 8);
446 if (*str == '\0')
447 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
448
449 skip_whitespace(&str);
450 if (*str == '\0')
451 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
452
453 free(stream->pwd);
454 if ((r=grab_token(&str, &stream->pwd)))
455 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
456 }
457 else {
458 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
459 }
460
461 skip_whitespace(&str);
462
463 /* RFC 5245 grammar doesn't have an extension point for ice-pwd or
464 ice-ufrag: if there's anything left on the line, we treat it as bad. */
465 if (str[0] != '\0') {
466 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
467 }
468
469 _status=0;
470 abort:
471 if (_status) {
472 if (orig)
473 r_log(LOG_ICE,LOG_WARNING4,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig);
474 }
475
476 return(_status);
477}
478
479int
480nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int attr_ct)
481{
482 int r,_status;
483 int i;
484 const char *orig = 0;
485 const char *str;
486 char *component_id = 0;
487 char *connection_address = 0;
488 unsigned int port;
489 in_addr_t addr;
490 char *ice_option_tag = 0;
491
492 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
493 orig = str = attrs[i];
494
495 component_id = 0;
496 connection_address = 0;
497 ice_option_tag = 0;
498
499 if (!strncasecmp(str, "remote-candidates:", 18)) {
3
Taking true branch
8
Taking true branch
500 fast_forward(&str, 18);
501 skip_whitespace(&str);
502
503 while (*str != '\0') {
4
Loop condition is false. Execution continues on line 590
9
Assuming the condition is true
10
Loop condition is true. Entering loop body
504 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
505 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
506
507 if (*str == '\0')
19
Taking false branch
508 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
509
510 skip_whitespace(&str);
511 if (*str == '\0')
20
Assuming the condition is false
21
Taking false branch
512 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
513
514 if ((r=grab_token(&str, &connection_address)))
22
Assuming 'r' is 0
23
Taking false branch
515 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
516
517 if (*str == '\0')
24
Taking false branch
518 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
519
520 addr = inet_addr(connection_address);
521 if (addr == INADDR_NONE((in_addr_t) 0xffffffff))
25
Assuming 'addr' is not equal to INADDR_NONE
26
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')
27
Assuming the condition is false
28
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 (sscanf(str, "%u", &port) != 1)
29
Assuming the condition is false
529 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
530
531 if (port < 1 || port > 0x0FFFF)
30
Assuming 'port' is >= 1
31
Assuming 'port' is <= 65535
32
Taking false branch
532 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
533
534 skip_to_past_space(&str);
535
536 component_id = 0; /* prevent free */
537 free(connection_address);
33
Potential leak of memory pointed to by 'component_id'
538 connection_address = 0; /* prevent free */
539 }
540 }
541 else if (!strncasecmp(str, "ice-lite", 8)) {
542 pctx->peer_lite = 1;
543 pctx->controlling = 1;
544
545 fast_forward(&str, 8);
546 }
547 else if (!strncasecmp(str, "ice-mismatch", 12)) {
548 pctx->peer_ice_mismatch = 1;
549
550 fast_forward(&str, 12);
551 }
552 else if (!strncasecmp(str, "ice-ufrag:", 10)) {
553 fast_forward(&str, 10);
554 if (*str == '\0')
555 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
556
557 skip_whitespace(&str);
558 if (*str == '\0')
559 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
560 }
561 else if (!strncasecmp(str, "ice-pwd:", 8)) {
562 fast_forward(&str, 8);
563 if (*str == '\0')
564 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
565
566 skip_whitespace(&str);
567 if (*str == '\0')
568 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
569 }
570 else if (!strncasecmp(str, "ice-options:", 12)) {
571 fast_forward(&str, 12);
572 skip_whitespace(&str);
573
574 while (*str != '\0') {
575 if ((r=grab_token(&str, &ice_option_tag)))
576 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
577
578 skip_whitespace(&str);
579
580 //TODO: for now, just throw away; later put somewhere
581 free(ice_option_tag);
582
583 ice_option_tag = 0; /* prevent free */
584 }
585 }
586 else {
587 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
588 }
589
590 skip_whitespace(&str);
591
592 /* RFC 5245 grammar doesn't have an extension point for any of the
593 preceding attributes: if there's anything left on the line, we
594 treat it as bad data. */
595 if (str[0] != '\0') {
5
Taking false branch
596 ABORT(R_BAD_DATA)do { int _r=7; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
597 }
598 }
599
600 _status=0;
601 abort:
602 if (_status) {
603 if (orig)
604 r_log(LOG_ICE,LOG_WARNING4,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig);
605 }
606
607 free(connection_address);
608 free(component_id);
609 free(ice_option_tag);
610 return(_status);
611}
612