Bug Summary

File:root/firefox-clang/media/ffvpx/libavutil/avsscanf.c
Warning:line 884, column 37
Although the value stored to 'c' is used in the enclosing expression, the value is never actually read from 'c'

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 avsscanf.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/media/ffvpx/libavutil -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavutil -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -include libavutil_visibility.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D HAVE_AV_CONFIG_H -D ASSERT_LEVEL=2 -I /root/firefox-clang/media/ffvpx/libavutil -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavutil -I /root/firefox-clang/third_party/khronos/vulkan-headers/include -I /root/firefox-clang/media/mozva -I /root/firefox-clang/media/ffvpx -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 -Wno-parentheses -Wno-pointer-sign -Wno-sign-compare -Wno-switch -Wno-type-limits -Wno-unused-function -Wno-deprecated-declarations -Wno-absolute-value -Wno-incompatible-pointer-types -Wno-string-conversion -Wno-visibility -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/media/ffvpx/libavutil/avsscanf.c
1/*
2 * Copyright (c) 2005-2014 Rich Felker, et al.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include <errno(*__errno_location ()).h>
25#include <limits.h>
26#include <math.h>
27#include <stdarg.h>
28#include <stddef.h>
29#include <stdint.h>
30#include <stdio.h>
31#include <string.h>
32#include <float.h>
33
34#include "avstring.h"
35#include "libm.h"
36
37typedef struct FFFILE {
38 size_t buf_size;
39 unsigned char *buf;
40 unsigned char *rpos, *rend;
41 unsigned char *shend;
42 ptrdiff_t shlim, shcnt;
43 void *cookie;
44 size_t (*read)(struct FFFILE *, unsigned char *, size_t);
45} FFFILE;
46
47#define SIZE_hh-2 -2
48#define SIZE_h-1 -1
49#define SIZE_def0 0
50#define SIZE_l1 1
51#define SIZE_L2 2
52#define SIZE_ll3 3
53
54#define shcnt(f)((f)->shcnt + ((f)->rpos - (f)->buf)) ((f)->shcnt + ((f)->rpos - (f)->buf))
55
56static int fftoread(FFFILE *f)
57{
58 f->rpos = f->rend = f->buf + f->buf_size;
59 return 0;
60}
61
62static size_t ffstring_read(FFFILE *f, unsigned char *buf, size_t len)
63{
64 char *src = f->cookie;
65 size_t k = len+256;
66 char *end = memchr(src, 0, k);
67
68 if (end) k = end-src;
69 if (k < len) len = k;
70 memcpy(buf, src, len);
71 f->rpos = (void *)(src+len);
72 f->rend = (void *)(src+k);
73 f->cookie = src+k;
74
75 return len;
76}
77
78static int ffuflow(FFFILE *f)
79{
80 unsigned char c;
81 if (!fftoread(f) && f->read(f, &c, 1)==1) return c;
82 return EOF(-1);
83}
84
85static void ffshlim(FFFILE *f, ptrdiff_t lim)
86{
87 f->shlim = lim;
88 f->shcnt = f->buf - f->rpos;
89 /* If lim is nonzero, rend must be a valid pointer. */
90 if (lim && f->rend - f->rpos > lim)
91 f->shend = f->rpos + lim;
92 else
93 f->shend = f->rend;
94}
95
96static int ffshgetc(FFFILE *f)
97{
98 int c;
99 ptrdiff_t cnt = shcnt(f)((f)->shcnt + ((f)->rpos - (f)->buf));
100 if (f->shlim && cnt >= f->shlim || (c=ffuflow(f)) < 0) {
101 f->shcnt = f->buf - f->rpos + cnt;
102 f->shend = 0;
103 return EOF(-1);
104 }
105 cnt++;
106 if (f->shlim && f->rend - f->rpos > f->shlim - cnt)
107 f->shend = f->rpos + (f->shlim - cnt);
108 else
109 f->shend = f->rend;
110 f->shcnt = f->buf - f->rpos + cnt;
111 if (f->rpos[-1] != c) f->rpos[-1] = c;
112 return c;
113}
114
115#define shlim(f, lim)ffshlim((f), (lim)) ffshlim((f), (lim))
116#define shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc(f))
117#define shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0) ((f)->shend ? (void)(f)->rpos-- : (void)0)
118
119static const unsigned char table[] = { -1,
120 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
121 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
122 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
123 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
124 -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
125 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
126 -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
127 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
128 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
129 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
130 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
131 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
132 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
133 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
134 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
135 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
136};
137
138static unsigned long long ffintscan(FFFILE *f, unsigned base, int pok, unsigned long long lim)
139{
140 const unsigned char *val = table+1;
141 int c, neg=0;
142 unsigned x;
143 unsigned long long y;
144 if (base > 36 || base == 1) {
145 errno(*__errno_location ()) = EINVAL22;
146 return 0;
147 }
148 while (av_isspace((c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)));
149 if (c=='+' || c=='-') {
150 neg = -(c=='-');
151 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
152 }
153 if ((base == 0 || base == 16) && c=='0') {
154 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
155 if ((c|32)=='x') {
156 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
157 if (val[c]>=16) {
158 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
159 if (pok) shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
160 else shlim(f, 0)ffshlim((f), (0));
161 return 0;
162 }
163 base = 16;
164 } else if (base == 0) {
165 base = 8;
166 }
167 } else {
168 if (base == 0) base = 10;
169 if (val[c] >= base) {
170 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
171 shlim(f, 0)ffshlim((f), (0));
172 errno(*__errno_location ()) = EINVAL22;
173 return 0;
174 }
175 }
176 if (base == 10) {
177 for (x=0; c-'0'<10U && x<=UINT_MAX(2147483647 *2U +1U)/10-1; c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)
178 x = x*10 + (c-'0');
179 for (y=x; c-'0'<10U && y<=ULLONG_MAX(9223372036854775807LL*2ULL+1ULL)/10 && 10*y<=ULLONG_MAX(9223372036854775807LL*2ULL+1ULL)-(c-'0'); c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)
180 y = y*10 + (c-'0');
181 if (c-'0'>=10U) goto done;
182 } else if (!(base & base-1)) {
183 int bs = "\0\1\2\4\7\3\6\5"[(0x17*base)>>5&7];
184 for (x=0; val[c]<base && x<=UINT_MAX(2147483647 *2U +1U)/32; c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)
185 x = x<<bs | val[c];
186 for (y=x; val[c]<base && y<=ULLONG_MAX(9223372036854775807LL*2ULL+1ULL)>>bs; c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)
187 y = y<<bs | val[c];
188 } else {
189 for (x=0; val[c]<base && x<=UINT_MAX(2147483647 *2U +1U)/36-1; c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)
190 x = x*base + val[c];
191 for (y=x; val[c]<base && y<=ULLONG_MAX(9223372036854775807LL*2ULL+1ULL)/base && base*y<=ULLONG_MAX(9223372036854775807LL*2ULL+1ULL)-val[c]; c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)
192 y = y*base + val[c];
193 }
194 if (val[c]<base) {
195 for (; val[c]<base; c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
);
196 errno(*__errno_location ()) = ERANGE34;
197 y = lim;
198 if (lim&1) neg = 0;
199 }
200done:
201 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
202 if (y>=lim) {
203 if (!(lim&1) && !neg) {
204 errno(*__errno_location ()) = ERANGE34;
205 return lim-1;
206 } else if (y>lim) {
207 errno(*__errno_location ()) = ERANGE34;
208 return lim;
209 }
210 }
211 return (y^neg)-neg;
212}
213
214static long long scanexp(FFFILE *f, int pok)
215{
216 int c;
217 int x;
218 long long y;
219 int neg = 0;
220
221 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
222 if (c=='+' || c=='-') {
223 neg = (c=='-');
224 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
225 if (c-'0'>=10U && pok) shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
226 }
227 if (c-'0'>=10U) {
228 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
229 return LLONG_MIN(-9223372036854775807LL -1LL);
230 }
231 for (x=0; c-'0'<10U && x<INT_MAX2147483647/10; c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)
232 x = 10*x + (c-'0');
233 for (y=x; c-'0'<10U && y<LLONG_MAX9223372036854775807LL/100; c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)
234 y = 10*y + (c-'0');
235 for (; c-'0'<10U; c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
);
236 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
237 return neg ? -y : y;
238}
239
240#define LD_B1B_DIG2 2
241#define LD_B1B_MAX9007199, 254740991 9007199, 254740991
242#define KMAX128 128
243#define MASK(128 -1) (KMAX128-1)
244
245static double decfloat(FFFILE *f, int c, int bits, int emin, int sign, int pok)
246{
247 uint32_t x[KMAX128];
248 static const uint32_t th[] = { LD_B1B_MAX9007199, 254740991 };
249 int i, j, k, a, z;
250 long long lrp=0, dc=0;
251 long long e10=0;
252 int lnz = 0;
253 int gotdig = 0, gotrad = 0;
254 int rp;
255 int e2;
256 int emax = -emin-bits+3;
257 int denormal = 0;
258 double y;
259 double frac=0;
260 double bias=0;
261 static const int p10s[] = { 10, 100, 1000, 10000,
262 100000, 1000000, 10000000, 100000000 };
263
264 j=0;
265 k=0;
266
267 /* Don't let leading zeros consume buffer space */
268 for (; c=='0'; c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
) gotdig=1;
269 if (c=='.') {
270 gotrad = 1;
271 for (c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
; c=='0'; c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
) gotdig=1, lrp--;
272 }
273
274 x[0] = 0;
275 for (; c-'0'<10U || c=='.'; c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
) {
276 if (c == '.') {
277 if (gotrad) break;
278 gotrad = 1;
279 lrp = dc;
280 } else if (k < KMAX128-3) {
281 dc++;
282 if (c!='0') lnz = dc;
283 if (j) x[k] = x[k]*10 + c-'0';
284 else x[k] = c-'0';
285 if (++j==9) {
286 k++;
287 j=0;
288 }
289 gotdig=1;
290 } else {
291 dc++;
292 if (c!='0') {
293 lnz = (KMAX128-4)*9;
294 x[KMAX128-4] |= 1;
295 }
296 }
297 }
298 if (!gotrad) lrp=dc;
299
300 if (gotdig && (c|32)=='e') {
301 e10 = scanexp(f, pok);
302 if (e10 == LLONG_MIN(-9223372036854775807LL -1LL)) {
303 if (pok) {
304 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
305 } else {
306 shlim(f, 0)ffshlim((f), (0));
307 return 0;
308 }
309 e10 = 0;
310 }
311 lrp += e10;
312 } else if (c>=0) {
313 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
314 }
315 if (!gotdig) {
316 errno(*__errno_location ()) = EINVAL22;
317 shlim(f, 0)ffshlim((f), (0));
318 return 0;
319 }
320
321 /* Handle zero specially to avoid nasty special cases later */
322 if (!x[0]) return sign * 0.0;
323
324 /* Optimize small integers (w/no exponent) and over/under-flow */
325 if (lrp==dc && dc<10 && (bits>30 || x[0]>>bits==0))
326 return sign * (double)x[0];
327 if (lrp > -emin/2) {
328 errno(*__errno_location ()) = ERANGE34;
329 return sign * DBL_MAX1.7976931348623157e+308 * DBL_MAX1.7976931348623157e+308;
330 }
331 if (lrp < emin-2*DBL_MANT_DIG53) {
332 errno(*__errno_location ()) = ERANGE34;
333 return sign * DBL_MIN2.2250738585072014e-308 * DBL_MIN2.2250738585072014e-308;
334 }
335
336 /* Align incomplete final B1B digit */
337 if (j) {
338 for (; j<9; j++) x[k]*=10;
339 k++;
340 j=0;
341 }
342
343 a = 0;
344 z = k;
345 e2 = 0;
346 rp = lrp;
347
348 /* Optimize small to mid-size integers (even in exp. notation) */
349 if (lnz<9 && lnz<=rp && rp < 18) {
350 int bitlim;
351 if (rp == 9) return sign * (double)x[0];
352 if (rp < 9) return sign * (double)x[0] / p10s[8-rp];
353 bitlim = bits-3*(int)(rp-9);
354 if (bitlim>30 || x[0]>>bitlim==0)
355 return sign * (double)x[0] * p10s[rp-10];
356 }
357
358 /* Drop trailing zeros */
359 for (; !x[z-1]; z--);
360
361 /* Align radix point to B1B digit boundary */
362 if (rp % 9) {
363 int rpm9 = rp>=0 ? rp%9 : rp%9+9;
364 int p10 = p10s[8-rpm9];
365 uint32_t carry = 0;
366 for (k=a; k!=z; k++) {
367 uint32_t tmp = x[k] % p10;
368 x[k] = x[k]/p10 + carry;
369 carry = 1000000000/p10 * tmp;
370 if (k==a && !x[k]) {
371 a = (a+1 & MASK(128 -1));
372 rp -= 9;
373 }
374 }
375 if (carry) x[z++] = carry;
376 rp += 9-rpm9;
377 }
378
379 /* Upscale until desired number of bits are left of radix point */
380 while (rp < 9*LD_B1B_DIG2 || (rp == 9*LD_B1B_DIG2 && x[a]<th[0])) {
381 uint32_t carry = 0;
382 e2 -= 29;
383 for (k=(z-1 & MASK(128 -1)); ; k=(k-1 & MASK(128 -1))) {
384 uint64_t tmp = ((uint64_t)x[k] << 29) + carry;
385 if (tmp > 1000000000) {
386 carry = tmp / 1000000000;
387 x[k] = tmp % 1000000000;
388 } else {
389 carry = 0;
390 x[k] = tmp;
391 }
392 if (k==(z-1 & MASK(128 -1)) && k!=a && !x[k]) z = k;
393 if (k==a) break;
394 }
395 if (carry) {
396 rp += 9;
397 a = (a-1 & MASK(128 -1));
398 if (a == z) {
399 z = (z-1 & MASK(128 -1));
400 x[z-1 & MASK(128 -1)] |= x[z];
401 }
402 x[a] = carry;
403 }
404 }
405
406 /* Downscale until exactly number of bits are left of radix point */
407 for (;;) {
408 uint32_t carry = 0;
409 int sh = 1;
410 for (i=0; i<LD_B1B_DIG2; i++) {
411 k = (a+i & MASK(128 -1));
412 if (k == z || x[k] < th[i]) {
413 i=LD_B1B_DIG2;
414 break;
415 }
416 if (x[a+i & MASK(128 -1)] > th[i]) break;
417 }
418 if (i==LD_B1B_DIG2 && rp==9*LD_B1B_DIG2) break;
419 /* FIXME: find a way to compute optimal sh */
420 if (rp > 9+9*LD_B1B_DIG2) sh = 9;
421 e2 += sh;
422 for (k=a; k!=z; k=(k+1 & MASK(128 -1))) {
423 uint32_t tmp = x[k] & (1<<sh)-1;
424 x[k] = (x[k]>>sh) + carry;
425 carry = (1000000000>>sh) * tmp;
426 if (k==a && !x[k]) {
427 a = (a+1 & MASK(128 -1));
428 i--;
429 rp -= 9;
430 }
431 }
432 if (carry) {
433 if ((z+1 & MASK(128 -1)) != a) {
434 x[z] = carry;
435 z = (z+1 & MASK(128 -1));
436 } else x[z-1 & MASK(128 -1)] |= 1;
437 }
438 }
439
440 /* Assemble desired bits into floating point variable */
441 for (y=i=0; i<LD_B1B_DIG2; i++) {
442 if ((a+i & MASK(128 -1))==z) x[(z=(z+1 & MASK(128 -1)))-1] = 0;
443 y = 1000000000.0L * y + x[a+i & MASK(128 -1)];
444 }
445
446 y *= sign;
447
448 /* Limit precision for denormal results */
449 if (bits > DBL_MANT_DIG53+e2-emin) {
450 bits = DBL_MANT_DIG53+e2-emin;
451 if (bits<0) bits=0;
452 denormal = 1;
453 }
454
455 /* Calculate bias term to force rounding, move out lower bits */
456 if (bits < DBL_MANT_DIG53) {
457 bias = copysign(scalbn(1, 2*DBL_MANT_DIG53-bits-1), y);
458 frac = fmod(y, scalbn(1, DBL_MANT_DIG53-bits));
459 y -= frac;
460 y += bias;
461 }
462
463 /* Process tail of decimal input so it can affect rounding */
464 if ((a+i & MASK(128 -1)) != z) {
465 uint32_t t = x[a+i & MASK(128 -1)];
466 if (t < 500000000 && (t || (a+i+1 & MASK(128 -1)) != z))
467 frac += 0.25*sign;
468 else if (t > 500000000)
469 frac += 0.75*sign;
470 else if (t == 500000000) {
471 if ((a+i+1 & MASK(128 -1)) == z)
472 frac += 0.5*sign;
473 else
474 frac += 0.75*sign;
475 }
476 if (DBL_MANT_DIG53-bits >= 2 && !fmod(frac, 1))
477 frac++;
478 }
479
480 y += frac;
481 y -= bias;
482
483 if ((e2+DBL_MANT_DIG53 & INT_MAX2147483647) > emax-5) {
484 if (fabs(y) >= pow(2, DBL_MANT_DIG53)) {
485 if (denormal && bits==DBL_MANT_DIG53+e2-emin)
486 denormal = 0;
487 y *= 0.5;
488 e2++;
489 }
490 if (e2+DBL_MANT_DIG53>emax || (denormal && frac))
491 errno(*__errno_location ()) = ERANGE34;
492 }
493
494 return scalbn(y, e2);
495}
496
497static double hexfloat(FFFILE *f, int bits, int emin, int sign, int pok)
498{
499 uint32_t x = 0;
500 double y = 0;
501 double scale = 1;
502 double bias = 0;
503 int gottail = 0, gotrad = 0, gotdig = 0;
504 long long rp = 0;
505 long long dc = 0;
506 long long e2 = 0;
507 int d;
508 int c;
509
510 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
511
512 /* Skip leading zeros */
513 for (; c=='0'; c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)
514 gotdig = 1;
515
516 if (c=='.') {
517 gotrad = 1;
518 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
519 /* Count zeros after the radix point before significand */
520 for (rp=0; c=='0'; c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
, rp--) gotdig = 1;
521 }
522
523 for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
) {
524 if (c=='.') {
525 if (gotrad) break;
526 rp = dc;
527 gotrad = 1;
528 } else {
529 gotdig = 1;
530 if (c > '9') d = (c|32)+10-'a';
531 else d = c-'0';
532 if (dc<8) {
533 x = x*16 + d;
534 } else if (dc < DBL_MANT_DIG53/4+1) {
535 y += d*(scale/=16);
536 } else if (d && !gottail) {
537 y += 0.5*scale;
538 gottail = 1;
539 }
540 dc++;
541 }
542 }
543 if (!gotdig) {
544 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
545 if (pok) {
546 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
547 if (gotrad) shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
548 } else {
549 shlim(f, 0)ffshlim((f), (0));
550 }
551 return sign * 0.0;
552 }
553 if (!gotrad) rp = dc;
554 while (dc<8) x *= 16, dc++;
555 if ((c|32)=='p') {
556 e2 = scanexp(f, pok);
557 if (e2 == LLONG_MIN(-9223372036854775807LL -1LL)) {
558 if (pok) {
559 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
560 } else {
561 shlim(f, 0)ffshlim((f), (0));
562 return 0;
563 }
564 e2 = 0;
565 }
566 } else {
567 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
568 }
569 e2 += 4*rp - 32;
570
571 if (!x) return sign * 0.0;
572 if (e2 > -emin) {
573 errno(*__errno_location ()) = ERANGE34;
574 return sign * DBL_MAX1.7976931348623157e+308 * DBL_MAX1.7976931348623157e+308;
575 }
576 if (e2 < emin-2*DBL_MANT_DIG53) {
577 errno(*__errno_location ()) = ERANGE34;
578 return sign * DBL_MIN2.2250738585072014e-308 * DBL_MIN2.2250738585072014e-308;
579 }
580
581 while (x < 0x80000000) {
582 if (y>=0.5) {
583 x += x + 1;
584 y += y - 1;
585 } else {
586 x += x;
587 y += y;
588 }
589 e2--;
590 }
591
592 if (bits > 32+e2-emin) {
593 bits = 32+e2-emin;
594 if (bits<0) bits=0;
595 }
596
597 if (bits < DBL_MANT_DIG53)
598 bias = copysign(scalbn(1, 32+DBL_MANT_DIG53-bits-1), sign);
599
600 if (bits<32 && y && !(x&1)) x++, y=0;
601
602 y = bias + sign*(double)x + sign*y;
603 y -= bias;
604
605 if (!y) errno(*__errno_location ()) = ERANGE34;
606
607 return scalbn(y, e2);
608}
609
610static double fffloatscan(FFFILE *f, int prec, int pok)
611{
612 int sign = 1;
613 size_t i;
614 int bits;
615 int emin;
616 int c;
617
618 switch (prec) {
619 case 0:
620 bits = FLT_MANT_DIG24;
621 emin = FLT_MIN_EXP(-125)-bits;
622 break;
623 case 1:
624 bits = DBL_MANT_DIG53;
625 emin = DBL_MIN_EXP(-1021)-bits;
626 break;
627 case 2:
628 bits = DBL_MANT_DIG53;
629 emin = DBL_MIN_EXP(-1021)-bits;
630 break;
631 default:
632 return 0;
633 }
634
635 while (av_isspace((c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)));
636
637 if (c=='+' || c=='-') {
638 sign -= 2*(c=='-');
639 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
640 }
641
642 for (i=0; i<8 && (c|32)=="infinity"[i]; i++)
643 if (i<7) c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
644 if (i==3 || i==8 || (i>3 && pok)) {
645 if (i!=8) {
646 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
647 if (pok) for (; i>3; i--) shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
648 }
649 return sign * INFINITY(__builtin_inff());
650 }
651 if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++)
652 if (i<2) c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
653 if (i==3) {
654 if (shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
!= '(') {
655 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
656 return NAN(__builtin_nanf(""));
657 }
658 for (i=1; ; i++) {
659 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
660 if (c-'0'<10U || c-'A'<26U || c-'a'<26U || c=='_')
661 continue;
662 if (c==')') return NAN(__builtin_nanf(""));
663 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
664 if (!pok) {
665 errno(*__errno_location ()) = EINVAL22;
666 shlim(f, 0)ffshlim((f), (0));
667 return 0;
668 }
669 while (i--) shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
670 return NAN(__builtin_nanf(""));
671 }
672 }
673
674 if (i) {
675 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
676 errno(*__errno_location ()) = EINVAL22;
677 shlim(f, 0)ffshlim((f), (0));
678 return 0;
679 }
680
681 if (c=='0') {
682 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
683 if ((c|32) == 'x')
684 return hexfloat(f, bits, emin, sign, pok);
685 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
686 c = '0';
687 }
688
689 return decfloat(f, c, bits, emin, sign, pok);
690}
691
692static void *arg_n(va_list ap, unsigned int n)
693{
694 void *p;
695 unsigned int i;
696 va_list ap2;
697 va_copy(ap2, ap)__builtin_va_copy(ap2, ap);
698 for (i=n; i>1; i--) va_arg(ap2, void *)__builtin_va_arg(ap2, void *);
699 p = va_arg(ap2, void *)__builtin_va_arg(ap2, void *);
700 va_end(ap2)__builtin_va_end(ap2);
701 return p;
702}
703
704static void store_int(void *dest, int size, unsigned long long i)
705{
706 if (!dest) return;
707 switch (size) {
708 case SIZE_hh-2:
709 *(char *)dest = i;
710 break;
711 case SIZE_h-1:
712 *(short *)dest = i;
713 break;
714 case SIZE_def0:
715 *(int *)dest = i;
716 break;
717 case SIZE_l1:
718 *(long *)dest = i;
719 break;
720 case SIZE_ll3:
721 *(long long *)dest = i;
722 break;
723 }
724}
725
726static int ff_vfscanf(FFFILE *f, const char *fmt, va_list ap)
727{
728 int width;
729 int size;
730 int base;
731 const unsigned char *p;
732 int c, t;
733 char *s;
734 void *dest=NULL((void*)0);
735 int invert;
736 int matches=0;
737 unsigned long long x;
738 double y;
739 ptrdiff_t pos = 0;
740 unsigned char scanset[257];
741 size_t i;
742
743 for (p=(const unsigned char *)fmt; *p; p++) {
744
745 if (av_isspace(*p)) {
746 while (av_isspace(p[1])) p++;
747 shlim(f, 0)ffshlim((f), (0));
748 while (av_isspace(shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
));
749 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
750 pos += shcnt(f)((f)->shcnt + ((f)->rpos - (f)->buf));
751 continue;
752 }
753 if (*p != '%' || p[1] == '%') {
754 shlim(f, 0)ffshlim((f), (0));
755 if (*p == '%') {
756 p++;
757 while (av_isspace((c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)));
758 } else {
759 c = shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
;
760 }
761 if (c!=*p) {
762 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
763 if (c<0) goto input_fail;
764 goto match_fail;
765 }
766 pos += shcnt(f)((f)->shcnt + ((f)->rpos - (f)->buf));
767 continue;
768 }
769
770 p++;
771 if (*p=='*') {
772 dest = 0; p++;
773 } else if (av_isdigit(*p) && p[1]=='$') {
774 dest = arg_n(ap, *p-'0'); p+=2;
775 } else {
776 dest = va_arg(ap, void *)__builtin_va_arg(ap, void *);
777 }
778
779 for (width=0; av_isdigit(*p); p++) {
780 width = 10*width + *p - '0';
781 }
782
783 if (*p=='m') {
784 s = 0;
785 p++;
786 }
787
788 size = SIZE_def0;
789 switch (*p++) {
790 case 'h':
791 if (*p == 'h') p++, size = SIZE_hh-2;
792 else size = SIZE_h-1;
793 break;
794 case 'l':
795 if (*p == 'l') p++, size = SIZE_ll3;
796 else size = SIZE_l1;
797 break;
798 case 'j':
799 size = SIZE_ll3;
800 break;
801 case 'z':
802 case 't':
803 size = SIZE_l1;
804 break;
805 case 'L':
806 size = SIZE_L2;
807 break;
808 case 'd': case 'i': case 'o': case 'u': case 'x':
809 case 'a': case 'e': case 'f': case 'g':
810 case 'A': case 'E': case 'F': case 'G': case 'X':
811 case 's': case 'c': case '[':
812 case 'S': case 'C':
813 case 'p': case 'n':
814 p--;
815 break;
816 default:
817 goto fmt_fail;
818 }
819
820 t = *p;
821
822 /* C or S */
823 if ((t&0x2f) == 3) {
824 t |= 32;
825 size = SIZE_l1;
826 }
827
828 switch (t) {
829 case 'c':
830 if (width < 1) width = 1;
831 case '[':
832 break;
833 case 'n':
834 store_int(dest, size, pos);
835 /* do not increment match count, etc! */
836 continue;
837 default:
838 shlim(f, 0)ffshlim((f), (0));
839 while (av_isspace(shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
));
840 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
841 pos += shcnt(f)((f)->shcnt + ((f)->rpos - (f)->buf));
842 }
843
844 shlim(f, width)ffshlim((f), (width));
845 if (shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
< 0) goto input_fail;
846 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
847
848 switch (t) {
849 case 's':
850 case 'c':
851 case '[':
852 if (t == 'c' || t == 's') {
853 memset(scanset, -1, sizeof scanset);
854 scanset[0] = 0;
855 if (t == 's') {
856 scanset[1 + '\t'] = 0;
857 scanset[1 + '\n'] = 0;
858 scanset[1 + '\v'] = 0;
859 scanset[1 + '\f'] = 0;
860 scanset[1 + '\r'] = 0;
861 scanset[1 + ' ' ] = 0;
862 }
863 } else {
864 if (*++p == '^') p++, invert = 1;
865 else invert = 0;
866 memset(scanset, invert, sizeof scanset);
867 scanset[0] = 0;
868 if (*p == '-') p++, scanset[1+'-'] = 1-invert;
869 else if (*p == ']') p++, scanset[1+']'] = 1-invert;
870 for (; *p != ']'; p++) {
871 if (!*p) goto fmt_fail;
872 if (*p=='-' && p[1] && p[1] != ']')
873 for (c=p++[-1]; c<*p; c++)
874 scanset[1+c] = 1-invert;
875 scanset[1+*p] = 1-invert;
876 }
877 }
878 s = 0;
879 i = 0;
880 if ((s = dest)) {
881 while (scanset[(c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)+1])
882 s[i++] = c;
883 } else {
884 while (scanset[(c=shgetc(f)(((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc
(f))
)+1]);
Although the value stored to 'c' is used in the enclosing expression, the value is never actually read from 'c'
885 }
886 shunget(f)((f)->shend ? (void)(f)->rpos-- : (void)0);
887 if (!shcnt(f)((f)->shcnt + ((f)->rpos - (f)->buf))) goto match_fail;
888 if (t == 'c' && shcnt(f)((f)->shcnt + ((f)->rpos - (f)->buf)) != width) goto match_fail;
889 if (t != 'c') {
890 if (s) s[i] = 0;
891 }
892 break;
893 case 'p':
894 case 'X':
895 case 'x':
896 base = 16;
897 goto int_common;
898 case 'o':
899 base = 8;
900 goto int_common;
901 case 'd':
902 case 'u':
903 base = 10;
904 goto int_common;
905 case 'i':
906 base = 0;
907int_common:
908 x = ffintscan(f, base, 0, ULLONG_MAX(9223372036854775807LL*2ULL+1ULL));
909 if (!shcnt(f)((f)->shcnt + ((f)->rpos - (f)->buf)))
910 goto match_fail;
911 if (t=='p' && dest)
912 *(void **)dest = (void *)(uintptr_t)x;
913 else
914 store_int(dest, size, x);
915 break;
916 case 'a': case 'A':
917 case 'e': case 'E':
918 case 'f': case 'F':
919 case 'g': case 'G':
920 y = fffloatscan(f, size, 0);
921 if (!shcnt(f)((f)->shcnt + ((f)->rpos - (f)->buf)))
922 goto match_fail;
923 if (dest) {
924 switch (size) {
925 case SIZE_def0:
926 *(float *)dest = y;
927 break;
928 case SIZE_l1:
929 *(double *)dest = y;
930 break;
931 case SIZE_L2:
932 *(double *)dest = y;
933 break;
934 }
935 }
936 break;
937 }
938
939 pos += shcnt(f)((f)->shcnt + ((f)->rpos - (f)->buf));
940 if (dest) matches++;
941 }
942 if (0) {
943fmt_fail:
944input_fail:
945 if (!matches) matches--;
946 }
947match_fail:
948 return matches;
949}
950
951static int ff_vsscanf(const char *s, const char *fmt, va_list ap)
952{
953 FFFILE f = {
954 .buf = (void *)s, .cookie = (void *)s,
955 .read = ffstring_read,
956 };
957
958 return ff_vfscanf(&f, fmt, ap);
959}
960
961int av_sscanf(const char *string, const char *format, ...)
962{
963 int ret;
964 va_list ap;
965 va_start(ap, format)__builtin_va_start(ap, format);
966 ret = ff_vsscanf(string, format, ap);
967 va_end(ap)__builtin_va_end(ap);
968 return ret;
969}