1*8d67ca89SAndroid Build Coastguard Worker /* $OpenBSD: vfscanf.c,v 1.31 2014/03/19 05:17:01 guenther Exp $ */
2*8d67ca89SAndroid Build Coastguard Worker /*-
3*8d67ca89SAndroid Build Coastguard Worker * Copyright (c) 1990, 1993
4*8d67ca89SAndroid Build Coastguard Worker * The Regents of the University of California. All rights reserved.
5*8d67ca89SAndroid Build Coastguard Worker *
6*8d67ca89SAndroid Build Coastguard Worker * This code is derived from software contributed to Berkeley by
7*8d67ca89SAndroid Build Coastguard Worker * Chris Torek.
8*8d67ca89SAndroid Build Coastguard Worker *
9*8d67ca89SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
10*8d67ca89SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
11*8d67ca89SAndroid Build Coastguard Worker * are met:
12*8d67ca89SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
13*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
14*8d67ca89SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
15*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
16*8d67ca89SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
17*8d67ca89SAndroid Build Coastguard Worker * 3. Neither the name of the University nor the names of its contributors
18*8d67ca89SAndroid Build Coastguard Worker * may be used to endorse or promote products derived from this software
19*8d67ca89SAndroid Build Coastguard Worker * without specific prior written permission.
20*8d67ca89SAndroid Build Coastguard Worker *
21*8d67ca89SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*8d67ca89SAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*8d67ca89SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*8d67ca89SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*8d67ca89SAndroid Build Coastguard Worker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*8d67ca89SAndroid Build Coastguard Worker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*8d67ca89SAndroid Build Coastguard Worker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*8d67ca89SAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*8d67ca89SAndroid Build Coastguard Worker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*8d67ca89SAndroid Build Coastguard Worker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*8d67ca89SAndroid Build Coastguard Worker * SUCH DAMAGE.
32*8d67ca89SAndroid Build Coastguard Worker */
33*8d67ca89SAndroid Build Coastguard Worker
34*8d67ca89SAndroid Build Coastguard Worker #include <ctype.h>
35*8d67ca89SAndroid Build Coastguard Worker #include <inttypes.h>
36*8d67ca89SAndroid Build Coastguard Worker #include <limits.h>
37*8d67ca89SAndroid Build Coastguard Worker #include <locale.h>
38*8d67ca89SAndroid Build Coastguard Worker #include <stdarg.h>
39*8d67ca89SAndroid Build Coastguard Worker #include <stddef.h>
40*8d67ca89SAndroid Build Coastguard Worker #include <stdio.h>
41*8d67ca89SAndroid Build Coastguard Worker #include <stdlib.h>
42*8d67ca89SAndroid Build Coastguard Worker #include <string.h>
43*8d67ca89SAndroid Build Coastguard Worker #include <sys/param.h>
44*8d67ca89SAndroid Build Coastguard Worker #include <wctype.h>
45*8d67ca89SAndroid Build Coastguard Worker #include "local.h"
46*8d67ca89SAndroid Build Coastguard Worker
47*8d67ca89SAndroid Build Coastguard Worker #include <platform/bionic/macros.h>
48*8d67ca89SAndroid Build Coastguard Worker #include <private/bionic_fortify.h>
49*8d67ca89SAndroid Build Coastguard Worker #include <private/bionic_mbstate.h>
50*8d67ca89SAndroid Build Coastguard Worker
51*8d67ca89SAndroid Build Coastguard Worker #define BUF 513 /* Maximum length of numeric string. */
52*8d67ca89SAndroid Build Coastguard Worker
53*8d67ca89SAndroid Build Coastguard Worker // Flags used during conversion.
54*8d67ca89SAndroid Build Coastguard Worker // Size/type:
55*8d67ca89SAndroid Build Coastguard Worker #define LONG 0x00001 // l: long or double
56*8d67ca89SAndroid Build Coastguard Worker #define LONGDBL 0x00002 // L: long double
57*8d67ca89SAndroid Build Coastguard Worker #define SHORT 0x00004 // h: short
58*8d67ca89SAndroid Build Coastguard Worker #define SHORTSHORT 0x00008 // hh: 8 bit integer
59*8d67ca89SAndroid Build Coastguard Worker #define LLONG 0x00010 // ll: long long (+ deprecated q: quad)
60*8d67ca89SAndroid Build Coastguard Worker #define POINTER 0x00020 // p: void* (as hex)
61*8d67ca89SAndroid Build Coastguard Worker #define SIZEINT 0x00040 // z: (signed) size_t
62*8d67ca89SAndroid Build Coastguard Worker #define MAXINT 0x00080 // j: intmax_t
63*8d67ca89SAndroid Build Coastguard Worker #define PTRINT 0x00100 // t: ptrdiff_t
64*8d67ca89SAndroid Build Coastguard Worker #define NOSKIP 0x00200 // [ or c: do not skip blanks
65*8d67ca89SAndroid Build Coastguard Worker // Modifiers:
66*8d67ca89SAndroid Build Coastguard Worker #define SUPPRESS 0x00400 // *: suppress assignment
67*8d67ca89SAndroid Build Coastguard Worker #define UNSIGNED 0x00800 // %[oupxX] conversions
68*8d67ca89SAndroid Build Coastguard Worker #define ALLOCATE 0x01000 // m: allocate a char*
69*8d67ca89SAndroid Build Coastguard Worker // Internal use during integer parsing:
70*8d67ca89SAndroid Build Coastguard Worker #define SIGNOK 0x02000 // +/- is (still) legal
71*8d67ca89SAndroid Build Coastguard Worker #define HAVESIGN 0x04000 // Sign detected
72*8d67ca89SAndroid Build Coastguard Worker #define NDIGITS 0x08000 // No digits detected
73*8d67ca89SAndroid Build Coastguard Worker #define PFXOK 0x10000 // "0x" prefix is (still) legal
74*8d67ca89SAndroid Build Coastguard Worker #define PFBOK 0x20000 // "0b" prefix is (still) legal
75*8d67ca89SAndroid Build Coastguard Worker #define NZDIGITS 0x40000 // No zero digits detected
76*8d67ca89SAndroid Build Coastguard Worker
77*8d67ca89SAndroid Build Coastguard Worker // Conversion types.
78*8d67ca89SAndroid Build Coastguard Worker #define CT_CHAR 0 // %c conversion
79*8d67ca89SAndroid Build Coastguard Worker #define CT_CCL 1 // %[...] conversion
80*8d67ca89SAndroid Build Coastguard Worker #define CT_STRING 2 // %s conversion
81*8d67ca89SAndroid Build Coastguard Worker #define CT_INT 3 // Integer: strtoimax/strtoumax
82*8d67ca89SAndroid Build Coastguard Worker #define CT_FLOAT 4 // Float: strtod
83*8d67ca89SAndroid Build Coastguard Worker
84*8d67ca89SAndroid Build Coastguard Worker #define to_digit(c) static_cast<int>((c) - '0')
85*8d67ca89SAndroid Build Coastguard Worker #define is_digit(c) (static_cast<unsigned>(to_digit(c)) <= 9)
86*8d67ca89SAndroid Build Coastguard Worker
87*8d67ca89SAndroid Build Coastguard Worker // Append a digit to a value and check for overflow.
88*8d67ca89SAndroid Build Coastguard Worker #define APPEND_DIGIT(val, dig) \
89*8d67ca89SAndroid Build Coastguard Worker do { \
90*8d67ca89SAndroid Build Coastguard Worker if ((val) > INT_MAX / 10) \
91*8d67ca89SAndroid Build Coastguard Worker errno = ENOMEM; \
92*8d67ca89SAndroid Build Coastguard Worker else { \
93*8d67ca89SAndroid Build Coastguard Worker (val) *= 10; \
94*8d67ca89SAndroid Build Coastguard Worker if ((val) > INT_MAX - to_digit((dig))) \
95*8d67ca89SAndroid Build Coastguard Worker errno = ENOMEM; \
96*8d67ca89SAndroid Build Coastguard Worker else \
97*8d67ca89SAndroid Build Coastguard Worker (val) += to_digit((dig)); \
98*8d67ca89SAndroid Build Coastguard Worker } \
99*8d67ca89SAndroid Build Coastguard Worker } while (0)
100*8d67ca89SAndroid Build Coastguard Worker
101*8d67ca89SAndroid Build Coastguard Worker #pragma clang diagnostic push
102*8d67ca89SAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wunused-function"
103*8d67ca89SAndroid Build Coastguard Worker // Trasnlate a fixed size integer argument for the %w/%wf format to a
104*8d67ca89SAndroid Build Coastguard Worker // flag representation. Supported sizes are 8, 16, 32, and 64 so far.
105*8d67ca89SAndroid Build Coastguard Worker // See details in bionic/libc/include/stdint.h
w_to_flag(int size,bool fast)106*8d67ca89SAndroid Build Coastguard Worker static int w_to_flag(int size, bool fast) {
107*8d67ca89SAndroid Build Coastguard Worker static constexpr int fast_size = sizeof(void*) == 8 ? LLONG : 0;
108*8d67ca89SAndroid Build Coastguard Worker if (size == 8) return SHORTSHORT;
109*8d67ca89SAndroid Build Coastguard Worker if (size == 16) return fast ? fast_size : SHORT;
110*8d67ca89SAndroid Build Coastguard Worker if (size == 32) return fast ? fast_size : 0;
111*8d67ca89SAndroid Build Coastguard Worker if (size == 64) return LLONG;
112*8d67ca89SAndroid Build Coastguard Worker __fortify_fatal("%%w%s%d is unsupported", fast ? "f" : "", size);
113*8d67ca89SAndroid Build Coastguard Worker }
114*8d67ca89SAndroid Build Coastguard Worker
115*8d67ca89SAndroid Build Coastguard Worker #pragma clang diagnostic pop
116