• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16
17/* [Standardize-exceptions] Use unsafe function: Performance-sensitive
18 * [reason] Always used in the performance critical path,
19 *          and sufficient input validation is performed before calling
20 */
21
22#ifndef __INPUT_INL__5D13A042_DC3F_4ED9_A8D1_882811274C27
23#define __INPUT_INL__5D13A042_DC3F_4ED9_A8D1_882811274C27
24
25#if !defined(SECUREC_SYSAPI4VXWORKS)
26#include <ctype.h>
27#ifdef SECUREC_FOR_WCHAR
28#include <wctype.h>             /* for iswspace */
29#endif
30#endif
31
32#define SECUREC_NUM_WIDTH_SHORT       0
33#define SECUREC_NUM_WIDTH_INT         1
34#define SECUREC_NUM_WIDTH_LONG        2
35#define SECUREC_NUM_WIDTH_LONG_LONG   3 /* also long double */
36
37#define SECUREC_BUF_EXT_MUL (2)
38#define SECUREC_BUFFERED_BLOK_SIZE 1024
39
40#if defined(SECUREC_SYSAPI4VXWORKS)
41#define SECUREC_DECIMAL_POINT_PTR  "."
42#else
43#include <locale.h>             /* if this file NOT exist, you can remove it */
44#define SECUREC_DECIMAL_POINT_PTR (localeconv()->decimal_point)
45#endif
46
47#if defined(SECUREC_VXWORKS_PLATFORM) && !defined(va_copy) && !defined(__va_copy)
48/* the name is the same as system macro. */
49#define __va_copy(d,s) do { \
50                            size_t size_of_d = (size_t)sizeof(d); \
51                            size_t size_of_s = (size_t)sizeof(s); \
52                            if (size_of_d != size_of_s) { \
53                                (void)memcpy((d), (s), sizeof(va_list)); \
54                            } else { \
55                                (void)memcpy(&(d), &(s), sizeof(va_list)); \
56                            } \
57                         } SECUREC_WHILE_ZERO
58#endif
59
60#define SECUREC_MUL10(x) ((((x) << 2) + (x)) << 1)
61#define SECUREC_MULTI_BYTE_MAX_LEN (6)
62#define SECUREC_INT_MAX_DIV_TEN       21474836
63
64/* Compatibility macro name cannot be modifie */
65#ifndef UNALIGNED
66#if !(defined(_M_IA64)) && !(defined(_M_AMD64))
67#define UNALIGNED
68#else
69#define UNALIGNED __unaligned
70#endif
71#endif
72
73#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
74#define SECUREC_MAX_64BITS_VALUE                18446744073709551615ULL
75#define SECUREC_MAX_64BITS_VALUE_DIV_TEN        1844674407370955161ULL
76#define SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT 18446744073709551610ULL
77#define SECUREC_MIN_64BITS_NEG_VALUE            9223372036854775808ULL
78#define SECUREC_MAX_64BITS_POS_VALUE            9223372036854775807ULL
79#define SECUREC_MIN_32BITS_NEG_VALUE            2147483648ULL
80#define SECUREC_MAX_32BITS_POS_VALUE            2147483647ULL
81#define SECUREC_MAX_32BITS_VALUE                4294967295ULL
82#define SECUREC_MAX_32BITS_VALUE_INC            4294967296ULL
83#define SECUREC_MAX_32BITS_VALUE_DIV_TEN        429496729ULL
84#define SECUREC_LONG_BIT_NUM            ((unsigned int)(sizeof(long) << 3U))
85#endif
86
87#define SECUREC_CHAR(x) (x)
88#define SECUREC_BRACE ('{')     /* [ to { */
89
90#ifdef SECUREC_FOR_WCHAR
91#define SECUREC_EOF WEOF
92#define SECUREC_MB_LEN 16       /* max. # bytes in multibyte char  ,see MB_LEN_MAX */
93#define SECUREC_GET_CHAR() (++charCount, SecGetCharW(stream))
94/* un get char marco do not set char count ,The reason is to avoid warning that variables are not used */
95#define SECUREC_UN_GET_CHAR(chr) (--charCount,SecUnGetCharW((chr), stream))
96#define SECUREC_IS_DIGIT(chr) (!((chr) & 0xff00) && isdigit(((chr) & 0x00ff)))
97#define SECUREC_IS_XDIGIT(chr) (!((chr) & 0xff00) && isxdigit(((chr) & 0x00ff)))
98static void SecUnGetCharW(SecInt chr, SecFileStream *str);
99static SecInt SecGetCharW(SecFileStream *str);
100#else
101#define SECUREC_EOF EOF
102#define SECUREC_GET_CHAR() (++charCount, SecGetChar(stream))
103#define SECUREC_UN_GET_CHAR(chr) (--charCount,SecUnGetChar((chr), stream))
104#define SECUREC_IS_DIGIT(chr) isdigit((unsigned char)(chr)& 0x00ff)
105#define SECUREC_IS_XDIGIT(chr) isxdigit((unsigned char)(chr)& 0x00ff)
106static SecInt SecGetChar(SecFileStream *str);
107static void SecUnGetChar(SecInt chr, SecFileStream *str);
108#endif
109
110#define SECUREC_SKIP_SPACE_CHAR() SecSkipSpaceChar(&charCount, stream)
111
112static SecInt SecSkipSpaceChar(int *, SecFileStream *);
113
114typedef struct {
115#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
116    SecUnsignedInt64 number64As;
117    int beyondMax;
118#endif
119    SecUnsignedInt64 number64;
120    unsigned long number;
121    int negative;
122} SecNumberSpce;
123
124static int SecCheckFloatDecPoint(char dec_point)
125{
126    /* don't support multi-language decimal point */
127    if (dec_point == '.') {
128        return 1;
129    }
130    return 0;
131}
132
133static int SecIs64BitPtr(size_t ptrSize)
134{
135    /* point size is 4 or 8 , Under the 64 bit system, the value not 0 */
136    /* to clear e778 */
137    return (int)(ptrSize & sizeof(SecInt64));
138}
139
140static void SecAssignFloat(int numberWidth, void *argument, const char *number)
141{
142    char *endptr = NULL;
143    double d;
144#if SECUREC_SUPPORT_STRTOLD
145    if (numberWidth == SECUREC_NUM_WIDTH_LONG_LONG) {
146        long double d2 = strtold(number, &endptr);
147        *(long double UNALIGNED *)argument = d2;
148        return;
149    }
150#endif
151    d = strtod(number, &endptr);
152    if (numberWidth > SECUREC_NUM_WIDTH_INT) {
153        *(double UNALIGNED *)argument = (double)d;
154    } else {
155        *(float UNALIGNED *)argument = (float)d;
156    }
157}
158
159static int SecUpdateFloatString(size_t usedLen,
160                                size_t *floatStrSize,
161                                SecChar **floatStr, const SecChar *floatStrBuf, SecChar **allocFlag)
162{
163    if (usedLen == (*floatStrSize)) {
164        if ((*floatStr) == floatStrBuf) {
165            /* add 1 to clear ZERO LENGTH ALLOCATIONS warning */
166            size_t oriBufSize = (*floatStrSize) * SECUREC_BUF_EXT_MUL * sizeof(SecChar) + 1;
167            void *tmpPointer = (void *)SECUREC_MALLOC(oriBufSize);
168            if (tmpPointer == NULL) {
169                return 0;
170            }
171            if (memcpy_s(tmpPointer, oriBufSize, (*floatStr), (*floatStrSize) * sizeof(SecChar)) != EOK) {
172                SECUREC_FREE(tmpPointer);   /* This is a dead code, just to meet the coding requirements */
173                return 0;
174            }
175            (*floatStr) = (SecChar *) (tmpPointer);
176            (*allocFlag) = (SecChar *) (tmpPointer); /* use to clear free on stack warning */
177            (*floatStrSize) *= SECUREC_BUF_EXT_MUL; /* this is OK, oriBufSize plus 1 just clear warning */
178        } else {
179            /* LSD 2014.3.6 fix, replace realloc to malloc to avoid heap injection */
180            size_t oriBufSize = (*floatStrSize) * sizeof(SecChar);
181            size_t nextSize = oriBufSize * SECUREC_BUF_EXT_MUL + 1; /* add 1 to clear ZERO LENGTH ALLOCATIONS warning */
182            /* Prevents integer overflow when calculating the wide character length.
183             * The maximum length of 2G/2 is enough
184             */
185            if (nextSize <= (SECUREC_WCHAR_MEM_MAX_LEN) / 2) {
186                void *tmpPointer = (void *)SECUREC_MALLOC(nextSize);
187                if (tmpPointer == NULL) {
188                    return 0;
189                }
190                if (memcpy_s(tmpPointer, nextSize, (*floatStr), oriBufSize) != EOK) {
191                    SECUREC_FREE(tmpPointer);   /* This is a dead code, just to meet the coding requirements */
192                    return 0;
193                }
194                if (memset_s((*floatStr), oriBufSize, 0, oriBufSize) != EOK) {
195                    SECUREC_FREE(tmpPointer);   /* This is a dead code, just to meet the coding requirements */
196                    return 0;
197                }
198                SECUREC_FREE((*floatStr));
199
200                (*floatStr) = (SecChar *) (tmpPointer);
201                (*allocFlag) = (SecChar *) (tmpPointer);    /* use to clear free on stack warning */
202                (*floatStrSize) *= SECUREC_BUF_EXT_MUL; /* this is OK, oriBufSize plus 1 just clear warning */
203                return 1;
204            }
205            return 0;
206        }
207    }
208    return 1;
209}
210
211#ifndef SECUREC_FOR_WCHAR
212
213/* LSD only multi-bytes string need isleadbyte() function */
214static int SecIsleadbyte(SecInt ch)
215{
216    unsigned int c = (unsigned int)ch;
217#if !(defined(_WIN32) || defined(_INC_WCTYPE))
218    return (int)(c & 0x80);
219#else
220    return (int)isleadbyte((int)(c & 0xff));
221#endif
222}
223
224#endif
225
226static void SecUpdateWcharFlagByType(SecUnsignedChar chr, signed char *isWchar)
227{
228#if defined(SECUREC_FOR_WCHAR) && (defined(SECUREC_COMPATIBLE_WIN_FORMAT))
229    signed char flagForUpperType = -1;
230    signed char flagForLowerType =  1;
231#else
232    signed char flagForUpperType =  1;
233    signed char flagForLowerType = -1;
234#endif
235
236    if ((*isWchar) == 0) {
237        if ((chr == SECUREC_CHAR('C')) || (chr == SECUREC_CHAR('S'))) {
238            (*isWchar) = flagForUpperType;
239        } else {
240            (*isWchar) = flagForLowerType;
241        }
242    }
243    return;
244}
245
246#define SECUREC_FLOAT_BUFSIZE (309+40)  /* digits in max. dp value + slop */
247#ifdef SECUREC_FOR_WCHAR
248#define SECUREC_BRACKET_TABLE_SIZE    (32 * 256)
249#else
250#define SECUREC_BRACKET_TABLE_SIZE    (32)
251#endif
252
253#ifdef SECUREC_FOR_WCHAR
254#define SECUREC_GETC fgetwc
255#define SECUREC_UN_GETC ungetwc
256#define SECUREC_CHAR_MASK 0xffff
257#else
258#define SECUREC_GETC fgetc
259#define SECUREC_UN_GETC ungetc
260#define SECUREC_CHAR_MASK 0xff
261#endif
262
263/* LSD 2014 1 24 add to protect NULL pointer access */
264#define SECUREC_CHECK_INPUT_ADDR(p) do { \
265                                        if ((p) == NULL) { \
266                                            paraIsNull = 1; \
267                                            goto ERR_RET; \
268                                        } \
269                                    } SECUREC_WHILE_ZERO
270
271#ifdef SECUREC_FOR_WCHAR
272void SecClearDestBufW(const wchar_t *buffer, const wchar_t *cformat, va_list arglist)
273#else
274void SecClearDestBuf(const char *buffer, const char *cformat, va_list arglist)
275#endif
276{
277    const SecUnsignedChar *fmt = (const SecUnsignedChar *)cformat;
278    void *pDestBuf = NULL;
279    va_list arglistSave;        /* backup for arglist value, this variable don't need initialized */
280    size_t bufSize = 0;
281    int spec = 0;
282    signed char isWchar = 0;
283    char doneFlag = 0;
284
285    if (fmt != NULL) {
286        while (*fmt) {
287            if (*fmt == SECUREC_CHAR('%')) {
288                doneFlag = 0;
289                isWchar = 0;
290
291                while (doneFlag == 0) {
292                    spec = *(++fmt);
293
294                    if (SECUREC_IS_DIGIT((SecUnsignedChar) spec)) {
295                        continue;
296                    } else if (spec == SECUREC_CHAR('h')) {
297                        isWchar = -1;
298                        continue;
299                    } else if (spec == SECUREC_CHAR('l') || spec == SECUREC_CHAR('w')) {
300                        isWchar = 1;
301                        continue;
302                    }
303                    doneFlag = 1;
304                }
305
306                /* if no  l or h flag */
307                SecUpdateWcharFlagByType(*fmt, &isWchar);
308
309                spec = *fmt | (SECUREC_CHAR('a') - SECUREC_CHAR('A'));
310
311                if (!(spec == SECUREC_CHAR('c') || spec == SECUREC_CHAR('s') || spec == SECUREC_BRACE)) {
312                    return;     /* first argument is not a string type */
313                }
314
315                if ((buffer != NULL) && (*buffer != SECUREC_CHAR('\0')) && (spec != SECUREC_CHAR('s'))) {
316                    /* when buffer not empty just clear %s.
317                     * example call sscanf by  argument of (" \n","%s",str,sizeof(str))
318                     */
319                    return;
320                }
321
322                if (spec == SECUREC_BRACE) {
323#if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))
324                    if (*fmt == SECUREC_CHAR('{')) {
325                        return;
326                    }
327#endif
328                    ++fmt;
329
330                    if (*fmt == SECUREC_CHAR('^')) {
331                        ++fmt;
332                    }
333
334                    if (*fmt == SECUREC_CHAR(']')) {
335                        ++fmt;
336                    }
337
338                    while ((*fmt != SECUREC_CHAR('\0')) && (*fmt != SECUREC_CHAR(']'))) {
339                        ++fmt;
340                    }
341                    if (*fmt == SECUREC_CHAR('\0')) {
342                        return; /* trunc'd format string */
343                    }
344                }
345
346                (void)memset(&arglistSave, 0, sizeof(arglistSave)); /* to clear e530 arglistSave not initialized */
347#if defined(va_copy)
348                va_copy(arglistSave, arglist);
349#elif defined(__va_copy)        /* for vxworks */
350                __va_copy(arglistSave, arglist);
351#else
352                arglistSave = arglist;
353#endif
354                pDestBuf = (void *)va_arg(arglistSave, void *);
355                /* Get the next argument - size of the array in characters */
356                bufSize = ((size_t)(va_arg(arglistSave, size_t))) & 0xFFFFFFFFUL;
357
358                va_end(arglistSave);
359                /* to clear e438 last value assigned not used , the compiler will optimize this code */
360                (void)arglistSave;
361
362                if (bufSize == 0 || bufSize > SECUREC_STRING_MAX_LEN || pDestBuf == NULL) {
363                    return;
364                }
365
366                *(char *)pDestBuf = '\0';
367
368                if (isWchar > 0 && bufSize >= sizeof(wchar_t)) {
369                    *(wchar_t UNALIGNED *)pDestBuf = L'\0';
370                }
371
372                return;
373            }
374            ++fmt;              /* skip to next char */
375        }
376    }
377    return;
378}
379
380static void SecAssignNumber(void *argPtr, const int numberWidth, const unsigned long number)
381{
382    if (numberWidth > SECUREC_NUM_WIDTH_INT) {
383        *(long UNALIGNED *)argPtr = (long)number;   /* take number as unsigned number */
384    } else if (numberWidth == SECUREC_NUM_WIDTH_INT) {
385        *(int UNALIGNED *)argPtr = (int)number;
386    } else if (numberWidth == SECUREC_NUM_WIDTH_SHORT) {
387        *(short UNALIGNED *)argPtr = (short)number; /* take number as unsigned number */
388    } else {                    /* < 0 for hh format modifier */
389        *(char UNALIGNED *)argPtr = (char)number;   /* take number as unsigned number */
390    }
391}
392
393#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
394static int SecIsLongBitEqual(const int bitNum)
395{
396    return (unsigned int)bitNum == SECUREC_LONG_BIT_NUM;
397}
398#endif
399static SecInt SecHex2Dec(const SecInt ch)
400{
401    /* use isdigt Causing tool false alarms */
402    return (SecInt) ((ch >= '0' && ch <= '9') ? (unsigned char)ch :
403                     ((((unsigned char)ch | (unsigned char)('a' - 'A')) - ('a')) + 10 + '0'));
404}
405
406static char SecDecodeNumber(const int comChr, const SecInt ch, SecNumberSpce *spec)
407{
408    char doneFlag = 0;
409#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
410    unsigned long decimalEdge = SECUREC_MAX_32BITS_VALUE_DIV_TEN;
411#endif
412    if (comChr == SECUREC_CHAR('x') || comChr == SECUREC_CHAR('p')) {
413        if (SECUREC_IS_XDIGIT(ch)) {
414            SecInt ch2;
415#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
416            if ((spec->number >> (SECUREC_LONG_BIT_NUM - 4)) > 0) {
417                spec->beyondMax = 1;
418            }
419#endif
420            spec->number = (spec->number << 4);
421            ch2 = SecHex2Dec(ch);
422            spec->number += (unsigned long)((SecUnsignedInt) ch2 - SECUREC_CHAR('0'));
423        } else {
424            doneFlag = 1;
425        }
426    } else if (SECUREC_IS_DIGIT(ch)) {
427
428        if (comChr == SECUREC_CHAR('o')) {
429            if (ch < SECUREC_CHAR('8')) {
430#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
431                if ((spec->number >> (SECUREC_LONG_BIT_NUM - 3)) > 0) {
432                    spec->beyondMax = 1;
433                }
434#endif
435                spec->number = (spec->number << 3);
436                spec->number += (unsigned long)((SecUnsignedInt) ch - SECUREC_CHAR('0'));
437            } else {
438                doneFlag = 1;
439            }
440        } else {                /* SECUREC_CHAR('d') == comChr */
441#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
442#ifdef SECUREC_ON_64BITS
443            if (SecIsLongBitEqual(64)) {
444                decimalEdge = (unsigned long)SECUREC_MAX_64BITS_VALUE_DIV_TEN;
445            }
446#else
447            if (SecIsLongBitEqual(32)) {
448                decimalEdge = SECUREC_MAX_32BITS_VALUE_DIV_TEN;
449            }
450#endif
451            if (spec->number > decimalEdge) {
452                spec->beyondMax = 1;
453            }
454#endif
455            spec->number = SECUREC_MUL10(spec->number);
456#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
457            if (spec->number == SECUREC_MUL10(decimalEdge)) {
458                spec->number64As = (unsigned long)SECUREC_MAX_64BITS_VALUE - spec->number;
459                if (spec->number64As < (SecUnsignedInt64)((SecUnsignedInt) ch - SECUREC_CHAR('0'))) {
460                    spec->beyondMax = 1;
461                }
462            }
463#endif
464            spec->number += (unsigned long)((SecUnsignedInt) ch - SECUREC_CHAR('0'));
465        }
466    } else {
467        doneFlag = 1;
468    }
469    return doneFlag;
470}
471
472static void SecFinishNumber(const int comChr, const int numberWidth, SecNumberSpce *spec)
473{
474
475#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
476    if (spec->negative != 0) {
477        if (numberWidth == SECUREC_NUM_WIDTH_INT) {
478            if ((comChr == SECUREC_CHAR('d')) || (comChr == SECUREC_CHAR('i'))) {
479#ifdef SECUREC_ON_64BITS
480                if (SecIsLongBitEqual(64)) {
481                    if ((spec->number > SECUREC_MIN_64BITS_NEG_VALUE)) {
482                        spec->number = 0;
483                    } else {
484                        spec->number = (unsigned int)(-(int)spec->number);
485                    }
486                }
487#else
488                if (SecIsLongBitEqual(32)) {
489                    if ((spec->number > SECUREC_MIN_32BITS_NEG_VALUE)) {
490                        spec->number = SECUREC_MIN_32BITS_NEG_VALUE;
491                    } else {
492                        spec->number = (unsigned int)(-(int)spec->number);
493                    }
494                }
495#endif
496                if (spec->beyondMax) {
497#ifdef SECUREC_ON_64BITS
498                    if (SecIsLongBitEqual(64)) {
499                        spec->number = 0;
500                    }
501#else
502                    if (SecIsLongBitEqual(32)) {
503                        spec->number = SECUREC_MIN_32BITS_NEG_VALUE;
504                    }
505#endif
506                }
507            } else {            /* o, u, x, X ,p */
508#ifdef SECUREC_ON_64BITS
509                if (spec->number > SECUREC_MAX_32BITS_VALUE_INC) {
510                    spec->number = SECUREC_MAX_32BITS_VALUE;
511                } else {
512                    spec->number = (unsigned int)(-(int)spec->number);
513                }
514#else
515                 spec->number = (unsigned int)(-(int)spec->number);
516#endif
517                if (spec->beyondMax) {
518                    spec->number |= (unsigned long)0xffffffffffffffffULL;
519                }
520            }
521        } else {
522            if ((comChr == SECUREC_CHAR('d')) || (comChr == SECUREC_CHAR('i'))) {
523                if (spec->number > (unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1))) {
524                    spec->number = (unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1));
525                } else {
526                    spec->number = (unsigned long)(-(long)spec->number);
527                }
528            } else {
529                spec->number = (unsigned long)(-(long)spec->number);
530                if (spec->beyondMax) {
531                    spec->number |= (unsigned long)0xffffffffffffffffULL;
532                }
533            }
534        }
535        if ((comChr == SECUREC_CHAR('d')) || (comChr == SECUREC_CHAR('i'))) {
536            if (((spec->beyondMax) && (numberWidth < SECUREC_NUM_WIDTH_SHORT)) ||
537                ((spec->beyondMax) && (numberWidth == SECUREC_NUM_WIDTH_SHORT)) ||
538                ((spec->beyondMax) && (numberWidth == SECUREC_NUM_WIDTH_INT) && (SecIsLongBitEqual(64)))) {
539                spec->number = 0;
540            }
541            if ((spec->beyondMax) && (numberWidth == SECUREC_NUM_WIDTH_LONG)) {
542                spec->number = ((unsigned long)(1UL << (SECUREC_LONG_BIT_NUM - 1)));
543            }
544        } else {                /* o, u, x, X, p */
545            if (spec->beyondMax) {
546                spec->number |= (unsigned long)0xffffffffffffffffULL;
547            }
548        }
549    } else {
550        if (numberWidth == SECUREC_NUM_WIDTH_INT) {
551            if ((comChr == SECUREC_CHAR('d')) || (comChr == SECUREC_CHAR('i'))) {
552#ifdef SECUREC_ON_64BITS
553                if (SecIsLongBitEqual(64)) {
554                    if (spec->number > SECUREC_MAX_64BITS_POS_VALUE) {
555                        spec->number |= (unsigned long)0xffffffffffffffffULL;
556                    }
557                }
558                if ((spec->beyondMax) && (SecIsLongBitEqual(64))) {
559                    spec->number |= (unsigned long)0xffffffffffffffffULL;
560                }
561#else
562                if (SecIsLongBitEqual(32)) {
563                    if (spec->number > SECUREC_MAX_32BITS_POS_VALUE) {
564                        spec->number = SECUREC_MAX_32BITS_POS_VALUE;
565                    }
566                }
567                if ((spec->beyondMax) && (SecIsLongBitEqual(32))) {
568                    spec->number = SECUREC_MAX_32BITS_POS_VALUE;
569                }
570#endif
571            } else {            /* o,u,x,X,p */
572                if (spec->beyondMax) {
573                    spec->number = SECUREC_MAX_32BITS_VALUE;
574                }
575            }
576
577        } else {
578            if ((comChr == SECUREC_CHAR('d')) || (comChr == SECUREC_CHAR('i'))) {
579                if (spec->number > ((unsigned long)(1UL << (SECUREC_LONG_BIT_NUM - 1)) - 1)) {
580                    spec->number = ((unsigned long)(1UL << (SECUREC_LONG_BIT_NUM - 1)) - 1);
581                }
582                if (((spec->beyondMax) && (numberWidth < SECUREC_NUM_WIDTH_SHORT)) ||
583                    ((spec->beyondMax) && (numberWidth == SECUREC_NUM_WIDTH_SHORT))) {
584                    spec->number |= (unsigned long)0xffffffffffffffffULL;
585                }
586                if ((spec->beyondMax) && (numberWidth == SECUREC_NUM_WIDTH_LONG)) {
587                    spec->number = ((unsigned long)(1UL << (SECUREC_LONG_BIT_NUM - 1)) - 1);
588                }
589            } else {
590                if (spec->beyondMax) {
591                    spec->number |= (unsigned long)0xffffffffffffffffULL;
592                }
593            }
594        }
595    }
596#else
597    if (spec->negative != 0) {
598#if defined(__hpux)
599        if (comChr != SECUREC_CHAR('p')) {
600            spec->number = (unsigned long)(-(long)spec->number);
601        }
602#else
603        spec->number = (unsigned long)(-(long)spec->number);
604#endif
605    }
606#endif
607
608    (void)numberWidth;          /* clear compile warning */
609    (void)comChr;               /* clear compile warning */
610    return;
611}
612
613static char SecDecodeNumber64(const int comChr, const SecInt ch, SecNumberSpce *spec)
614{
615    char doneFlag = 0;
616
617    if (comChr == SECUREC_CHAR('x') || comChr == SECUREC_CHAR('p')) {
618        if (SECUREC_IS_XDIGIT(ch)) {
619            SecInt ch2;
620#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
621            if ((spec->number64 >> 60) > 0) {
622                spec->beyondMax = 1;
623            }
624            spec->number64As = 16;
625#endif
626            spec->number64 <<= 4;
627            ch2 = SecHex2Dec(ch);
628            spec->number64 += (SecUnsignedInt64)((SecUnsignedInt) ch2 - SECUREC_CHAR('0'));
629        } else {
630            doneFlag = 1;
631        }
632    } else if (SECUREC_IS_DIGIT(ch)) {
633        if (comChr == SECUREC_CHAR('o')) {
634            if (ch < SECUREC_CHAR('8')) {
635#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
636                if ((spec->number64 >> 61) > 0) {
637                    spec->beyondMax = 1;
638                }
639                spec->number64As = 8;
640#endif
641                spec->number64 <<= 3;
642                spec->number64 += (SecUnsignedInt64)((SecUnsignedInt) ch - SECUREC_CHAR('0'));
643            } else {
644                doneFlag = 1;
645            }
646        } else {                /* SECUREC_CHAR('d') == comChr */
647#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
648            if (spec->number64 > SECUREC_MAX_64BITS_VALUE_DIV_TEN) {
649                spec->beyondMax = 1;
650            }
651#endif
652            spec->number64 = SECUREC_MUL10(spec->number64);
653#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
654            if (spec->number64 == SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT) {
655                spec->number64As = SECUREC_MAX_64BITS_VALUE - spec->number64;
656                if (spec->number64As < (SecUnsignedInt64)((SecUnsignedInt) ch - SECUREC_CHAR('0'))) {
657                    spec->beyondMax = 1;
658                }
659            }
660#endif
661            spec->number64 += (SecUnsignedInt64)((SecUnsignedInt) ch - SECUREC_CHAR('0'));
662        }
663
664    } else {
665        doneFlag = 1;
666    }
667
668    return doneFlag;
669}
670
671static void SecFinishNumber64(const int comChr, SecNumberSpce *spec)
672{
673#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
674    if (spec->negative != 0) {
675        if (comChr == (SECUREC_CHAR('d')) || (comChr == SECUREC_CHAR('i'))) {
676            if (spec->number64 > SECUREC_MIN_64BITS_NEG_VALUE) {
677                spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE;
678            } else {
679                spec->number64 = (SecUnsignedInt64)(-(SecInt64)spec->number64);
680            }
681            if (spec->beyondMax) {
682                spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE;
683            }
684        } else {                /* o, u, x, X, p */
685            spec->number64 = (SecUnsignedInt64)(-(SecInt64)spec->number64);
686            if (spec->beyondMax) {
687                spec->number64 = SECUREC_MAX_64BITS_VALUE;
688            }
689        }
690    } else {
691        if ((comChr == SECUREC_CHAR('d')) || (comChr == SECUREC_CHAR('i'))) {
692            if (spec->number64 > SECUREC_MAX_64BITS_POS_VALUE) {
693                spec->number64 = SECUREC_MAX_64BITS_POS_VALUE;
694            }
695            if (spec->beyondMax) {
696                spec->number64 = SECUREC_MAX_64BITS_POS_VALUE;
697            }
698        } else {
699            if (spec->beyondMax) {
700                spec->number64 = SECUREC_MAX_64BITS_VALUE;
701            }
702        }
703    }
704#else
705    if (spec->negative != 0) {
706#if defined(__hpux)
707        if (comChr != SECUREC_CHAR('p')) {
708            spec->number64 = (SecUnsignedInt64)(-(SecInt64)spec->number64);
709        }
710#else
711        spec->number64 = (SecUnsignedInt64)(-(SecInt64)spec->number64);
712#endif
713    }
714#endif
715    (void)comChr;               /* clear compile warning */
716    return;
717}
718
719static void SecAdjustStream(SecFileStream *stream)
720{
721    if (stream != NULL && (stream->flag & SECUREC_FILE_STREAM_FLAG) && stream->base != NULL) {
722
723        if ((0 == stream->count) && feof(stream->pf)) {
724            /* file pointer at the end of file, don't need to seek back */
725            stream->base[0] = '\0';
726        } else {
727            /* LSD seek to original position, bug fix 2014 1 21 */
728
729            if (fseek(stream->pf, stream->oriFilePos, SEEK_SET)) {
730                /* seek failed, ignore it */
731                stream->oriFilePos = 0;
732            } else {
733                if (stream->fileRealRead > 0) { /* LSD bug fix. when file reach to EOF, don't seek back */
734#if (defined(SECUREC_COMPATIBLE_WIN_FORMAT))
735                    int loops;
736                    for (loops = 0; loops < (stream->fileRealRead / SECUREC_BUFFERED_BLOK_SIZE); ++loops) {
737                        if (fread(stream->base, (size_t)1, (size_t)SECUREC_BUFFERED_BLOK_SIZE,
738                                  stream->pf) != SECUREC_BUFFERED_BLOK_SIZE) {
739                            break;
740                        }
741                    }
742                    if ((stream->fileRealRead % SECUREC_BUFFERED_BLOK_SIZE) != 0) {
743                        size_t ret = fread(stream->base,
744                                           (size_t)((unsigned int)stream->fileRealRead % SECUREC_BUFFERED_BLOK_SIZE),
745                                           (size_t)1, stream->pf);
746                        if (ret == 1 || ret == 0) {
747                            if (ftell(stream->pf) < stream->oriFilePos + stream->fileRealRead) {
748                                (void)fseek(stream->pf, stream->oriFilePos + stream->fileRealRead, SEEK_SET);
749                            }
750                        }
751                    }
752
753#else
754                    /* in linux like system */
755                    if (fseek(stream->pf, stream->oriFilePos + stream->fileRealRead, SEEK_SET)) {
756                        /* seek failed, ignore it */
757                        stream->oriFilePos = 0;
758                    }
759#endif
760                }
761            }
762        }
763
764        SECUREC_FREE(stream->base);
765        stream->base = NULL;
766    }
767    return;
768}
769
770#ifdef SECUREC_FOR_WCHAR
771int SecInputSW(SecFileStream *stream, const wchar_t *cformat, va_list arglist)
772#else
773int SecInputS(SecFileStream *stream, const char *cformat, va_list arglist)
774#endif
775{
776    SecChar floatStrBuffer[SECUREC_FLOAT_BUFSIZE + 1];
777    SecChar *pFloatStr = floatStrBuffer;
778    SecChar *pAllocedFloatStr = NULL;
779    const SecUnsignedChar *format = (const SecUnsignedChar *)cformat;
780
781    size_t arrayWidth = 0;
782    size_t floatStrUsedLen = 0;
783    size_t floatStrSize = sizeof(floatStrBuffer) / sizeof(floatStrBuffer[0]);
784
785#ifdef SECUREC_FOR_WCHAR
786    unsigned char *bracketTable = NULL;
787#else
788    unsigned char bracketTable[SECUREC_BRACKET_TABLE_SIZE] = { 0 };
789#endif
790
791#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
792    SecNumberSpce numberSpec = { 0, 0, 0, 0, 0 };
793#else
794    SecNumberSpce numberSpec = { 0, 0, 0 };
795#endif
796
797    void *argPtr = NULL;        /* points to receiving data addr */
798    void *startPtr = NULL;
799
800    SecInt ch = 0;
801    int charCount;
802    int comChr = 0;
803    int oricomChr = 0;
804
805    int doneCount;
806
807    int started = 0;
808    int width = 0;
809    int widthSet = 0;
810    int errNoMem = 0;
811    int formatError = 0;
812    int paraIsNull = 0;
813    int numberWidth = SECUREC_NUM_WIDTH_INT;    /* 0 = SHORT, 1 = int, > 1  long or L_DOUBLE */
814    int isInt64Arg = 0;         /* 1 for 64-bit integer, 0 otherwise */
815
816    va_list arglistSave;        /* backup for arglist value, this variable don't need initialized */
817
818#if defined(va_copy) || defined(__va_copy)
819    int arglistBeenCopied = 0;
820#endif
821
822    SecChar decimal;
823    SecUnsignedChar expCh;
824    SecUnsignedChar last;
825    SecUnsignedChar prevChar;
826
827    signed char isWchar;     /* -1/0 not wchar, 1 for wchar */
828    unsigned char tableMask;
829    char suppress;
830    char match;
831    char doneFlag;
832
833    doneCount = 0;
834    charCount = 0;
835    match = 0;
836    (void)memset(&arglistSave, 0, sizeof(arglistSave));
837
838    while (format != NULL && *format) {
839        if (isspace((SecUnsignedChar) * format)) {
840            SecUnsignedChar tch;
841            /* eat all space chars and put fist no space char backup */
842            SECUREC_UN_GET_CHAR(SECUREC_SKIP_SPACE_CHAR());
843            do {
844                tch = (SecUnsignedChar) * (++format);
845            } while (isspace(tch));
846            continue;
847        }
848
849        if (*format == SECUREC_CHAR('%')) {
850            numberSpec.number = 0;
851            numberSpec.negative = 0;
852            prevChar = 0;
853            width = 0;
854            widthSet = 0;
855            started = 0;
856            arrayWidth = 0;
857            errNoMem = 0;
858            doneFlag = 0;
859            suppress = 0;
860            tableMask = 0;
861            isWchar = 0;
862            numberWidth = SECUREC_NUM_WIDTH_INT;
863#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
864            numberSpec.beyondMax = 0;
865#endif
866            isInt64Arg = 0;
867            numberSpec.number64 = 0;
868
869            while (doneFlag == 0) {
870                comChr = *(++format);
871                if (SECUREC_IS_DIGIT((SecUnsignedChar) comChr)) {
872                    widthSet = 1;
873                    if (width > SECUREC_INT_MAX_DIV_TEN) {
874                        formatError = 1;
875                        goto ERR_RET;
876                    }
877                    width = (int)SECUREC_MUL10((unsigned int)width) + (comChr - SECUREC_CHAR('0'));
878                } else {
879                    switch (comChr) {
880                    case SECUREC_CHAR('F'):    /* fall-through */ /* FALLTHRU */
881                    case SECUREC_CHAR('N'):
882                        break;
883                    case SECUREC_CHAR('h'):
884                        --numberWidth;  /* h for SHORT , hh for CHAR */
885                        isWchar = -1;
886                        break;
887#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
888                    case SECUREC_CHAR('j'):
889                        numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;  /* intmax_t or uintmax_t */
890                        isInt64Arg = 1;
891                        break;
892                    case SECUREC_CHAR('t'):    /* fall-through */ /* FALLTHRU */
893#endif
894                    case SECUREC_CHAR('z'):
895#ifdef SECUREC_ON_64BITS
896                        numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;
897                        isInt64Arg = 1;
898#else
899                        numberWidth = SECUREC_NUM_WIDTH_LONG;
900#endif
901                        break;
902                    case SECUREC_CHAR('L'):    /* long double */ /* fall-through */ /* FALLTHRU */
903                    case SECUREC_CHAR('q'):
904                        numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;
905                        isInt64Arg = 1;
906                        break;
907                    case SECUREC_CHAR('l'):
908                        if (*(format + 1) == SECUREC_CHAR('l')) {
909                            isInt64Arg = 1;
910                            numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;
911                            ++format;
912                        } else {
913                            numberWidth = SECUREC_NUM_WIDTH_LONG;
914#ifdef SECUREC_ON_64BITS
915#if  !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))  /* on window 64 system sizeof long is 32bit */
916                            isInt64Arg = 1;
917#endif
918#endif
919                            isWchar = 1;
920                        }
921                        break;
922                    case SECUREC_CHAR('w'):
923                        isWchar = 1;
924                        break;
925
926                    case SECUREC_CHAR('*'):
927                        suppress = 1;
928                        break;
929
930                    case SECUREC_CHAR('I'):
931                        if ((*(format + 1) == SECUREC_CHAR('6')) &&
932                            (*(format + 2) == SECUREC_CHAR('4'))) {
933                            isInt64Arg = 1;
934                            format += 2;
935                            break;
936                        } else if ((*(format + 1) == SECUREC_CHAR('3')) &&
937                                   (*(format + 2) == SECUREC_CHAR('2'))) {
938                            format += 2;
939                            break;
940                        } else if ((*(format + 1) == SECUREC_CHAR('d')) ||
941                                   (*(format + 1) == SECUREC_CHAR('i')) ||
942                                   (*(format + 1) == SECUREC_CHAR('o')) ||
943                                   (*(format + 1) == SECUREC_CHAR('x')) ||
944                                   (*(format + 1) == SECUREC_CHAR('X'))) {
945                            isInt64Arg = SecIs64BitPtr(sizeof(void *));
946                            break;
947                        }
948                        isInt64Arg = SecIs64BitPtr(sizeof(void *));
949                        doneFlag = 1;
950                        break;
951                    default:
952                        doneFlag = 1;
953                        break;
954                    }           /* end of switch (comChr) ... */
955                }
956            }
957
958            if (suppress == 0) {
959                /* LSD change, for gcc compile Assign arglist to   arglistSave */
960#if defined(va_copy)
961                va_copy(arglistSave, arglist);
962#elif defined(__va_copy)        /* for vxworks */
963                __va_copy(arglistSave, arglist);
964#else
965                arglistSave = arglist;
966#endif
967                argPtr = (void *)va_arg(arglist, void *);
968                SECUREC_CHECK_INPUT_ADDR(argPtr);
969            } else {
970                /* "argPtr = NULL" is safe, in suppress mode we don't use argPtr to store data */
971                argPtr = NULL;  /* doesn't matter what value we use here - we're only using it as a flag */
972            }
973
974            doneFlag = 0;
975
976            SecUpdateWcharFlagByType(*format, &isWchar);
977
978            comChr = *format | (SECUREC_CHAR('a') - SECUREC_CHAR('A')); /* to lowercase */
979
980            if (comChr != SECUREC_CHAR('n')) {
981                if (comChr != SECUREC_CHAR('c') && comChr != SECUREC_BRACE) {
982                    ch = SECUREC_SKIP_SPACE_CHAR();
983                } else {
984                    ch = SECUREC_GET_CHAR();
985                }
986            }
987
988            if (comChr != SECUREC_CHAR('n')) {
989                if (ch == SECUREC_EOF) {
990                    goto ERR_RET;
991                }
992            }
993
994            if (widthSet == 0 || width != 0) {
995                if (suppress == 0 && (comChr == SECUREC_CHAR('c') ||
996                    comChr == SECUREC_CHAR('s') ||
997                    comChr == SECUREC_BRACE)) {
998
999#if defined(va_copy)
1000                    va_copy(arglist, arglistSave);
1001                    va_end(arglistSave);
1002                    arglistBeenCopied = 1;
1003#elif defined(__va_copy)        /* for vxworks */
1004                    __va_copy(arglist, arglistSave);
1005                    va_end(arglistSave);
1006                    arglistBeenCopied = 1;
1007#else
1008                    arglist = arglistSave;
1009#endif
1010                    argPtr = (void *)va_arg(arglist, void *);
1011                    SECUREC_CHECK_INPUT_ADDR(argPtr);
1012
1013#if defined(va_copy)
1014                    va_copy(arglistSave, arglist);
1015#elif defined(__va_copy)        /* for vxworks */
1016                    __va_copy(arglistSave, arglist);
1017#else
1018                    arglistSave = arglist;
1019#endif
1020                    /* Get the next argument - size of the array in characters */
1021#ifdef SECUREC_ON_64BITS
1022                    arrayWidth = ((size_t)(va_arg(arglist, size_t))) & 0xFFFFFFFFUL;
1023#else /* !SECUREC_ON_64BITS */
1024                    arrayWidth = (size_t)va_arg(arglist, size_t);
1025#endif
1026
1027                    if (arrayWidth < 1) {
1028
1029                        if (isWchar > 0) {
1030                            *(wchar_t UNALIGNED *)argPtr = L'\0';
1031                        } else {
1032                            *(char *)argPtr = '\0';
1033                        }
1034
1035                        goto ERR_RET;
1036                    }
1037
1038                    /* LSD add string maxi width protection */
1039                    if (isWchar > 0) {
1040                        if (arrayWidth > SECUREC_WCHAR_STRING_MAX_LEN) {
1041                            goto ERR_RET;
1042                        }
1043                    } else {
1044                        /* for char *buffer */
1045                        if (arrayWidth > SECUREC_STRING_MAX_LEN) {
1046                            goto ERR_RET;
1047                        }
1048                    }
1049
1050                }
1051
1052                oricomChr = comChr;
1053
1054                switch (comChr) {
1055                case SECUREC_CHAR('c'):
1056                    /* also case 'C' */ /* fall-through */ /* FALLTHRU */
1057                case SECUREC_CHAR('s'):
1058                    /* also case 'S': */ /* fall-through */ /* FALLTHRU */
1059                case SECUREC_BRACE:
1060                    if (comChr == 'c') {
1061                        if (widthSet == 0) {
1062                            widthSet = 1;
1063                            width = 1;
1064                        }
1065                    } else if (comChr == 's') {
1066                        /* empty */
1067                    } else {    /* for [ */
1068                        const SecUnsignedChar *bracketFmtPtr = (const SecUnsignedChar *)(format);
1069#if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))
1070                        if (*format == SECUREC_CHAR('{')) {
1071                            goto ERR_RET;
1072                        }
1073#endif
1074                        /* for building "table" data */
1075                        ++bracketFmtPtr;
1076
1077                        if (*bracketFmtPtr == SECUREC_CHAR('^')) {
1078                            ++bracketFmtPtr;
1079                            tableMask = (unsigned char)0xff;
1080                        }
1081
1082                        /* malloc  when  first %[ is meet  for wchar version */
1083#ifdef SECUREC_FOR_WCHAR
1084                        if (bracketTable == NULL) {
1085                            /* LSD the table will be freed after ERR_RET label of this function */
1086                            bracketTable = (unsigned char *)SECUREC_MALLOC(SECUREC_BRACKET_TABLE_SIZE);
1087                            if (bracketTable == NULL) {
1088                                goto ERR_RET;
1089                            }
1090                        }
1091#endif
1092                        (void)memset(bracketTable, 0, (size_t)SECUREC_BRACKET_TABLE_SIZE);
1093
1094                        if (*bracketFmtPtr == SECUREC_CHAR(']')) {
1095                            prevChar = SECUREC_CHAR(']');
1096                            ++bracketFmtPtr;
1097
1098                            bracketTable[SECUREC_CHAR(']') >> 3] = 1 << (SECUREC_CHAR(']') & 7);
1099
1100                        }
1101
1102                        while (*bracketFmtPtr != SECUREC_CHAR('\0') && *bracketFmtPtr != SECUREC_CHAR(']')) {
1103                            unsigned int tmpIndex;  /* to clear warning */
1104                            expCh = *bracketFmtPtr++;
1105
1106                            if (expCh != SECUREC_CHAR('-') || !prevChar ||  /* first char */
1107                                *bracketFmtPtr == SECUREC_CHAR(']')) {  /* last char */
1108                                prevChar = expCh;
1109                                /* only supports  wide characters with a maximum length of two bytes */
1110                                tmpIndex = (unsigned int)(int)expCh & SECUREC_CHAR_MASK;
1111                                /* Do not use    |= optimize this code, it will cause compiling warning */
1112                                bracketTable[(tmpIndex) >> 3] = (unsigned char)(bracketTable[(tmpIndex) >> 3] |
1113                                                                (unsigned char)(1 << (tmpIndex & 7)));
1114                            } else {
1115                                /* for %[a-z] */
1116                                expCh = *bracketFmtPtr++;   /* get end of range */
1117
1118                                if (prevChar < expCh) { /* %[a-z] */
1119                                    last = expCh;
1120                                } else {
1121
1122#if (defined(SECUREC_COMPATIBLE_WIN_FORMAT))
1123                                    /* %[z-a] */
1124                                    last = prevChar;
1125                                    prevChar = expCh;
1126#else
1127                                    prevChar = expCh;
1128                                    /* only supports  wide characters with a maximum length of two bytes */
1129                                    tmpIndex = (unsigned int)(int)expCh & SECUREC_CHAR_MASK;
1130                                    bracketTable['-' >> 3] |= (unsigned char)(1 << ('-' & 7));
1131                                    bracketTable[(tmpIndex) >> 3] = (unsigned char)(bracketTable[(tmpIndex) >> 3] |
1132                                                                    (unsigned char)(1 << (tmpIndex & 7)));
1133                                    continue;
1134#endif
1135                                }
1136                                /* format %[a-\xff] last is 0xFF, condition (rnch <= last) cause dead loop */
1137                                for (expCh = prevChar; expCh < last; ++expCh) {
1138                                    /* only supports  wide characters with a maximum length of two bytes */
1139                                    tmpIndex = (unsigned int)(int)expCh & SECUREC_CHAR_MASK;
1140                                    bracketTable[tmpIndex >> 3] = (unsigned char)(bracketTable[tmpIndex >> 3] |
1141                                                                  (unsigned char)(1 << (tmpIndex & 7)));
1142                                }
1143                                /* only supports  wide characters with a maximum length of two bytes */
1144                                tmpIndex = (unsigned int)(int)last & SECUREC_CHAR_MASK;
1145                                bracketTable[tmpIndex >> 3] = (unsigned char)(bracketTable[tmpIndex >> 3] |
1146                                                              (unsigned char)(1 << (tmpIndex & 7)));
1147                                prevChar = 0;
1148                            }
1149                        }
1150
1151                        if (*bracketFmtPtr == SECUREC_CHAR('\0')) {
1152                            if (arrayWidth >= sizeof(SecChar) && argPtr) {
1153                                *(SecChar *) argPtr = SECUREC_CHAR('\0');
1154                            }
1155                            goto ERR_RET;   /* trunc'd format string */
1156                        }
1157                        format = bracketFmtPtr;
1158                    }
1159                    /* scanset completed.  Now read string */
1160
1161                    startPtr = argPtr;
1162
1163                    SECUREC_UN_GET_CHAR(ch);
1164
1165                    /* One element is needed for '\0' for %s & %[ */
1166                    if (comChr != SECUREC_CHAR('c')) {
1167                        --arrayWidth;
1168                    }
1169                    while (widthSet == 0 || width-- != 0) {
1170
1171                        ch = SECUREC_GET_CHAR();
1172                        if ((SECUREC_EOF != ch) &&
1173                            /* char conditions */
1174                            ((comChr == SECUREC_CHAR('c')) ||
1175                             /* string conditions !isspace() */
1176                             ((comChr == SECUREC_CHAR('s') &&
1177                               (!(ch >= SECUREC_CHAR('\t') && ch <= SECUREC_CHAR('\r')) && ch != SECUREC_CHAR(' ')))) ||
1178                             /* BRACKET conditions */
1179                             ((comChr == SECUREC_BRACE) &&
1180#ifdef SECUREC_FOR_WCHAR
1181                              bracketTable &&   /* only supports  wide characters with a maximum length of two bytes */
1182                              ((bracketTable[((unsigned int)(int)ch & SECUREC_CHAR_MASK) >> 3] ^ tableMask) &
1183                               (1 << (ch & 7)))
1184#else
1185                              ((bracketTable[((unsigned char)ch & 0xff) >> 3] ^ tableMask) & (1 << (ch & 7)))
1186#endif
1187                             ))) {
1188                            if (suppress == 0) {
1189                                if (arrayWidth == 0) {
1190                                    /* We have exhausted the user's buffer */
1191
1192                                    errNoMem = 1;
1193                                    break;
1194                                }
1195                                SECUREC_CHECK_INPUT_ADDR(argPtr);
1196
1197#ifdef SECUREC_FOR_WCHAR
1198                                if (isWchar > 0) {
1199                                    *(wchar_t UNALIGNED *)argPtr = (wchar_t)ch;
1200                                    argPtr = (wchar_t *)argPtr + 1;
1201                                    --arrayWidth;
1202                                } else {
1203                                    int temp = 0;
1204                                    if (arrayWidth >= ((size_t)MB_CUR_MAX)) {
1205                                        SECUREC_MASK_MSVC_CRT_WARNING
1206                                        temp = wctomb((char *)argPtr, (wchar_t)ch);
1207                                        SECUREC_END_MASK_MSVC_CRT_WARNING
1208                                    } else {
1209                                        char tmpBuf[SECUREC_MB_LEN + 1];
1210                                        SECUREC_MASK_MSVC_CRT_WARNING temp = wctomb(tmpBuf, (wchar_t)ch);
1211                                        SECUREC_END_MASK_MSVC_CRT_WARNING
1212                                        if (temp > 0 && ((size_t)(unsigned int)temp) > arrayWidth) {
1213                                            errNoMem = 1;
1214                                            break;
1215                                        }
1216                                        if (temp > 0 && ((size_t)(unsigned int)temp) <= sizeof(tmpBuf)) {
1217                                            if (EOK != memcpy_s(argPtr, arrayWidth,
1218                                                                tmpBuf, (size_t)(unsigned int)temp)) {
1219                                                errNoMem = 1;
1220                                                break;
1221                                            }
1222                                        }
1223                                    }
1224                                    if (temp > 0) {
1225                                        /* if wctomb  error, then ignore character */
1226                                        argPtr = (char *)argPtr + temp;
1227                                        arrayWidth -= (size_t)(unsigned int)temp;
1228                                    }
1229                                }
1230#else
1231
1232                                if (isWchar > 0) {
1233                                    wchar_t tempWchar = L'?';   /* set default char as ? */
1234                                    char temp[SECUREC_MULTI_BYTE_MAX_LEN + 1];
1235                                    temp[0] = (char)ch;
1236                                    temp[1] = '\0';
1237#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
1238                                    if (SecIsleadbyte(ch)) {
1239                                        temp[1] = (char)SECUREC_GET_CHAR();
1240                                        temp[2] = '\0';
1241                                    }
1242                                    if (mbtowc(&tempWchar, temp, sizeof(temp)) <= 0) {
1243                                        /* no string termination error for tool */
1244                                        tempWchar = L'?';
1245                                    }
1246#else
1247                                    if (SecIsleadbyte(ch)) {
1248                                        int convRes = 0;
1249                                        int di = 1;
1250                                        /* in Linux like system, the string is encoded in UTF-8 */
1251                                        while (di < (int)MB_CUR_MAX && di < SECUREC_MULTI_BYTE_MAX_LEN) {
1252                                            temp[di++] = (char)SECUREC_GET_CHAR();
1253                                            temp[di] = '\0';
1254                                            convRes = mbtowc(&tempWchar, temp, sizeof(temp));
1255                                            if (convRes > 0) {
1256                                                break;  /* convert succeed */
1257                                            }
1258                                        }
1259                                        if (convRes <= 0) {
1260                                            tempWchar = L'?';
1261                                        }
1262                                    } else {
1263                                        if (mbtowc(&tempWchar, temp, sizeof(temp)) <= 0) {
1264                                            /* no string termination error for tool */
1265                                            tempWchar = L'?';
1266                                        }
1267                                    }
1268#endif
1269
1270                                    *(wchar_t UNALIGNED *)argPtr = tempWchar;
1271                                    /* just copy L'?' if mbtowc fails, errno is set by mbtowc */
1272                                    argPtr = (wchar_t *)argPtr + 1;
1273                                    --arrayWidth;
1274
1275                                 } else {
1276                                    *(char *)argPtr = (char)ch;
1277                                    argPtr = (char *)argPtr + 1;
1278                                    --arrayWidth;
1279                                 }
1280#endif
1281                            } else {
1282                                /* suppress */
1283                                /* this is OK ,Used to identify processed data for %* ,use size_t just  clear e613 */
1284                                startPtr = (SecChar *) (size_t)1 + (size_t)argPtr;
1285                            }
1286                        } else {
1287                            SECUREC_UN_GET_CHAR(ch);
1288                            break;
1289                        }
1290                    }
1291
1292                    if (errNoMem != 0) {
1293                        /* In case of error, blank out the input buffer */
1294                        if (isWchar > 0) {
1295                            if (startPtr != NULL) {
1296                                *(wchar_t UNALIGNED *)startPtr = 0;
1297                            }
1298                        } else {
1299                            if (startPtr != NULL) {
1300                                *(char *)startPtr = 0;
1301                            }
1302                        }
1303
1304                        goto ERR_RET;
1305                    }
1306
1307                    if (startPtr != argPtr) {
1308                        if (suppress == 0) {
1309
1310                            SECUREC_CHECK_INPUT_ADDR(argPtr);
1311
1312                            if (comChr != 'c') {
1313                                /* null-terminate strings */
1314                                if (isWchar > 0) {
1315                                    *(wchar_t UNALIGNED *)argPtr = L'\0';
1316                                } else {
1317                                    *(char *)argPtr = '\0';
1318                                }
1319                            }
1320                            ++doneCount;
1321                        }
1322
1323                    } else {
1324                        goto ERR_RET;
1325                    }
1326
1327                    break;
1328                case SECUREC_CHAR('p'):
1329                    /* make %hp same as %p */
1330                    numberWidth = SECUREC_NUM_WIDTH_INT;
1331#ifdef SECUREC_ON_64BITS
1332                    isInt64Arg = 1;
1333#endif
1334                    /* fall-through */
1335                    /* FALLTHRU */
1336                case SECUREC_CHAR('o'):    /* fall-through */ /* FALLTHRU */
1337                case SECUREC_CHAR('u'):    /* fall-through */ /* FALLTHRU */
1338                case SECUREC_CHAR('d'):    /* fall-through */ /* FALLTHRU */
1339                case SECUREC_CHAR('i'):    /* fall-through */ /* FALLTHRU */
1340                case SECUREC_CHAR('x'):
1341                    if (ch == SECUREC_CHAR('+') || ch == SECUREC_CHAR('-')) {
1342                        if (ch == SECUREC_CHAR('-')) {
1343                            numberSpec.negative = 1;
1344                        }
1345                        if (--width == 0 && widthSet != 0) {
1346                            doneFlag = 1;
1347                        } else {
1348                            ch = SECUREC_GET_CHAR();
1349                        }
1350                    }
1351
1352                    if (comChr == SECUREC_CHAR('x') || comChr == SECUREC_CHAR('i')) {
1353                        if (comChr == SECUREC_CHAR('i')) {
1354                            /* i could be d, o, or x, use d as default */
1355                            comChr = SECUREC_CHAR('d');
1356                        }
1357                        if (ch == SECUREC_CHAR('0')) {
1358                            ch = SECUREC_GET_CHAR();
1359                            if ((SecChar) (ch) == SECUREC_CHAR('x') || (SecChar) ch == SECUREC_CHAR('X')) {
1360                                ch = SECUREC_GET_CHAR();
1361                                if (widthSet != 0) {
1362                                    width -= 2;
1363                                    if (width < 1) {
1364                                        doneFlag = 1;
1365                                    }
1366                                }
1367                                comChr = SECUREC_CHAR('x');
1368                            } else {
1369                                started = 1;
1370                                if (comChr != SECUREC_CHAR('x')) {
1371                                    if (widthSet != 0 && --width == 0) {
1372                                        doneFlag = 1;
1373                                    }
1374                                    comChr = SECUREC_CHAR('o');
1375                                } else {
1376                                    SECUREC_UN_GET_CHAR(ch);
1377                                    ch = SECUREC_CHAR('0');
1378                                }
1379                            }
1380                        }
1381                    }
1382
1383                    /* scanNumber: */
1384                    if (isInt64Arg != 0) {
1385                        while (doneFlag == 0) {
1386                            /* decode ch to number64 */
1387                            doneFlag = SecDecodeNumber64(comChr, ch, &numberSpec);
1388
1389                            if (doneFlag == 0) {
1390                                started = 1;
1391
1392                                if (widthSet != 0 && --width == 0) {
1393                                    doneFlag = 1;
1394                                } else {
1395                                    ch = SECUREC_GET_CHAR();
1396                                }
1397                            } else {
1398                                SECUREC_UN_GET_CHAR(ch);
1399                            }
1400
1401                        }       /* end of WHILE loop */
1402
1403                        /* Handling integer negative numbers and beyond max */
1404
1405                        SecFinishNumber64(oricomChr, &numberSpec);
1406
1407                    }
1408                    /* do not use else , Otherwise, the vxworks55 arm926ej compiler will crash. */
1409                    if (isInt64Arg == 0) {
1410                        while (doneFlag == 0) {
1411                            /* decode ch to number */
1412                            doneFlag = SecDecodeNumber(comChr, ch, &numberSpec);
1413                            if (doneFlag == 0) {
1414                                started = 1;
1415
1416                                if (widthSet != 0 && --width == 0) {
1417                                    doneFlag = 1;
1418                                } else {
1419                                    ch = SECUREC_GET_CHAR();
1420                                }
1421                            } else {
1422                                SECUREC_UN_GET_CHAR(ch);
1423                            }
1424                        }       /* end of WHILE loop */
1425
1426                        /* Handling integer negative numbers and beyond max */
1427
1428                        SecFinishNumber(oricomChr, numberWidth, &numberSpec);
1429
1430                    }
1431
1432                    if (comChr == SECUREC_CHAR('F')) {  /* expected ':' in long pointer */
1433                        started = 0;
1434                    }
1435
1436                    if (started != 0) {
1437                        if (suppress == 0) {
1438                            SECUREC_CHECK_INPUT_ADDR(argPtr);
1439
1440                            if (isInt64Arg != 0) {
1441#if defined(SECUREC_VXWORKS_PLATFORM)
1442                                /* take number64 as unsigned number */
1443                                *(SecInt64 UNALIGNED *)argPtr = *(SecUnsignedInt64 *)(&numberSpec.number64);
1444#else
1445                                /* take number64 as unsigned number */
1446                                *(SecInt64 UNALIGNED *)argPtr = (SecInt64)numberSpec.number64;
1447#endif
1448                            } else {
1449                                SecAssignNumber(argPtr, numberWidth, numberSpec.number);
1450                            }
1451                            ++doneCount;
1452                        }
1453                        /* remove blank else */
1454                    } else {
1455                        goto ERR_RET;
1456                    }
1457                    break;
1458
1459                case SECUREC_CHAR('n'):    /* char count */
1460                    if (suppress == 0) {
1461                        SECUREC_CHECK_INPUT_ADDR(argPtr);
1462                        SecAssignNumber(argPtr, numberWidth, (unsigned long)(unsigned int)charCount);
1463                    }
1464                    break;
1465
1466                case SECUREC_CHAR('e'):    /* fall-through */ /* FALLTHRU */
1467                case SECUREC_CHAR('f'):    /* fall-through */ /* FALLTHRU */
1468                case SECUREC_CHAR('g'):    /* scan a float */
1469
1470                    floatStrUsedLen = 0;
1471
1472                    if (ch == SECUREC_CHAR('-')) {
1473                        pFloatStr[floatStrUsedLen++] = SECUREC_CHAR('-');
1474                        --width;
1475                        ch = SECUREC_GET_CHAR();
1476
1477                    } else if (ch == SECUREC_CHAR('+')) {
1478                        --width;
1479                        ch = SECUREC_GET_CHAR();
1480                    }
1481
1482                    if (widthSet == 0) {    /* must care width */
1483                        width = -1;
1484                    }
1485
1486                    /* now get integral part */
1487                    while (SECUREC_IS_DIGIT(ch) && width-- != 0) {
1488                        started = 1;
1489                        pFloatStr[floatStrUsedLen++] = (SecChar) ch;    /* ch must be '0' - '9' */
1490                        if (SecUpdateFloatString(floatStrUsedLen,
1491                                                 &floatStrSize, &pFloatStr, floatStrBuffer, &pAllocedFloatStr) == 0) {
1492                            goto ERR_RET;
1493                        }
1494                        ch = SECUREC_GET_CHAR();
1495                    }
1496
1497#ifdef SECUREC_FOR_WCHAR
1498                    /* convert decimal point(.) to wide-char */
1499                    decimal = L'.';
1500                    if (mbtowc(&decimal, SECUREC_DECIMAL_POINT_PTR, (size_t)MB_CUR_MAX) <= 0) {
1501                        decimal = L'.';
1502                    }
1503#else
1504                    decimal = *SECUREC_DECIMAL_POINT_PTR;   /* if locale.h NOT exist, let decimal = '.' */
1505#endif
1506
1507                    if (SecCheckFloatDecPoint((char)decimal) != 1) {
1508                        goto ERR_RET;
1509                    }
1510
1511                    /* now check for decimal */
1512                    if (decimal == (char)ch && width-- != 0) {
1513                        ch = SECUREC_GET_CHAR();
1514                        pFloatStr[floatStrUsedLen++] = decimal;
1515                        if (SecUpdateFloatString(floatStrUsedLen,
1516                                                 &floatStrSize, &pFloatStr, floatStrBuffer, &pAllocedFloatStr) == 0) {
1517                            goto ERR_RET;
1518                        }
1519                        while (SECUREC_IS_DIGIT(ch) && width-- != 0) {
1520                            started = 1;
1521                            pFloatStr[floatStrUsedLen++] = (SecChar) ch;
1522                            if (SecUpdateFloatString(floatStrUsedLen,
1523                                                     &floatStrSize,
1524                                                     &pFloatStr, floatStrBuffer, &pAllocedFloatStr) == 0) {
1525                                goto ERR_RET;
1526                            }
1527                            ch = SECUREC_GET_CHAR();
1528                        }
1529                    }
1530
1531                    /* now check for exponent */
1532
1533                    if (started != 0 && (ch == SECUREC_CHAR('e') || ch == SECUREC_CHAR('E')) && width-- != 0) {
1534                        pFloatStr[floatStrUsedLen++] = SECUREC_CHAR('e');
1535                        if (SecUpdateFloatString(floatStrUsedLen,
1536                                                 &floatStrSize, &pFloatStr, floatStrBuffer, &pAllocedFloatStr) == 0) {
1537                            goto ERR_RET;
1538                        }
1539
1540                        ch = SECUREC_GET_CHAR();
1541                        if (ch == SECUREC_CHAR('+') || ch == SECUREC_CHAR('-')) {
1542                            if (ch == SECUREC_CHAR('-')) {
1543
1544                                pFloatStr[floatStrUsedLen++] = SECUREC_CHAR('-');
1545                                if (SecUpdateFloatString(floatStrUsedLen,
1546                                                         &floatStrSize,
1547                                                         &pFloatStr, floatStrBuffer, &pAllocedFloatStr) == 0) {
1548                                    goto ERR_RET;
1549                                }
1550                            }
1551
1552                            if (width != 0) {
1553                                ch = SECUREC_GET_CHAR();
1554                                --width;
1555                            }
1556                        }
1557
1558                        while (SECUREC_IS_DIGIT(ch) && width-- != 0) {
1559                            pFloatStr[floatStrUsedLen++] = (SecChar) ch;
1560                            if (SecUpdateFloatString(floatStrUsedLen,
1561                                                     &floatStrSize,
1562                                                     &pFloatStr, floatStrBuffer, &pAllocedFloatStr) == 0) {
1563                                goto ERR_RET;
1564                            }
1565                            ch = SECUREC_GET_CHAR();
1566                        }
1567
1568                    }
1569
1570                    SECUREC_UN_GET_CHAR(ch);
1571
1572                    if (started != 0) {
1573                        if (suppress == 0) {
1574                            SECUREC_CHECK_INPUT_ADDR(argPtr);
1575
1576                            /* Make sure  have a string terminator */
1577                            pFloatStr[floatStrUsedLen] = SECUREC_CHAR('\0');
1578#ifdef SECUREC_FOR_WCHAR
1579                            {
1580                                /* convert float string */
1581                                size_t mbsLen;
1582                                size_t tempFloatStrLen = (size_t)(floatStrSize + 1) * sizeof(wchar_t);
1583                                char *tempFloatStr = (char *)SECUREC_MALLOC(tempFloatStrLen);
1584
1585                                if (tempFloatStr == NULL) {
1586                                    goto ERR_RET;
1587                                }
1588                                tempFloatStr[0] = '\0';
1589                                SECUREC_MASK_MSVC_CRT_WARNING
1590                                mbsLen = wcstombs(tempFloatStr, pFloatStr, tempFloatStrLen - 1);
1591                                SECUREC_END_MASK_MSVC_CRT_WARNING
1592                                if (mbsLen != (size_t)-1) {
1593                                    tempFloatStr[mbsLen] = '\0';
1594                                    SecAssignFloat(numberWidth, argPtr, tempFloatStr);
1595                                } else {
1596                                    SECUREC_FREE(tempFloatStr);
1597                                    goto ERR_RET;
1598                                }
1599                                SECUREC_FREE(tempFloatStr);
1600                            }
1601#else
1602                            SecAssignFloat(numberWidth, argPtr, pFloatStr);
1603#endif
1604                            ++doneCount;
1605                        }
1606                        /* remove blank else */ /* NULL */
1607                    } else {
1608                        goto ERR_RET;
1609                    }
1610
1611                    break;
1612                default:
1613                    if ((int)*format != (int)ch) {
1614                        SECUREC_UN_GET_CHAR(ch);
1615                        /* to clear e438 last value assigned not used , the compiler will optimize this code */
1616                        (void)charCount;
1617                        formatError = 1;
1618                        goto ERR_RET;
1619                    } else {
1620                        --match;
1621                    }
1622
1623                    if (suppress == 0) {
1624#if defined(va_copy)
1625                        va_copy(arglist, arglistSave);
1626                        arglistBeenCopied = 1;
1627                        va_end(arglistSave);
1628#elif defined(__va_copy)        /* for vxworks */
1629                        __va_copy(arglist, arglistSave);
1630                        arglistBeenCopied = 1;
1631                        va_end(arglistSave);
1632#else
1633                        arglist = arglistSave;
1634#endif
1635                    }
1636                }
1637
1638                ++match;
1639
1640            }
1641
1642            else {
1643                /* 0 width in format */
1644                SECUREC_UN_GET_CHAR(ch);
1645                /* to clear e438 last value assigned not used , the compiler will optimize this code */
1646                (void)charCount;
1647                goto ERR_RET;
1648            }
1649
1650            ++format;
1651        } else {
1652            ch = SECUREC_GET_CHAR();
1653            if ((int)*format++ != (int)(ch)) {
1654                SECUREC_UN_GET_CHAR(ch);
1655                /* to clear e438 last value assigned not used , the compiler will optimize this code */
1656                (void)charCount;
1657                goto ERR_RET;
1658            }
1659#ifndef SECUREC_FOR_WCHAR
1660            /* The purpose of type conversion is to avoid warnings */
1661            if (SecIsleadbyte(ch)) {
1662                char temp[SECUREC_MULTI_BYTE_MAX_LEN];
1663                wchar_t tempWchar = L'\0';
1664                int ch2 = SECUREC_GET_CHAR();
1665
1666                if ((int)*format++ != (ch2)) {
1667                    SECUREC_UN_GET_CHAR(ch2);   /* LSD in console mode, ungetc twice will cause problem */
1668                    SECUREC_UN_GET_CHAR(ch);
1669                    /* to clear e438 last value assigned not used , the compiler will optimize this code */
1670                    (void)charCount;
1671                    goto ERR_RET;
1672                }
1673                if (MB_CUR_MAX > 2 && (((unsigned char)ch & 0xE0) == 0xE0) && (((unsigned char)ch2 & 0x80) == 0x80)) {
1674                    /* this char is very likely to be a UTF-8 char */
1675                    int ch3 = SECUREC_GET_CHAR();
1676                    temp[0] = (char)ch;
1677                    temp[1] = (char)ch2;
1678                    temp[2] = (char)ch3;
1679                    temp[3] = '\0';
1680
1681                    if (mbtowc(&tempWchar, temp, sizeof(temp)) > 0) {
1682                        /* succeed */
1683                        if ((int)*format++ != (int)ch3) {
1684                            SECUREC_UN_GET_CHAR(ch3);
1685                            /* to clear e438 last value assigned not used , the compiler will optimize this code */
1686                            (void)charCount;
1687                            goto ERR_RET;
1688                        }
1689                        --charCount;
1690                    } else {
1691                        SECUREC_UN_GET_CHAR(ch3);
1692                    }
1693                }
1694                --charCount;    /* only count as one character read */
1695            }
1696#endif /* SECUREC_FOR_WCHAR */
1697        }
1698
1699        if ((ch == SECUREC_EOF) && ((*format != SECUREC_CHAR('%')) || (*(format + 1) != SECUREC_CHAR('n')))) {
1700            break;
1701        }
1702
1703    }
1704
1705ERR_RET:
1706#ifdef SECUREC_FOR_WCHAR
1707    if (bracketTable != NULL) {
1708        SECUREC_FREE(bracketTable);
1709        bracketTable = NULL;
1710        (void)bracketTable;     /* to clear e438 last value assigned not used , the compiler will optimize this code */
1711    }
1712#endif
1713
1714#if defined(va_copy) || defined(__va_copy)
1715    if (arglistBeenCopied != 0) {
1716        va_end(arglist);
1717        (void)arglist;          /* to clear e438 last value assigned not used , the compiler will optimize this code */
1718    }
1719#endif
1720    va_end(arglistSave);
1721    (void)arglistSave;          /* to clear e438 last value assigned not used , the compiler will optimize this code */
1722
1723    /* LSD 2014.3.6 add, clear the stack data */
1724    if (memset_s(floatStrBuffer, sizeof(floatStrBuffer), 0, sizeof(floatStrBuffer)) != EOK) {
1725        doneCount = 0;          /* This is a dead code, just to meet the coding requirements */
1726    }
1727    if (pAllocedFloatStr != NULL) {
1728        /* pFloatStr can be allocated in SecUpdateFloatString function, clear and free it */
1729        if (memset_s(pAllocedFloatStr, floatStrSize * sizeof(SecChar), 0, floatStrSize * sizeof(SecChar)) != EOK) {
1730            doneCount = 0;      /* This is a dead code, just to meet the coding requirements */
1731        }
1732        SECUREC_FREE(pAllocedFloatStr);
1733        pAllocedFloatStr = NULL;
1734        (void)pAllocedFloatStr; /* to clear e438 last value assigned not used , the compiler will optimize this code */
1735    }
1736
1737    SecAdjustStream(stream);
1738
1739    if (ch == SECUREC_EOF) {
1740        return ((doneCount || match) ? doneCount : EOF);
1741    } else if (formatError != 0 || paraIsNull != 0) {
1742        /* Invalid Input Format or parameter */
1743        return SECUREC_SCANF_ERROR_PARA;
1744    }
1745
1746    return doneCount;
1747}
1748
1749#ifdef SECUREC_FOR_WCHAR
1750static SecInt SecGetCharW(SecFileStream *str)
1751#else
1752static SecInt SecGetChar(SecFileStream *str)
1753#endif
1754{
1755
1756    SecInt ch = 0;
1757    int firstReadOnFile = 0;
1758    do {
1759        if ((str->flag & SECUREC_FROM_STDIN_FLAG) > 0) {
1760#if defined(SECUREC_NO_STD_UNGETC)
1761            if (str->fUnget == 1) {
1762                ch = (SecInt) str->lastChar;
1763                str->fUnget = 0;
1764
1765            } else {
1766                ch = SECUREC_GETC(str->pf);
1767                str->lastChar = (unsigned int)ch;
1768
1769            }
1770#else
1771            ch = SECUREC_GETC(str->pf);
1772#endif
1773            break;
1774        } else if ((str->flag & SECUREC_FILE_STREAM_FLAG) > 0 && str->count == 0) {
1775            /* load file to buffer */
1776            if (str->base == NULL) {
1777                str->base = (char *)SECUREC_MALLOC(SECUREC_BUFFERED_BLOK_SIZE + 1);
1778                if (str->base == NULL) {
1779                    ch = SECUREC_EOF;
1780                    break;
1781                }
1782                str->base[SECUREC_BUFFERED_BLOK_SIZE] = '\0';   /* for tool Warning string null */
1783            }
1784            /* LSD add 2014.3.21 */
1785            if (str->oriFilePos == SECUREC_UNINITIALIZED_FILE_POS) {
1786                str->oriFilePos = ftell(str->pf);   /* save original file read position */
1787                firstReadOnFile = 1;
1788            }
1789            str->count = (int)fread(str->base, (size_t)1, (size_t)SECUREC_BUFFERED_BLOK_SIZE, str->pf);
1790            str->base[SECUREC_BUFFERED_BLOK_SIZE] = '\0';   /* for tool Warning string null */
1791            if (str->count == 0 || str->count > SECUREC_BUFFERED_BLOK_SIZE) {
1792                ch = SECUREC_EOF;
1793                break;
1794            }
1795            str->cur = str->base;
1796            str->flag |= SECUREC_LOAD_FILE_TO_MEM_FLAG;
1797            if (firstReadOnFile != 0) {
1798#ifdef SECUREC_FOR_WCHAR
1799
1800                if (str->count > 1
1801                    && (((unsigned char)(str->base[0]) == 0xFFU && (unsigned char)(str->base[1]) == 0xFEU)
1802                        || ((unsigned char)(str->base[0]) == 0xFEU && (unsigned char)(str->base[1]) == 0xFFU))) {
1803                    /* it's BOM header, UNICODE little endian */
1804                    str->count -= SECUREC_BOM_HEADER_SIZE;
1805                    if (memmove_s(str->base, (size_t)SECUREC_BUFFERED_BLOK_SIZE,
1806                                  str->base + SECUREC_BOM_HEADER_SIZE, (size_t)(unsigned int)str->count) != EOK) {
1807                        ch = SECUREC_EOF;
1808                        break;
1809                    }
1810
1811                    if (str->count % (int)sizeof(SecChar)) {
1812                        /* the str->count must be a  multiple of  sizeof(SecChar),
1813                         * otherwise this function will return SECUREC_EOF when read the last character
1814                         */
1815                        int ret = (int)fread(str->base + str->count, (size_t)1,
1816                                             (size_t)SECUREC_BOM_HEADER_SIZE, str->pf);
1817                        if (ret > 0 && ret <= SECUREC_BUFFERED_BLOK_SIZE) {
1818                            str->count += ret;
1819                        }
1820                    }
1821                }
1822
1823#else
1824                if (str->count > 2 && (unsigned char)(str->base[0]) == 0xEFU &&
1825                    (unsigned char)(str->base[1]) == 0xBBU && (unsigned char)(str->base[2]) == 0xBFU) {
1826                    /* it's BOM header,  little endian */
1827                    str->count -= SECUREC_UTF8_BOM_HEADER_SIZE;
1828                    str->cur += SECUREC_UTF8_BOM_HEADER_SIZE;
1829                }
1830#endif
1831            }
1832        }
1833
1834        if ((str->flag & SECUREC_MEM_STR_FLAG) > 0 || (str->flag & SECUREC_LOAD_FILE_TO_MEM_FLAG) > 0) {
1835            /* according  wchar_t has two bytes */
1836            ch = (SecInt)((str->count -= (int)sizeof(SecChar)) >= 0 ? \
1837                          (SecInt) (SECUREC_CHAR_MASK & *((const SecChar *)(const void *)str->cur)) : SECUREC_EOF);
1838            str->cur += sizeof(SecChar);
1839        }
1840        /* use break in do-while to skip some code */
1841    } SECUREC_WHILE_ZERO;
1842
1843
1844    if (ch != SECUREC_EOF && (str->flag & SECUREC_FILE_STREAM_FLAG) > 0 && str->base) {
1845        str->fileRealRead += (int)sizeof(SecChar);
1846    }
1847    return ch;
1848
1849}
1850
1851static void SecUnGetCharImpl(SecInt chr, SecFileStream *str)
1852{
1853    if ((str->flag & SECUREC_FROM_STDIN_FLAG) > 0) {
1854#if defined(SECUREC_NO_STD_UNGETC)
1855        str->lastChar = (unsigned int)chr;
1856        str->fUnget = 1;
1857#else
1858        (void)SECUREC_UN_GETC(chr, str->pf);
1859#endif
1860    } else if ((str->flag & SECUREC_MEM_STR_FLAG) || (str->flag & SECUREC_LOAD_FILE_TO_MEM_FLAG) > 0) {
1861        if (str->cur > str->base) {
1862            str->cur -= sizeof(SecChar);
1863            str->count += (int)sizeof(SecChar);
1864        }
1865    }
1866
1867    if ((str->flag & SECUREC_FILE_STREAM_FLAG) > 0 && str->base) {
1868        /* LSD fix, change from -- str->fileRealRead to str->fileRealRead -= sizeof(SecChar). 2014.2.21 */
1869        str->fileRealRead -= (int)sizeof(SecChar);
1870    }
1871
1872}
1873
1874#ifdef SECUREC_FOR_WCHAR
1875static void SecUnGetCharW(SecInt chr, SecFileStream *str)
1876#else
1877static void SecUnGetChar(SecInt chr, SecFileStream *str)
1878#endif
1879{
1880    if (chr != SECUREC_EOF) {
1881        SecUnGetCharImpl(chr, str);
1882    }
1883}
1884
1885static SecInt SecSkipSpaceChar(int *counter, SecFileStream *fileptr)
1886{
1887    SecInt ch;
1888
1889    do {
1890        ++(*counter);
1891#ifdef SECUREC_FOR_WCHAR
1892        ch = SecGetCharW(fileptr);
1893#else
1894        ch = SecGetChar(fileptr);
1895#endif
1896        if (ch == SECUREC_EOF) {
1897            break;
1898        }
1899    }
1900#ifdef SECUREC_FOR_WCHAR
1901    while (iswspace((wint_t) ch));
1902#else
1903    while (isspace((SecUnsignedChar) ch));
1904#endif
1905    return ch;
1906}
1907
1908#endif /* __INPUT_INL__5D13A042_DC3F_4ED9_A8D1_882811274C27 */
1909
1910
1911