Bug Summary

File:root/firefox-clang/third_party/sipcc/sdp_base64.c
Warning:line 206, column 2
Value stored to 'line_count' is never read

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 sdp_base64.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -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/third_party/sipcc -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/sipcc -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/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D SIP_OS_LINUX -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/third_party/sipcc -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/third_party/sipcc -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -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=tautological-type-limit-compare -Wno-range-loop-analysis -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-unknown-warning-option -Wno-character-conversion -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -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/third_party/sipcc/sdp_base64.c
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "sdp_base64.h"
6
7/*
8 * Local definitions for Base64 to Raw table entries.
9 */
10#define INVALID_CHAR0xFF 0xFF /* Character not in supported Base64 set */
11#define WHITE_SPACE0xFE 0xFE /* Space, tab, newline, etc character */
12#define PADDING0xFD 0xFD /* The character '=' */
13
14#define PAD_CHAR'=' '=' /* The character '=' */
15
16/* Maximum length of a base64 encoded line */
17#define MAX_BASE64_LINE_LENGTH76 76
18
19/*
20 * base64_result_table
21 * String table for translating base64 error codes into human
22 * understanable strings.
23 */
24char *base64_result_table[BASE64_RESULT_MAX] =
25{
26 "Base64 successful",
27 "Base64 Buffer Overrun",
28 "Base64 Bad Data",
29 "Base64 Bad Padding",
30 "Base64 Bad Block Size"
31};
32
33/*
34 * base64_to_raw_table
35 * Heart of the Base64 decoding algorithm. Lookup table to convert
36 * the Base64 characters into their specified representative values.
37 * Invalid characters are marked with 0xFF, white space characters
38 * are marked with 0xFE, and the special pading character is marked
39 * with 0xFD.
40 */
41unsigned char base64_to_raw_table[128] =
42{
43 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, /* 0-9 */
44 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 10-19 */
45 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 20-29 */
46 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 30-39 */
47 0xFF, 0xFF, 0xFF, 62, 0xFF, 0xFF, 0xFF, 63, 52, 53, /* 40-49 */
48 54, 55, 56, 57, 58, 59, 60, 61, 0xFF, 0xFF, /* 50-59 */
49 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, /* 60-69 */
50 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70-79 */
51 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80-89 */
52 25, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 26, 27, 28, /* 90-99 */
53 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */
54 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */
55 49, 50, 51, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF /* 120-127 */
56};
57
58unsigned char raw_to_base64_table[64] =
59{
60 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0-9 */
61 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */
62 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20-29 */
63 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30-39 */
64 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', /* 40-49 */
65 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 50-59 */
66 '8', '9', '+', '/' /* 60-63 */
67};
68
69/*
70 * base64_encode_size_bytes
71 *
72 * DESCRIPTION
73 * Estimates the size of buffer required for holding the result of
74 * encoding data of size raw_size_bytes.
75 *
76 * PARAMETERS
77 * raw_size_bytes = Estimated size of the un-encoded data in bytes.
78 *
79 * RETURN VALUE
80 * The size of destination buffer to use for encoding in bytes.
81 */
82int base64_est_encode_size_bytes (int raw_size_bytes)
83{
84 int length;
85
86 /*
87 * Find the number of bytes needed to represent the data
88 * using a 4/3 expansion ratio. That result must be
89 * rounded to the next higher multiple of four to account
90 * for padding. Then add in a term to account for any '\n's
91 * added.
92 */
93 length = ((((raw_size_bytes * 4 + 2)/ 3) + 3) & ~(0x3)) +
94 raw_size_bytes / MAX_BASE64_LINE_LENGTH76;
95
96 return length;
97}
98
99/*
100 * base64_decode_size_bytes
101 *
102 * DESCRIPTION
103 * Estimates the size of buffer required for holding the result of
104 * decoding data of size base64_size_bytes.
105 *
106 * PARAMETERS
107 * base64_size_bytes = Estimated size of the Base64 data in bytes.
108 *
109 * RETURN VALUE
110 * The size of destination buffer to use for decoding in bytes.
111 */
112int base64_est_decode_size_bytes (int base64_size_bytes)
113{
114 int length;
115
116 length = (base64_size_bytes * 3 + 3) / 4;
117 return length;
118}
119
120/*
121 * base64_encode
122 *
123 * DESCRIPTION
124 * Encode data pointed to by src into the buffer pointer to by dest
125 * using the Base64 algorithm.
126 *
127 * NOTE: No trailing '\n' character will be added.
128 *
129 * NOTE: As per specification, '\n' will be placed every 76 chars.
130 *
131 * PARAMETERS
132 * src = Pointer to the raw data to base64 encode.
133 * src_bytes = The number of bytes in the src buffer to encode.
134 * dest = Pointer to the destination buffer where the converted data
135 * will reside when complete.
136 * dest_bytes = Initially holds the size of the destination buffer
137 * but at completion holds the number of bytes converted.
138 *
139 * RETURN VALUE
140 * base64_success if the buffer was successfully converted, the
141 * appropriate error code otherwise.
142 *
143 * The dest parameter holds the converted data.
144 *
145 * The dest_bytes parameter holds the actual number of bytes converted.
146 */
147base64_result_t base64_encode(unsigned char *src, int src_bytes, unsigned char *dest, int *dest_bytes)
148{
149 int i, j=0;
150 int line_count = 0;
151 unsigned char index; /* index into base64 lookup table */
152 int smax = src_bytes-2; /* only do full multiples of 3 */
153 int dmax = *dest_bytes; /* destination maximum */
154
155 *dest_bytes = 0;
156
157 /* Do full groups. Base64 must be done in blocks of 3 src bytes */
158 for (i=0; i<smax; i+=3) {
159 /* Check to see if newline should be injected */
160 if (line_count>=MAX_BASE64_LINE_LENGTH76) {
161 if (j<dmax){
162 dest[j++] = '\n';
163 } else {
164 return BASE64_BUFFER_OVERRUN;
165 }
166 line_count = 0;
167 }
168
169 line_count += 4;
170
171 if ((j+3) < dmax) {
172
173 /* Find mapping of upper 6 bits */
174 index = (src[i] >> 2) & 0x3F;
175 dest[j++] = raw_to_base64_table[index];
176
177 /* bottom 2 bits of first word, high 4 bits of second word */
178 index = ((src[i] << 4) & 0x30) | ((src[i+1] >> 4) & 0x0F);
179 dest[j++] = raw_to_base64_table[index];
180
181 /* bottom 4 bits of second word, high 2 bits of third word */
182 index = ((src[i+1] << 2) & 0x3C) | ((src[i+2] >> 6) & 0x03);
183 dest[j++] = raw_to_base64_table[index];
184
185 /* bottom 6 bits of third word */
186 index = src[i+2] & 0x3F;
187 dest[j++] = raw_to_base64_table[index];
188 } else {
189 return BASE64_BUFFER_OVERRUN;
190 }
191 }
192
193 /* Check to see if any more work must be done */
194 if (i<src_bytes) {
195
196 /* Check to see if a newline should be output */
197 if (line_count>=MAX_BASE64_LINE_LENGTH76) {
198 if (j<dmax){
199 dest[j++] = '\n';
200 } else {
201 return BASE64_BUFFER_OVERRUN;
202 }
203 line_count = 0;
204 }
205
206 line_count += 4;
Value stored to 'line_count' is never read
207
208 /* Must fill another quantum */
209 if (j+4>dmax) {
210 /* No room left in output buffer! */
211 return BASE64_BUFFER_OVERRUN;
212 }
213
214 /* Find mapping of upper 6 bits */
215 index = (src[i] >> 2) & 0x3F;
216 dest[j++] = raw_to_base64_table[index];
217
218 /* check for another stragler */
219 if ((i+1)<src_bytes) {
220 /* bottom 2 bits of first word, high 4 bits of second word */
221 index = ((src[i] << 4) & 0x30) | ((src[i+1] >> 4) & 0x0F);
222 dest[j++] = raw_to_base64_table[index];
223
224 /* bottom 4 bits of second word */
225 index = (src[i+1] << 2) & 0x3C;
226 dest[j++] = raw_to_base64_table[index];
227 dest[j++] = PAD_CHAR'=';
228 } else {
229 /* bottom 2 bits of first word */
230 index = (src[i] << 4) & 0x30;
231 dest[j++] = raw_to_base64_table[index];
232 dest[j++] = PAD_CHAR'=';
233 dest[j++] = PAD_CHAR'=';
234 }
235 }
236
237 *dest_bytes = j;
238
239 return BASE64_SUCCESS;
240}
241
242unsigned char base64_decode_get_raw(unsigned char index)
243{
244 /* only have 128 values, MSB must not be set! */
245 if (index >= 128) {
246 return INVALID_CHAR0xFF;
247 }
248 return base64_to_raw_table[index];
249}
250
251/*
252 * base64_decode
253 *
254 * DESCRIPTION
255 * Decode data pointed to by src into the buffer pointer to by dest
256 * using the Base64 algorithm.
257 *
258 * PARAMETERS
259 * src = Pointer to the Base64 data to decode.
260 * src_bytes = The number of bytes in the src buffer to decode.
261 * dest = Pointer to the destination buffer where the converted data
262 * will reside when complete.
263 * dest_bytes = Initially holds the size of the destination buffer
264 * but at completion holds the number of bytes converted.
265 *
266 * RETURN VALUE
267 * base64_success if the buffer was successfully converted, the
268 * appropriate error code otherwise.
269 *
270 * The dest parameter holds the converted data.
271 *
272 * The dest_bytes parameter holds the actual number of bytes converted.
273 */
274base64_result_t base64_decode(unsigned char *src, int src_bytes, unsigned char *dest, int *dest_bytes)
275{
276 int i, j = 0;
277 int sindex = 0; /* Current NON-whitespace source
278 * index */
279 int pad_count=0; /* Number of padding characters
280 * encountered */
281 int dest_size_bytes = *dest_bytes; /* Save size of destination buffer */
282 unsigned char cindex; /* The current Base64 character to
283 * process */
284 unsigned char val; /* The value of the current Base64
285 * character */
286
287 *dest_bytes = 0;
288
289 for (i=0; i<src_bytes; i++) {
290 cindex = src[i];
291
292 val = base64_decode_get_raw(cindex);
293 if (val == INVALID_CHAR0xFF) {
294 /* Invalid base64 character */
295 return BASE64_BAD_DATA;
296 }
297
298 if (val == WHITE_SPACE0xFE) {
299 /* Ignore white space */
300 continue;
301 }
302
303 if (val == PADDING0xFD) {
304 /* we must be at the end-finish up */
305 pad_count++;
306 if (++i<src_bytes) {
307 /* can have up to 2 pad chars */
308 if (base64_decode_get_raw(src[i]) != PADDING0xFD) {
309 return BASE64_BAD_PADDING;
310 }
311
312 if (++i<src_bytes) {
313 /* should not have any more padding! */
314 return BASE64_BAD_PADDING;
315 }
316
317 pad_count++;
318 }
319
320 /* DONE! */
321 break;
322 }
323
324 /* Determine which portion of the 3 bytes this data will fill */
325 switch (sindex & 0x3) {
326 case 0:
327 /* Fill upper 6 bits */
328 if (j<dest_size_bytes) {
329 dest[j] = val << 2;
330 } else {
331 return BASE64_BUFFER_OVERRUN;
332 }
333 break;
334 case 1:
335 /* Fill Bottom 2 bits */
336 dest[j++] |= val >> 4;
337
338 if (j<dest_size_bytes) {
339 /* Fill Top 4 bits */
340 dest[j] = (val << 4) & 0xF0;
341 } else {
342 /*
343 * Check to see if there is any more data present.
344 * Next base64 character MUST be a pad character and
345 * the rest of this data MUST be zero.
346 *
347 * If this is not the end of data then a buffer overrun
348 * has occurred
349 */
350 if ((val & 0x0F) ||
351 (i+1>=src_bytes) ||
352 (base64_decode_get_raw(src[i+1]) != PADDING0xFD)) {
353 return BASE64_BUFFER_OVERRUN;
354 }
355 }
356 break;
357 case 2:
358 /* Fill Bottom 4 bits */
359 dest[j++] |= val >> 2;
360
361 if (j<dest_size_bytes) {
362 /* Fill Top 2 bits */
363 dest[j] = (val << 6) & 0xC0;
364 } else {
365 /*
366 * Check to see if there is any more data present.
367 * Next base64 character MUST be a pad character and
368 * the rest of this data MUST be zero.
369 *
370 * If this is not the end of data then a buffer overrun
371 * has occurred
372 */
373 if ((val & 0x03) ||
374 (i+1>=src_bytes) ||
375 (base64_decode_get_raw(src[i+1]) != PADDING0xFD)) {
376 return BASE64_BUFFER_OVERRUN;
377 }
378 }
379 break;
380 case 3:
381 /*
382 * No need to check for overrun here since the
383 * previous case was already checked. If another
384 * group is present then case 0 will check again.
385 */
386
387 /* Fill Bottom 6 bits */
388 dest[j++] |= val;
389 break;
390 }
391 sindex++;
392 }
393
394 /* Check length for multiple of 3 bytes */
395 if (((j + pad_count)% 3) != 0) {
396 return BASE64_BAD_BLOCK_SIZE;
397 }
398
399 /* Save off the number of bytes converted */
400 *dest_bytes = j;
401
402 return BASE64_SUCCESS;
403}