input.inl 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229
  1. /*
  2. * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
  3. * Licensed under Mulan PSL v2.
  4. * You can use this software according to the terms and conditions of the Mulan PSL v2.
  5. * You may obtain a copy of Mulan PSL v2 at:
  6. * http://license.coscl.org.cn/MulanPSL2
  7. * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
  8. * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
  9. * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
  10. * See the Mulan PSL v2 for more details.
  11. * Description: Used by secureinput_a.c and secureinput_w.c to include.
  12. * This file provides a template function for ANSI and UNICODE compiling by
  13. * different type definition. The functions of SecInputS or
  14. * SecInputSW provides internal implementation for scanf family API, such as sscanf_s, fscanf_s.
  15. * Create: 2014-02-25
  16. * Notes: The formatted input processing results of integers on different platforms are different.
  17. */
  18. /*
  19. * [Standardize-exceptions] Use unsafe function: Performance-sensitive
  20. * [reason] Always used in the performance critical path,
  21. * and sufficient input validation is performed before calling
  22. */
  23. #ifndef INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27
  24. #define INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27
  25. #if SECUREC_IN_KERNEL
  26. #if !defined(SECUREC_CTYPE_MACRO_ADAPT)
  27. #include <linux/ctype.h>
  28. #endif
  29. #else
  30. #if !defined(SECUREC_SYSAPI4VXWORKS) && !defined(SECUREC_CTYPE_MACRO_ADAPT)
  31. #include <ctype.h>
  32. #ifdef SECUREC_FOR_WCHAR
  33. #include <wctype.h> /* For iswspace */
  34. #endif
  35. #endif
  36. #endif
  37. #ifndef EOF
  38. #define EOF (-1)
  39. #endif
  40. #define SECUREC_NUM_WIDTH_SHORT 0
  41. #define SECUREC_NUM_WIDTH_INT 1
  42. #define SECUREC_NUM_WIDTH_LONG 2
  43. #define SECUREC_NUM_WIDTH_LONG_LONG 3 /* Also long double */
  44. #define SECUREC_BUFFERED_BLOK_SIZE 1024U
  45. #if defined(SECUREC_VXWORKS_PLATFORM) && !defined(va_copy) && !defined(__va_copy)
  46. /* The name is the same as system macro. */
  47. #define __va_copy(dest, src) do { \
  48. size_t destSize_ = (size_t)sizeof(dest); \
  49. size_t srcSize_ = (size_t)sizeof(src); \
  50. if (destSize_ != srcSize_) { \
  51. SECUREC_MEMCPY_WARP_OPT((dest), (src), sizeof(va_list)); \
  52. } else { \
  53. SECUREC_MEMCPY_WARP_OPT(&(dest), &(src), sizeof(va_list)); \
  54. } \
  55. } SECUREC_WHILE_ZERO
  56. #endif
  57. #define SECUREC_MULTI_BYTE_MAX_LEN 6
  58. /* Compatibility macro name cannot be modifie */
  59. #ifndef UNALIGNED
  60. #if !(defined(_M_IA64)) && !(defined(_M_AMD64))
  61. #define UNALIGNED
  62. #else
  63. #define UNALIGNED __unaligned
  64. #endif
  65. #endif
  66. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  67. /* Max 64bit value is 0xffffffffffffffff */
  68. #define SECUREC_MAX_64BITS_VALUE 18446744073709551615ULL
  69. #define SECUREC_MAX_64BITS_VALUE_DIV_TEN 1844674407370955161ULL
  70. #define SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT 18446744073709551610ULL
  71. #define SECUREC_MIN_64BITS_NEG_VALUE 9223372036854775808ULL
  72. #define SECUREC_MAX_64BITS_POS_VALUE 9223372036854775807ULL
  73. #define SECUREC_MIN_32BITS_NEG_VALUE 2147483648UL
  74. #define SECUREC_MAX_32BITS_POS_VALUE 2147483647UL
  75. #define SECUREC_MAX_32BITS_VALUE 4294967295UL
  76. #define SECUREC_MAX_32BITS_VALUE_INC 4294967296UL
  77. #define SECUREC_MAX_32BITS_VALUE_DIV_TEN 429496729UL
  78. #define SECUREC_LONG_BIT_NUM ((unsigned int)(sizeof(long) << 3U))
  79. /* Use ULL to clean up cl6x compilation alerts */
  80. #define SECUREC_MAX_LONG_POS_VALUE ((unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1)) - 1)
  81. #define SECUREC_MIN_LONG_NEG_VALUE ((unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1)))
  82. /* Covert to long long to clean up cl6x compilation alerts */
  83. #define SECUREC_LONG_HEX_BEYOND_MAX(number) (((unsigned long long)(number) >> (SECUREC_LONG_BIT_NUM - 4U)) > 0)
  84. #define SECUREC_LONG_OCTAL_BEYOND_MAX(number) (((unsigned long long)(number) >> (SECUREC_LONG_BIT_NUM - 3U)) > 0)
  85. #define SECUREC_QWORD_HEX_BEYOND_MAX(number) (((number) >> (64U - 4U)) > 0)
  86. #define SECUREC_QWORD_OCTAL_BEYOND_MAX(number) (((number) >> (64U - 3U)) > 0)
  87. #define SECUREC_LP64_BIT_WIDTH 64
  88. #define SECUREC_LP32_BIT_WIDTH 32
  89. #define SECUREC_CONVERT_IS_SIGNED(conv) ((conv) == 'd' || (conv) == 'i')
  90. #endif
  91. #define SECUREC_BRACE '{' /* [ to { */
  92. #define SECUREC_FILED_WIDTH_ENOUGH(spec) ((spec)->widthSet == 0 || (spec)->width > 0)
  93. #define SECUREC_FILED_WIDTH_DEC(spec) do { \
  94. if ((spec)->widthSet != 0) { \
  95. --(spec)->width; \
  96. } \
  97. } SECUREC_WHILE_ZERO
  98. #ifdef SECUREC_FOR_WCHAR
  99. /* Bits for all wchar, size is 65536/8, only supports wide characters with a maximum length of two bytes */
  100. #define SECUREC_BRACKET_TABLE_SIZE 8192
  101. #define SECUREC_EOF WEOF
  102. #define SECUREC_MB_LEN 16 /* Max. # bytes in multibyte char ,see MB_LEN_MAX */
  103. #else
  104. /* Bits for all char, size is 256/8 */
  105. #define SECUREC_BRACKET_TABLE_SIZE 32
  106. #define SECUREC_EOF EOF
  107. #endif
  108. #if SECUREC_HAVE_WCHART
  109. #define SECUREC_ARRAY_WIDTH_IS_WRONG(spec) ((spec).arrayWidth == 0 || \
  110. ((spec).isWCharOrLong <= 0 && (spec).arrayWidth > SECUREC_STRING_MAX_LEN) || \
  111. ((spec).isWCharOrLong > 0 && (spec).arrayWidth > SECUREC_WCHAR_STRING_MAX_LEN))
  112. #else
  113. #define SECUREC_ARRAY_WIDTH_IS_WRONG(spec) ((spec).arrayWidth == 0 || (spec).arrayWidth > SECUREC_STRING_MAX_LEN)
  114. #endif
  115. #ifdef SECUREC_ON_64BITS
  116. /* Use 0xffffffffUL mask to pass integer as array length */
  117. #define SECUREC_GET_ARRAYWIDTH(argList) (((size_t)va_arg((argList), size_t)) & 0xffffffffUL)
  118. #else /* !SECUREC_ON_64BITS */
  119. #define SECUREC_GET_ARRAYWIDTH(argList) ((size_t)va_arg((argList), size_t))
  120. #endif
  121. typedef struct {
  122. #ifdef SECUREC_FOR_WCHAR
  123. unsigned char *table; /* Default NULL */
  124. #else
  125. unsigned char table[SECUREC_BRACKET_TABLE_SIZE]; /* Array length is large enough in application scenarios */
  126. #endif
  127. unsigned char mask; /* Default 0 */
  128. } SecBracketTable;
  129. #ifdef SECUREC_FOR_WCHAR
  130. #define SECUREC_INIT_BRACKET_TABLE { NULL, 0 }
  131. #else
  132. #define SECUREC_INIT_BRACKET_TABLE { {0}, 0 }
  133. #endif
  134. #if SECUREC_ENABLE_SCANF_FLOAT
  135. typedef struct {
  136. size_t floatStrTotalLen; /* Initialization must be length of buffer in charater */
  137. size_t floatStrUsedLen; /* Store float string len */
  138. SecChar *floatStr; /* Initialization must point to buffer */
  139. SecChar *allocatedFloatStr; /* Initialization must be NULL to store alloced point */
  140. SecChar buffer[SECUREC_FLOAT_BUFSIZE + 1];
  141. } SecFloatSpec;
  142. #endif
  143. #define SECUREC_NUMBER_STATE_DEFAULT 0U
  144. #define SECUREC_NUMBER_STATE_STARTED 1U
  145. typedef struct {
  146. SecInt ch; /* Char read from input */
  147. int charCount; /* Number of characters processed */
  148. void *argPtr; /* Variable parameter pointer, point to the end of the string */
  149. size_t arrayWidth; /* Length of pointer Variable parameter, in charaters */
  150. SecUnsignedInt64 number64; /* Store input number64 value */
  151. unsigned long number; /* Store input number32 value */
  152. int numberWidth; /* 0 = SHORT, 1 = int, > 1 long or L_DOUBLE */
  153. int numberArgType; /* 1 for 64-bit integer, 0 otherwise. use it as decode function index */
  154. unsigned int negative; /* 0 is positive */
  155. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  156. unsigned int beyondMax; /* Non-zero means beyond */
  157. #endif
  158. unsigned int numberState; /* Identifies whether to start processing numbers, 1 is can input number */
  159. int width; /* Width number in format */
  160. int widthSet; /* 0 is not set width in format */
  161. int convChr; /* Lowercase format conversion characters */
  162. int oriConvChr; /* Store original format conversion, convChr may change when parsing integers */
  163. signed char isWCharOrLong; /* -1/0 not wchar or long, 1 for wchar or long */
  164. unsigned char suppress; /* 0 is not have %* in format */
  165. } SecScanSpec;
  166. #ifdef SECUREC_FOR_WCHAR
  167. #define SECUREC_GETC fgetwc
  168. #define SECUREC_UN_GETC ungetwc
  169. /* Only supports wide characters with a maximum length of two bytes in format string */
  170. #define SECUREC_BRACKET_CHAR_MASK 0xffffU
  171. #else
  172. #define SECUREC_GETC fgetc
  173. #define SECUREC_UN_GETC ungetc
  174. #define SECUREC_BRACKET_CHAR_MASK 0xffU
  175. #endif
  176. #define SECUREC_CHAR_SIZE ((unsigned int)(sizeof(SecChar)))
  177. /* To avoid 648, mask high bit: 0x00ffffff 0x0000ffff or 0x00000000 */
  178. #define SECUREC_CHAR_MASK_HIGH (((((((((unsigned int)(-1) >> SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \
  179. SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \
  180. SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \
  181. SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE)
  182. /* For char is 0xff, wcahr_t is 0xffff or 0xffffffff. */
  183. #define SECUREC_CHAR_MASK (~((((((((((unsigned int)(-1) & SECUREC_CHAR_MASK_HIGH) << \
  184. SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \
  185. SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \
  186. SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \
  187. SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE))
  188. /* According wchar_t has multiple bytes, so use sizeof */
  189. #define SECUREC_GET_CHAR(stream, outCh) do { \
  190. if ((stream)->count >= sizeof(SecChar)) { \
  191. *(outCh) = (SecInt)(SECUREC_CHAR_MASK & \
  192. (unsigned int)(int)(*((const SecChar *)(const void *)(stream)->cur))); \
  193. (stream)->cur += sizeof(SecChar); \
  194. (stream)->count -= sizeof(SecChar); \
  195. } else { \
  196. *(outCh) = SECUREC_EOF; \
  197. } \
  198. } SECUREC_WHILE_ZERO
  199. #define SECUREC_UN_GET_CHAR(stream) do { \
  200. if ((stream)->cur > (stream)->base) { \
  201. (stream)->cur -= sizeof(SecChar); \
  202. (stream)->count += sizeof(SecChar); \
  203. } \
  204. } SECUREC_WHILE_ZERO
  205. /* Convert wchar_t to int and then to unsigned int to keep data clearing warning */
  206. #define SECUREC_TO_LOWERCASE(chr) ((int)((unsigned int)(int)(chr) | (unsigned int)('a' - 'A')))
  207. /* Record a flag for each bit */
  208. #define SECUREC_BRACKET_INDEX(x) ((unsigned int)(x) >> 3U)
  209. #define SECUREC_BRACKET_VALUE(x) ((unsigned char)(1U << ((unsigned int)(x) & 7U)))
  210. #if SECUREC_IN_KERNEL
  211. #define SECUREC_CONVERT_IS_UNSIGNED(conv) ((conv) == 'x' || (conv) == 'o' || (conv) == 'u')
  212. #endif
  213. /*
  214. * Set char in %[xxx] into table, only supports wide characters with a maximum length of two bytes
  215. */
  216. SECUREC_INLINE void SecBracketSetBit(unsigned char *table, SecUnsignedChar ch)
  217. {
  218. unsigned int tableIndex = SECUREC_BRACKET_INDEX(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));
  219. unsigned int tableValue = SECUREC_BRACKET_VALUE(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));
  220. /* Do not use |= optimize this code, it will cause compiling warning */
  221. table[tableIndex] = (unsigned char)(table[tableIndex] | tableValue);
  222. }
  223. SECUREC_INLINE void SecBracketSetBitRange(unsigned char *table, SecUnsignedChar startCh, SecUnsignedChar endCh)
  224. {
  225. SecUnsignedChar expCh;
  226. /* %[a-z] %[a-a] Format %[a-\xff] end is 0xFF, condition (expCh <= endChar) cause dead loop */
  227. for (expCh = startCh; expCh < endCh; ++expCh) {
  228. SecBracketSetBit(table, expCh);
  229. }
  230. SecBracketSetBit(table, endCh);
  231. }
  232. /*
  233. * Determine whether the expression can be satisfied
  234. */
  235. SECUREC_INLINE int SecCanInputForBracket(int convChr, SecInt ch, const SecBracketTable *bracketTable)
  236. {
  237. unsigned int tableIndex = SECUREC_BRACKET_INDEX(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));
  238. unsigned int tableValue = SECUREC_BRACKET_VALUE(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));
  239. #ifdef SECUREC_FOR_WCHAR
  240. if (((unsigned int)(int)ch & (~(SECUREC_BRACKET_CHAR_MASK))) != 0) {
  241. /* The value of the wide character exceeds the size of two bytes */
  242. return 0;
  243. }
  244. return (int)(convChr == SECUREC_BRACE &&
  245. (((unsigned int)bracketTable->table[tableIndex] ^ (unsigned int)bracketTable->mask) & tableValue) != 0);
  246. #else
  247. return (int)(convChr == SECUREC_BRACE &&
  248. (((unsigned int)bracketTable->table[tableIndex] ^ (unsigned int)bracketTable->mask) & tableValue) != 0);
  249. #endif
  250. }
  251. /*
  252. * String input ends when blank character is encountered
  253. */
  254. SECUREC_INLINE int SecCanInputString(int convChr, SecInt ch)
  255. {
  256. return (int)(convChr == 's' &&
  257. (!(ch >= SECUREC_CHAR('\t') && ch <= SECUREC_CHAR('\r')) && ch != SECUREC_CHAR(' ')));
  258. }
  259. /*
  260. * Can input a character when format is %c
  261. */
  262. SECUREC_INLINE int SecCanInputCharacter(int convChr)
  263. {
  264. return (int)(convChr == 'c');
  265. }
  266. /*
  267. * Determine if it is a 64-bit pointer function
  268. * Return 0 is not ,1 is 64bit pointer
  269. */
  270. SECUREC_INLINE int SecNumberArgType(size_t sizeOfVoidStar)
  271. {
  272. /* Point size is 4 or 8 , Under the 64 bit system, the value not 0 */
  273. /* To clear e778 */
  274. if ((sizeOfVoidStar & sizeof(SecInt64)) != 0) {
  275. return 1;
  276. }
  277. return 0;
  278. }
  279. SECUREC_INLINE int SecIsDigit(SecInt ch);
  280. SECUREC_INLINE int SecIsXdigit(SecInt ch);
  281. SECUREC_INLINE int SecIsSpace(SecInt ch);
  282. SECUREC_INLINE SecInt SecSkipSpaceChar(SecFileStream *stream, int *counter);
  283. SECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter);
  284. SECUREC_INLINE void SecUnGetChar(SecInt ch, SecFileStream *stream, int *counter);
  285. #if SECUREC_ENABLE_SCANF_FLOAT
  286. /*
  287. * Convert a floating point string to a floating point number
  288. */
  289. SECUREC_INLINE int SecAssignNarrowFloat(const char *floatStr, const SecScanSpec *spec)
  290. {
  291. char *endPtr = NULL;
  292. double d;
  293. #if SECUREC_SUPPORT_STRTOLD
  294. if (spec->numberWidth == SECUREC_NUM_WIDTH_LONG_LONG) {
  295. long double d2 = strtold(floatStr, &endPtr);
  296. if (endPtr == floatStr) {
  297. return -1;
  298. }
  299. *(long double UNALIGNED *)(spec->argPtr) = d2;
  300. return 0;
  301. }
  302. #endif
  303. d = strtod(floatStr, &endPtr);
  304. /* cannot detect if endPtr points to the end of floatStr,because strtod handles only two characters for 1.E */
  305. if (endPtr == floatStr) {
  306. return -1;
  307. }
  308. if (spec->numberWidth > SECUREC_NUM_WIDTH_INT) {
  309. *(double UNALIGNED *)(spec->argPtr) = (double)d;
  310. } else {
  311. *(float UNALIGNED *)(spec->argPtr) = (float)d;
  312. }
  313. return 0;
  314. }
  315. #ifdef SECUREC_FOR_WCHAR
  316. /*
  317. * Convert a floating point wchar string to a floating point number
  318. * Success ret 0
  319. */
  320. SECUREC_INLINE int SecAssignWideFloat(const SecFloatSpec *floatSpec, const SecScanSpec *spec)
  321. {
  322. int retVal;
  323. /* Convert float string */
  324. size_t mbsLen;
  325. size_t tempFloatStrLen = (size_t)(floatSpec->floatStrUsedLen + 1) * sizeof(wchar_t);
  326. char *tempFloatStr = (char *)SECUREC_MALLOC(tempFloatStrLen);
  327. if (tempFloatStr == NULL) {
  328. return -1;
  329. }
  330. tempFloatStr[0] = '\0';
  331. SECUREC_MASK_MSVC_CRT_WARNING
  332. mbsLen = wcstombs(tempFloatStr, floatSpec->floatStr, tempFloatStrLen - 1);
  333. SECUREC_END_MASK_MSVC_CRT_WARNING
  334. /* This condition must satisfy mbsLen is not -1 */
  335. if (mbsLen >= tempFloatStrLen) {
  336. SECUREC_FREE(tempFloatStr);
  337. return -1;
  338. }
  339. tempFloatStr[mbsLen] = '\0';
  340. retVal = SecAssignNarrowFloat(tempFloatStr, spec);
  341. SECUREC_FREE(tempFloatStr);
  342. return retVal;
  343. }
  344. #endif
  345. SECUREC_INLINE int SecAssignFloat(const SecFloatSpec *floatSpec, const SecScanSpec *spec)
  346. {
  347. #ifdef SECUREC_FOR_WCHAR
  348. return SecAssignWideFloat(floatSpec, spec);
  349. #else
  350. return SecAssignNarrowFloat(floatSpec->floatStr, spec);
  351. #endif
  352. }
  353. /*
  354. * Init SecFloatSpec before parse format
  355. */
  356. SECUREC_INLINE void SecInitFloatSpec(SecFloatSpec *floatSpec)
  357. {
  358. floatSpec->floatStr = floatSpec->buffer;
  359. floatSpec->allocatedFloatStr = NULL;
  360. floatSpec->floatStrTotalLen = sizeof(floatSpec->buffer) / sizeof(floatSpec->buffer[0]);
  361. floatSpec->floatStrUsedLen = 0;
  362. }
  363. SECUREC_INLINE void SecFreeFloatSpec(SecFloatSpec *floatSpec, int *doneCount)
  364. {
  365. /* 2014.3.6 add, clear the stack data */
  366. if (memset_s(floatSpec->buffer, sizeof(floatSpec->buffer), 0, sizeof(floatSpec->buffer)) != EOK) {
  367. *doneCount = 0; /* This code just to meet the coding requirements */
  368. }
  369. /* The pFloatStr can be alloced in SecExtendFloatLen function, clear and free it */
  370. if (floatSpec->allocatedFloatStr != NULL) {
  371. size_t bufferSize = floatSpec->floatStrTotalLen * sizeof(SecChar);
  372. if (memset_s(floatSpec->allocatedFloatStr, bufferSize, 0, bufferSize) != EOK) {
  373. *doneCount = 0; /* This code just to meet the coding requirements */
  374. }
  375. SECUREC_FREE(floatSpec->allocatedFloatStr);
  376. floatSpec->allocatedFloatStr = NULL;
  377. floatSpec->floatStr = NULL;
  378. }
  379. }
  380. /*
  381. * Splice floating point string
  382. * Return 0 OK
  383. */
  384. SECUREC_INLINE int SecExtendFloatLen(SecFloatSpec *floatSpec)
  385. {
  386. if (floatSpec->floatStrUsedLen >= floatSpec->floatStrTotalLen) {
  387. /* Buffer size is len x sizeof(SecChar) */
  388. size_t oriSize = floatSpec->floatStrTotalLen * sizeof(SecChar);
  389. /* Add one character to clear tool warning */
  390. size_t nextSize = (oriSize * 2) + sizeof(SecChar); /* Multiply 2 to extend buffer size */
  391. /* Prevents integer overflow, the maximum length of SECUREC_MAX_WIDTH_LEN is enough */
  392. if (nextSize <= (size_t)SECUREC_MAX_WIDTH_LEN) {
  393. void *nextBuffer = (void *)SECUREC_MALLOC(nextSize);
  394. if (nextBuffer == NULL) {
  395. return -1;
  396. }
  397. if (memcpy_s(nextBuffer, nextSize, floatSpec->floatStr, oriSize) != EOK) {
  398. SECUREC_FREE(nextBuffer); /* This is a dead code, just to meet the coding requirements */
  399. return -1;
  400. }
  401. /* Clear old buffer memory */
  402. if (memset_s(floatSpec->floatStr, oriSize, 0, oriSize) != EOK) {
  403. SECUREC_FREE(nextBuffer); /* This is a dead code, just to meet the coding requirements */
  404. return -1;
  405. }
  406. /* Free old allocated buffer */
  407. if (floatSpec->allocatedFloatStr != NULL) {
  408. SECUREC_FREE(floatSpec->allocatedFloatStr);
  409. }
  410. floatSpec->allocatedFloatStr = (SecChar *)(nextBuffer); /* Use to clear free on stack warning */
  411. floatSpec->floatStr = (SecChar *)(nextBuffer);
  412. floatSpec->floatStrTotalLen = nextSize / sizeof(SecChar); /* Get buffer total len in character */
  413. return 0;
  414. }
  415. return -1; /* Next size is beyond max */
  416. }
  417. return 0;
  418. }
  419. /* Do not use localeconv()->decimal_pointif onlay support '.' */
  420. SECUREC_INLINE int SecIsFloatDecimal(SecChar ch)
  421. {
  422. return (int)(ch == SECUREC_CHAR('.'));
  423. }
  424. SECUREC_INLINE int SecInputFloatSign(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)
  425. {
  426. if (!SECUREC_FILED_WIDTH_ENOUGH(spec)) {
  427. return 0;
  428. }
  429. spec->ch = SecGetChar(stream, &(spec->charCount));
  430. if (spec->ch == SECUREC_CHAR('+') || spec->ch == SECUREC_CHAR('-')) {
  431. SECUREC_FILED_WIDTH_DEC(spec); /* Make sure the count after un get char is correct */
  432. if (spec->ch == SECUREC_CHAR('-')) {
  433. floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('-');
  434. ++floatSpec->floatStrUsedLen;
  435. if (SecExtendFloatLen(floatSpec) != 0) {
  436. return -1;
  437. }
  438. }
  439. } else {
  440. SecUnGetChar(spec->ch, stream, &(spec->charCount));
  441. }
  442. return 0;
  443. }
  444. SECUREC_INLINE int SecInputFloatDigit(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)
  445. {
  446. /* Now get integral part */
  447. while (SECUREC_FILED_WIDTH_ENOUGH(spec)) {
  448. spec->ch = SecGetChar(stream, &(spec->charCount));
  449. if (SecIsDigit(spec->ch) == 0) {
  450. SecUnGetChar(spec->ch, stream, &(spec->charCount));
  451. return 0;
  452. }
  453. SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */
  454. spec->numberState = SECUREC_NUMBER_STATE_STARTED;
  455. floatSpec->floatStr[floatSpec->floatStrUsedLen] = (SecChar)spec->ch;
  456. ++floatSpec->floatStrUsedLen;
  457. if (SecExtendFloatLen(floatSpec) != 0) {
  458. return -1;
  459. }
  460. }
  461. return 0;
  462. }
  463. /*
  464. * Scan value of exponent.
  465. * Return 0 OK
  466. */
  467. SECUREC_INLINE int SecInputFloatE(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)
  468. {
  469. if (SecInputFloatSign(stream, spec, floatSpec) == -1) {
  470. return -1;
  471. }
  472. if (SecInputFloatDigit(stream, spec, floatSpec) != 0) {
  473. return -1;
  474. }
  475. return 0;
  476. }
  477. SECUREC_INLINE int SecInputFloatFractional(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)
  478. {
  479. if (SECUREC_FILED_WIDTH_ENOUGH(spec)) {
  480. spec->ch = SecGetChar(stream, &(spec->charCount));
  481. if (SecIsFloatDecimal((SecChar)spec->ch) == 0) {
  482. SecUnGetChar(spec->ch, stream, &(spec->charCount));
  483. return 0;
  484. }
  485. SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */
  486. /* Now check for decimal */
  487. floatSpec->floatStr[floatSpec->floatStrUsedLen] = (SecChar)spec->ch;
  488. ++floatSpec->floatStrUsedLen;
  489. if (SecExtendFloatLen(floatSpec) != 0) {
  490. return -1;
  491. }
  492. if (SecInputFloatDigit(stream, spec, floatSpec) != 0) {
  493. return -1;
  494. }
  495. }
  496. return 0;
  497. }
  498. SECUREC_INLINE int SecInputFloatExponent(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)
  499. {
  500. /* Now get exponent part */
  501. if (spec->numberState == SECUREC_NUMBER_STATE_STARTED && SECUREC_FILED_WIDTH_ENOUGH(spec)) {
  502. spec->ch = SecGetChar(stream, &(spec->charCount));
  503. if (spec->ch != SECUREC_CHAR('e') && spec->ch != SECUREC_CHAR('E')) {
  504. SecUnGetChar(spec->ch, stream, &(spec->charCount));
  505. return 0;
  506. }
  507. SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */
  508. floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('e');
  509. ++floatSpec->floatStrUsedLen;
  510. if (SecExtendFloatLen(floatSpec) != 0) {
  511. return -1;
  512. }
  513. if (SecInputFloatE(stream, spec, floatSpec) != 0) {
  514. return -1;
  515. }
  516. }
  517. return 0;
  518. }
  519. /*
  520. * Scan %f.
  521. * Return 0 OK
  522. */
  523. SECUREC_INLINE int SecInputFloat(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)
  524. {
  525. floatSpec->floatStrUsedLen = 0;
  526. /* The following code sequence is strict */
  527. if (SecInputFloatSign(stream, spec, floatSpec) != 0) {
  528. return -1;
  529. }
  530. if (SecInputFloatDigit(stream, spec, floatSpec) != 0) {
  531. return -1;
  532. }
  533. if (SecInputFloatFractional(stream, spec, floatSpec) != 0) {
  534. return -1;
  535. }
  536. if (SecInputFloatExponent(stream, spec, floatSpec) != 0) {
  537. return -1;
  538. }
  539. /* Make sure have a string terminator, buffer is large enough */
  540. floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('\0');
  541. if (spec->numberState == SECUREC_NUMBER_STATE_STARTED) {
  542. return 0;
  543. }
  544. return -1;
  545. }
  546. #endif
  547. #if (!defined(SECUREC_FOR_WCHAR) && SECUREC_HAVE_WCHART && SECUREC_HAVE_MBTOWC) || \
  548. (!defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION))
  549. /* only multi-bytes string need isleadbyte() function */
  550. SECUREC_INLINE int SecIsLeadByte(SecInt ch)
  551. {
  552. unsigned int c = (unsigned int)ch;
  553. #if !(defined(_MSC_VER) || defined(_INC_WCTYPE))
  554. return (int)(c & 0x80U); /* Use bitwise operation to check if the most significant bit is 1 */
  555. #else
  556. return (int)isleadbyte((int)(c & 0xffU)); /* Use bitwise operations to limit character values to valid ranges */
  557. #endif
  558. }
  559. #endif
  560. /*
  561. * Parsing whether it is a wide character
  562. */
  563. SECUREC_INLINE void SecUpdateWcharFlagByType(SecUnsignedChar ch, SecScanSpec *spec)
  564. {
  565. if (spec->isWCharOrLong != 0) {
  566. /* Wide character identifiers have been explicitly set by l or h flag */
  567. return;
  568. }
  569. /* Set default flag */
  570. #if defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_WIN_FORMAT)
  571. spec->isWCharOrLong = 1; /* On windows wide char version %c %s %[ is wide char */
  572. #else
  573. spec->isWCharOrLong = -1; /* On linux all version %c %s %[ is multi char */
  574. #endif
  575. if (ch == SECUREC_CHAR('C') || ch == SECUREC_CHAR('S')) {
  576. #if defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_WIN_FORMAT)
  577. spec->isWCharOrLong = -1; /* On windows wide char version %C %S is multi char */
  578. #else
  579. spec->isWCharOrLong = 1; /* On linux all version %C %S is wide char */
  580. #endif
  581. }
  582. return;
  583. }
  584. /*
  585. * Decode %l %ll
  586. */
  587. SECUREC_INLINE void SecDecodeScanQualifierL(const SecUnsignedChar **format, SecScanSpec *spec)
  588. {
  589. const SecUnsignedChar *fmt = *format;
  590. if (*(fmt + 1) == SECUREC_CHAR('l')) {
  591. spec->numberArgType = 1;
  592. spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;
  593. ++fmt;
  594. } else {
  595. spec->numberWidth = SECUREC_NUM_WIDTH_LONG;
  596. #if defined(SECUREC_ON_64BITS) && !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))
  597. /* On window 64 system sizeof long is 32bit */
  598. spec->numberArgType = 1;
  599. #endif
  600. spec->isWCharOrLong = 1;
  601. }
  602. *format = fmt;
  603. }
  604. /*
  605. * Decode %I %I43 %I64 %Id %Ii %Io ...
  606. * Set finishFlag to 1 finish Flag
  607. */
  608. SECUREC_INLINE void SecDecodeScanQualifierI(const SecUnsignedChar **format, SecScanSpec *spec, int *finishFlag)
  609. {
  610. const SecUnsignedChar *fmt = *format;
  611. if ((*(fmt + 1) == SECUREC_CHAR('6')) &&
  612. (*(fmt + 2) == SECUREC_CHAR('4'))) { /* Offset 2 for I64 */
  613. spec->numberArgType = 1;
  614. *format = *format + 2; /* Add 2 to skip I64 point to '4' next loop will inc */
  615. } else if ((*(fmt + 1) == SECUREC_CHAR('3')) &&
  616. (*(fmt + 2) == SECUREC_CHAR('2'))) { /* Offset 2 for I32 */
  617. *format = *format + 2; /* Add 2 to skip I32 point to '2' next loop will inc */
  618. } else if ((*(fmt + 1) == SECUREC_CHAR('d')) ||
  619. (*(fmt + 1) == SECUREC_CHAR('i')) ||
  620. (*(fmt + 1) == SECUREC_CHAR('o')) ||
  621. (*(fmt + 1) == SECUREC_CHAR('x')) ||
  622. (*(fmt + 1) == SECUREC_CHAR('X'))) {
  623. spec->numberArgType = SecNumberArgType(sizeof(void *));
  624. } else {
  625. /* For %I */
  626. spec->numberArgType = SecNumberArgType(sizeof(void *));
  627. *finishFlag = 1;
  628. }
  629. }
  630. SECUREC_INLINE int SecDecodeScanWidth(const SecUnsignedChar **format, SecScanSpec *spec)
  631. {
  632. const SecUnsignedChar *fmt = *format;
  633. while (SecIsDigit((SecInt)(int)(*fmt)) != 0) {
  634. spec->widthSet = 1;
  635. if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(spec->width)) {
  636. return -1;
  637. }
  638. spec->width = (int)SECUREC_MUL_TEN((unsigned int)spec->width) + (unsigned char)(*fmt - SECUREC_CHAR('0'));
  639. ++fmt;
  640. }
  641. *format = fmt;
  642. return 0;
  643. }
  644. /*
  645. * Init default flags for each format. do not init ch this variable is context-dependent
  646. */
  647. SECUREC_INLINE void SecSetDefaultScanSpec(SecScanSpec *spec)
  648. {
  649. /* The ch and charCount member variables cannot be initialized here */
  650. spec->argPtr = NULL;
  651. spec->arrayWidth = 0;
  652. spec->number64 = 0;
  653. spec->number = 0;
  654. spec->numberWidth = SECUREC_NUM_WIDTH_INT; /* 0 = SHORT, 1 = int, > 1 long or L_DOUBLE */
  655. spec->numberArgType = 0; /* 1 for 64-bit integer, 0 otherwise */
  656. spec->width = 0;
  657. spec->widthSet = 0;
  658. spec->convChr = 0;
  659. spec->oriConvChr = 0;
  660. spec->isWCharOrLong = 0;
  661. spec->suppress = 0;
  662. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  663. spec->beyondMax = 0;
  664. #endif
  665. spec->negative = 0;
  666. spec->numberState = SECUREC_NUMBER_STATE_DEFAULT;
  667. }
  668. /*
  669. * Decode qualifier %I %L %h ...
  670. * Set finishFlag to 1 finish Flag
  671. */
  672. SECUREC_INLINE void SecDecodeScanQualifier(const SecUnsignedChar **format, SecScanSpec *spec, int *finishFlag)
  673. {
  674. switch (**format) {
  675. case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */
  676. case SECUREC_CHAR('N'):
  677. break;
  678. case SECUREC_CHAR('h'):
  679. --spec->numberWidth; /* The h for SHORT , hh for CHAR */
  680. spec->isWCharOrLong = -1;
  681. break;
  682. #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
  683. case SECUREC_CHAR('j'):
  684. spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG; /* For intmax_t or uintmax_t */
  685. spec->numberArgType = 1;
  686. break;
  687. case SECUREC_CHAR('t'): /* fall-through */ /* FALLTHRU */
  688. #endif
  689. #if SECUREC_IN_KERNEL
  690. case SECUREC_CHAR('Z'): /* fall-through */ /* FALLTHRU */
  691. #endif
  692. case SECUREC_CHAR('z'):
  693. #ifdef SECUREC_ON_64BITS
  694. spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;
  695. spec->numberArgType = 1;
  696. #else
  697. spec->numberWidth = SECUREC_NUM_WIDTH_LONG;
  698. #endif
  699. break;
  700. case SECUREC_CHAR('L'): /* For long double */ /* fall-through */ /* FALLTHRU */
  701. case SECUREC_CHAR('q'):
  702. spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;
  703. spec->numberArgType = 1;
  704. break;
  705. case SECUREC_CHAR('l'):
  706. SecDecodeScanQualifierL(format, spec);
  707. break;
  708. case SECUREC_CHAR('w'):
  709. spec->isWCharOrLong = 1;
  710. break;
  711. case SECUREC_CHAR('*'):
  712. spec->suppress = 1;
  713. break;
  714. case SECUREC_CHAR('I'):
  715. SecDecodeScanQualifierI(format, spec, finishFlag);
  716. break;
  717. default:
  718. *finishFlag = 1;
  719. break;
  720. }
  721. }
  722. /*
  723. * Decode width and qualifier in format
  724. */
  725. SECUREC_INLINE int SecDecodeScanFlag(const SecUnsignedChar **format, SecScanSpec *spec)
  726. {
  727. const SecUnsignedChar *fmt = *format;
  728. int finishFlag = 0;
  729. do {
  730. ++fmt; /* First skip % , next seek fmt */
  731. /* May %*6d , so put it inside the loop */
  732. if (SecDecodeScanWidth(&fmt, spec) != 0) {
  733. return -1;
  734. }
  735. SecDecodeScanQualifier(&fmt, spec, &finishFlag);
  736. } while (finishFlag == 0);
  737. *format = fmt;
  738. return 0;
  739. }
  740. /*
  741. * Judging whether a zeroing buffer is needed according to different formats
  742. */
  743. SECUREC_INLINE int SecDecodeClearFormat(const SecUnsignedChar *format, int *convChr)
  744. {
  745. const SecUnsignedChar *fmt = format;
  746. /* To lowercase */
  747. int ch = SECUREC_TO_LOWERCASE(*fmt);
  748. if (!(ch == 'c' || ch == 's' || ch == SECUREC_BRACE)) {
  749. return -1; /* First argument is not a string type */
  750. }
  751. if (ch == SECUREC_BRACE) {
  752. #if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))
  753. if (*fmt == SECUREC_CHAR('{')) {
  754. return -1;
  755. }
  756. #endif
  757. ++fmt;
  758. if (*fmt == SECUREC_CHAR('^')) {
  759. ++fmt;
  760. }
  761. if (*fmt == SECUREC_CHAR(']')) {
  762. ++fmt;
  763. }
  764. while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR(']')) {
  765. ++fmt;
  766. }
  767. if (*fmt == SECUREC_CHAR('\0')) {
  768. return -1; /* Trunc'd format string */
  769. }
  770. }
  771. *convChr = ch;
  772. return 0;
  773. }
  774. /*
  775. * Add L'\0' for wchar string , add '\0' for char string
  776. */
  777. SECUREC_INLINE void SecAddEndingZero(void *ptr, const SecScanSpec *spec)
  778. {
  779. if (spec->suppress == 0) {
  780. *(char *)ptr = '\0';
  781. #if SECUREC_HAVE_WCHART
  782. if (spec->isWCharOrLong > 0) {
  783. *(wchar_t UNALIGNED *)ptr = L'\0';
  784. }
  785. #endif
  786. }
  787. }
  788. SECUREC_INLINE void SecDecodeClearArg(SecScanSpec *spec, va_list argList)
  789. {
  790. va_list argListSave; /* Backup for argList value, this variable don't need initialized */
  791. (void)SECUREC_MEMSET_FUNC_OPT(&argListSave, 0, sizeof(va_list)); /* To clear e530 argListSave not initialized */
  792. #if defined(va_copy)
  793. va_copy(argListSave, argList);
  794. #elif defined(__va_copy) /* For vxworks */
  795. __va_copy(argListSave, argList);
  796. #else
  797. argListSave = argList;
  798. #endif
  799. spec->argPtr = (void *)va_arg(argListSave, void *);
  800. /* Get the next argument, size of the array in characters */
  801. /* Use 0xffffffffUL mask to Support pass integer as array length */
  802. spec->arrayWidth = ((size_t)(va_arg(argListSave, size_t))) & 0xffffffffUL;
  803. va_end(argListSave);
  804. /* To clear e438 last value assigned not used , the compiler will optimize this code */
  805. (void)argListSave;
  806. }
  807. #ifdef SECUREC_FOR_WCHAR
  808. /*
  809. * Clean up the first %s %c buffer to zero for wchar version
  810. */
  811. void SecClearDestBufW(const wchar_t *buffer, const wchar_t *format, va_list argList)
  812. #else
  813. /*
  814. * Clean up the first %s %c buffer to zero for char version
  815. */
  816. void SecClearDestBuf(const char *buffer, const char *format, va_list argList)
  817. #endif
  818. {
  819. SecScanSpec spec;
  820. int convChr = 0;
  821. const SecUnsignedChar *fmt = (const SecUnsignedChar *)format;
  822. /* Find first % */
  823. while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR('%')) {
  824. ++fmt;
  825. }
  826. if (*fmt == SECUREC_CHAR('\0')) {
  827. return;
  828. }
  829. SecSetDefaultScanSpec(&spec);
  830. if (SecDecodeScanFlag(&fmt, &spec) != 0) {
  831. return;
  832. }
  833. /* Update wchar flag for %S %C */
  834. SecUpdateWcharFlagByType(*fmt, &spec);
  835. if (spec.suppress != 0) {
  836. return;
  837. }
  838. if (SecDecodeClearFormat(fmt, &convChr) != 0) {
  839. return;
  840. }
  841. if (*buffer != SECUREC_CHAR('\0') && convChr != 's') {
  842. /*
  843. * When buffer not empty just clear %s.
  844. * Example call sscanf by argment of (" \n", "%s", s, sizeof(s))
  845. */
  846. return;
  847. }
  848. SecDecodeClearArg(&spec, argList);
  849. /* There is no need to judge the upper limit */
  850. if (spec.arrayWidth == 0 || spec.argPtr == NULL) {
  851. return;
  852. }
  853. /* Clear one char */
  854. SecAddEndingZero(spec.argPtr, &spec);
  855. return;
  856. }
  857. /*
  858. * Assign number to output buffer
  859. */
  860. SECUREC_INLINE void SecAssignNumber(const SecScanSpec *spec)
  861. {
  862. void *argPtr = spec->argPtr;
  863. if (spec->numberArgType != 0) {
  864. #if defined(SECUREC_VXWORKS_PLATFORM)
  865. #if defined(SECUREC_VXWORKS_PLATFORM_COMP)
  866. *(SecInt64 UNALIGNED *)argPtr = (SecInt64)(spec->number64);
  867. #else
  868. /* Take number64 as unsigned number unsigned to int clear Compile warning */
  869. *(SecInt64 UNALIGNED *)argPtr = *(SecUnsignedInt64 *)(&(spec->number64));
  870. #endif
  871. #else
  872. /* Take number64 as unsigned number */
  873. *(SecInt64 UNALIGNED *)argPtr = (SecInt64)(spec->number64);
  874. #endif
  875. return;
  876. }
  877. if (spec->numberWidth > SECUREC_NUM_WIDTH_INT) {
  878. /* Take number as unsigned number */
  879. *(long UNALIGNED *)argPtr = (long)(spec->number);
  880. } else if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) {
  881. *(int UNALIGNED *)argPtr = (int)(spec->number);
  882. } else if (spec->numberWidth == SECUREC_NUM_WIDTH_SHORT) {
  883. /* Take number as unsigned number */
  884. *(short UNALIGNED *)argPtr = (short)(spec->number);
  885. } else { /* < 0 for hh format modifier */
  886. /* Take number as unsigned number */
  887. *(char UNALIGNED *)argPtr = (char)(spec->number);
  888. }
  889. }
  890. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  891. /*
  892. * Judge the long bit width
  893. */
  894. SECUREC_INLINE int SecIsLongBitEqual(int bitNum)
  895. {
  896. return (int)((unsigned int)bitNum == SECUREC_LONG_BIT_NUM);
  897. }
  898. #endif
  899. /*
  900. * Convert hexadecimal characters to decimal value
  901. */
  902. SECUREC_INLINE int SecHexValueOfChar(SecInt ch)
  903. {
  904. /* Use isdigt Causing tool false alarms */
  905. return (int)((ch >= '0' && ch <= '9') ? ((unsigned char)ch - '0') :
  906. ((((unsigned char)ch | (unsigned char)('a' - 'A')) - ('a')) + 10)); /* Adding 10 is to hex value */
  907. }
  908. /*
  909. * Parse decimal character to integer for 32bit .
  910. */
  911. static void SecDecodeNumberDecimal(SecScanSpec *spec)
  912. {
  913. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  914. unsigned long decimalEdge = SECUREC_MAX_32BITS_VALUE_DIV_TEN;
  915. #ifdef SECUREC_ON_64BITS
  916. if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {
  917. decimalEdge = (unsigned long)SECUREC_MAX_64BITS_VALUE_DIV_TEN;
  918. }
  919. #endif
  920. if (spec->number > decimalEdge) {
  921. spec->beyondMax = 1;
  922. }
  923. #endif
  924. spec->number = SECUREC_MUL_TEN(spec->number);
  925. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  926. if (spec->number == SECUREC_MUL_TEN(decimalEdge)) {
  927. /* This code is specially converted to unsigned long type for compatibility */
  928. SecUnsignedInt64 number64As = (unsigned long)SECUREC_MAX_64BITS_VALUE - spec->number;
  929. if (number64As < (SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0')) {
  930. spec->beyondMax = 1;
  931. }
  932. }
  933. #endif
  934. spec->number += ((unsigned long)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0'));
  935. }
  936. /*
  937. * Parse Hex character to integer for 32bit .
  938. */
  939. static void SecDecodeNumberHex(SecScanSpec *spec)
  940. {
  941. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  942. if (SECUREC_LONG_HEX_BEYOND_MAX(spec->number)) {
  943. spec->beyondMax = 1;
  944. }
  945. #endif
  946. spec->number = SECUREC_MUL_SIXTEEN(spec->number);
  947. spec->number += (unsigned long)(unsigned int)SecHexValueOfChar(spec->ch);
  948. }
  949. /*
  950. * Parse Octal character to integer for 32bit .
  951. */
  952. static void SecDecodeNumberOctal(SecScanSpec *spec)
  953. {
  954. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  955. if (SECUREC_LONG_OCTAL_BEYOND_MAX(spec->number)) {
  956. spec->beyondMax = 1;
  957. }
  958. #endif
  959. spec->number = SECUREC_MUL_EIGHT(spec->number);
  960. spec->number += ((unsigned long)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0'));
  961. }
  962. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  963. /* Compatible with integer negative values other than int */
  964. SECUREC_INLINE void SecFinishNumberNegativeOther(SecScanSpec *spec)
  965. {
  966. if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
  967. if (spec->number > SECUREC_MIN_LONG_NEG_VALUE) {
  968. spec->number = SECUREC_MIN_LONG_NEG_VALUE;
  969. } else {
  970. spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */
  971. }
  972. if (spec->beyondMax != 0) {
  973. if (spec->numberWidth < SECUREC_NUM_WIDTH_INT) {
  974. spec->number = 0;
  975. }
  976. if (spec->numberWidth == SECUREC_NUM_WIDTH_LONG) {
  977. spec->number = SECUREC_MIN_LONG_NEG_VALUE;
  978. }
  979. }
  980. } else { /* For o, u, x, X, p */
  981. spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */
  982. if (spec->beyondMax != 0) {
  983. spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
  984. }
  985. }
  986. }
  987. /* Compatible processing of integer negative numbers */
  988. SECUREC_INLINE void SecFinishNumberNegativeInt(SecScanSpec *spec)
  989. {
  990. if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
  991. #ifdef SECUREC_ON_64BITS
  992. if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {
  993. if ((spec->number > SECUREC_MIN_64BITS_NEG_VALUE)) {
  994. spec->number = 0;
  995. } else {
  996. spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */
  997. }
  998. }
  999. #else
  1000. if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {
  1001. if ((spec->number > SECUREC_MIN_32BITS_NEG_VALUE)) {
  1002. spec->number = SECUREC_MIN_32BITS_NEG_VALUE;
  1003. } else {
  1004. spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */
  1005. }
  1006. }
  1007. #endif
  1008. if (spec->beyondMax != 0) {
  1009. #ifdef SECUREC_ON_64BITS
  1010. if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {
  1011. spec->number = 0;
  1012. }
  1013. #else
  1014. if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {
  1015. spec->number = SECUREC_MIN_32BITS_NEG_VALUE;
  1016. }
  1017. #endif
  1018. }
  1019. } else { /* For o, u, x, X ,p */
  1020. #ifdef SECUREC_ON_64BITS
  1021. if (spec->number > SECUREC_MAX_32BITS_VALUE_INC) {
  1022. spec->number = SECUREC_MAX_32BITS_VALUE;
  1023. } else {
  1024. spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */
  1025. }
  1026. #else
  1027. spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */
  1028. #endif
  1029. if (spec->beyondMax != 0) {
  1030. spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
  1031. }
  1032. }
  1033. }
  1034. /* Compatible with integer positive values other than int */
  1035. SECUREC_INLINE void SecFinishNumberPositiveOther(SecScanSpec *spec)
  1036. {
  1037. if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
  1038. if (spec->number > SECUREC_MAX_LONG_POS_VALUE) {
  1039. spec->number = SECUREC_MAX_LONG_POS_VALUE;
  1040. }
  1041. if ((spec->beyondMax != 0 && spec->numberWidth < SECUREC_NUM_WIDTH_INT)) {
  1042. spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
  1043. }
  1044. if (spec->beyondMax != 0 && spec->numberWidth == SECUREC_NUM_WIDTH_LONG) {
  1045. spec->number = SECUREC_MAX_LONG_POS_VALUE;
  1046. }
  1047. } else {
  1048. if (spec->beyondMax != 0) {
  1049. spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
  1050. }
  1051. }
  1052. }
  1053. /* Compatible processing of integer positive numbers */
  1054. SECUREC_INLINE void SecFinishNumberPositiveInt(SecScanSpec *spec)
  1055. {
  1056. if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
  1057. #ifdef SECUREC_ON_64BITS
  1058. if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {
  1059. if (spec->number > SECUREC_MAX_64BITS_POS_VALUE) {
  1060. spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
  1061. }
  1062. }
  1063. if (spec->beyondMax != 0 && SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {
  1064. spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;
  1065. }
  1066. #else
  1067. if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {
  1068. if (spec->number > SECUREC_MAX_32BITS_POS_VALUE) {
  1069. spec->number = SECUREC_MAX_32BITS_POS_VALUE;
  1070. }
  1071. }
  1072. if (spec->beyondMax != 0 && SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {
  1073. spec->number = SECUREC_MAX_32BITS_POS_VALUE;
  1074. }
  1075. #endif
  1076. } else { /* For o,u,x,X,p */
  1077. if (spec->beyondMax != 0) {
  1078. spec->number = SECUREC_MAX_32BITS_VALUE;
  1079. }
  1080. }
  1081. }
  1082. #endif
  1083. /*
  1084. * Parse decimal character to integer for 64bit .
  1085. */
  1086. static void SecDecodeNumber64Decimal(SecScanSpec *spec)
  1087. {
  1088. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  1089. if (spec->number64 > SECUREC_MAX_64BITS_VALUE_DIV_TEN) {
  1090. spec->beyondMax = 1;
  1091. }
  1092. #endif
  1093. spec->number64 = SECUREC_MUL_TEN(spec->number64);
  1094. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  1095. if (spec->number64 == SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT) {
  1096. SecUnsignedInt64 number64As = (SecUnsignedInt64)SECUREC_MAX_64BITS_VALUE - spec->number64;
  1097. if (number64As < (SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0')) {
  1098. spec->beyondMax = 1;
  1099. }
  1100. }
  1101. #endif
  1102. spec->number64 += ((SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0'));
  1103. }
  1104. /*
  1105. * Parse Hex character to integer for 64bit .
  1106. */
  1107. static void SecDecodeNumber64Hex(SecScanSpec *spec)
  1108. {
  1109. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  1110. if (SECUREC_QWORD_HEX_BEYOND_MAX(spec->number64)) {
  1111. spec->beyondMax = 1;
  1112. }
  1113. #endif
  1114. spec->number64 = SECUREC_MUL_SIXTEEN(spec->number64);
  1115. spec->number64 += (SecUnsignedInt64)(unsigned int)SecHexValueOfChar(spec->ch);
  1116. }
  1117. /*
  1118. * Parse Octal character to integer for 64bit .
  1119. */
  1120. static void SecDecodeNumber64Octal(SecScanSpec *spec)
  1121. {
  1122. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  1123. if (SECUREC_QWORD_OCTAL_BEYOND_MAX(spec->number64)) {
  1124. spec->beyondMax = 1;
  1125. }
  1126. #endif
  1127. spec->number64 = SECUREC_MUL_EIGHT(spec->number64);
  1128. spec->number64 += ((SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0'));
  1129. }
  1130. #define SECUREC_DECODE_NUMBER_FUNC_NUM 2
  1131. /*
  1132. * Parse 64-bit integer formatted input, return 0 when ch is a number.
  1133. */
  1134. SECUREC_INLINE int SecDecodeNumber(SecScanSpec *spec)
  1135. {
  1136. /* Function name cannot add address symbol, causing 546 alarm */
  1137. static void (* const secDecodeNumberHex[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = {
  1138. SecDecodeNumberHex, SecDecodeNumber64Hex
  1139. };
  1140. static void (* const secDecodeNumberOctal[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = {
  1141. SecDecodeNumberOctal, SecDecodeNumber64Octal
  1142. };
  1143. static void (* const secDecodeNumberDecimal[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = {
  1144. SecDecodeNumberDecimal, SecDecodeNumber64Decimal
  1145. };
  1146. if (spec->convChr == 'x' || spec->convChr == 'p') {
  1147. if (SecIsXdigit(spec->ch) != 0) {
  1148. (*secDecodeNumberHex[spec->numberArgType])(spec);
  1149. } else {
  1150. return -1;
  1151. }
  1152. return 0;
  1153. }
  1154. if (SecIsDigit(spec->ch) == 0) {
  1155. return -1;
  1156. }
  1157. if (spec->convChr == 'o') {
  1158. if (spec->ch < SECUREC_CHAR('8')) { /* Octal maximum limit '8' */
  1159. (*secDecodeNumberOctal[spec->numberArgType])(spec);
  1160. } else {
  1161. return -1;
  1162. }
  1163. } else { /* The convChr is 'd' */
  1164. (*secDecodeNumberDecimal[spec->numberArgType])(spec);
  1165. }
  1166. return 0;
  1167. }
  1168. /*
  1169. * Complete the final 32-bit integer formatted input
  1170. */
  1171. static void SecFinishNumber(SecScanSpec *spec)
  1172. {
  1173. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  1174. if (spec->negative != 0) {
  1175. if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) {
  1176. SecFinishNumberNegativeInt(spec);
  1177. } else {
  1178. SecFinishNumberNegativeOther(spec);
  1179. }
  1180. } else {
  1181. if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) {
  1182. SecFinishNumberPositiveInt(spec);
  1183. } else {
  1184. SecFinishNumberPositiveOther(spec);
  1185. }
  1186. }
  1187. #else
  1188. if (spec->negative != 0) {
  1189. #if defined(__hpux)
  1190. if (spec->oriConvChr != 'p') {
  1191. spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */
  1192. }
  1193. #else
  1194. spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */
  1195. #endif
  1196. }
  1197. #endif
  1198. return;
  1199. }
  1200. /*
  1201. * Complete the final 64-bit integer formatted input
  1202. */
  1203. static void SecFinishNumber64(SecScanSpec *spec)
  1204. {
  1205. #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))
  1206. if (spec->negative != 0) {
  1207. if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
  1208. if (spec->number64 > SECUREC_MIN_64BITS_NEG_VALUE) {
  1209. spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE;
  1210. } else {
  1211. spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */
  1212. }
  1213. if (spec->beyondMax != 0) {
  1214. spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE;
  1215. }
  1216. } else { /* For o, u, x, X, p */
  1217. spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */
  1218. if (spec->beyondMax != 0) {
  1219. spec->number64 = SECUREC_MAX_64BITS_VALUE;
  1220. }
  1221. }
  1222. } else {
  1223. if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {
  1224. if (spec->number64 > SECUREC_MAX_64BITS_POS_VALUE) {
  1225. spec->number64 = SECUREC_MAX_64BITS_POS_VALUE;
  1226. }
  1227. if (spec->beyondMax != 0) {
  1228. spec->number64 = SECUREC_MAX_64BITS_POS_VALUE;
  1229. }
  1230. } else {
  1231. if (spec->beyondMax != 0) {
  1232. spec->number64 = SECUREC_MAX_64BITS_VALUE;
  1233. }
  1234. }
  1235. }
  1236. #else
  1237. if (spec->negative != 0) {
  1238. #if defined(__hpux)
  1239. if (spec->oriConvChr != 'p') {
  1240. spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */
  1241. }
  1242. #else
  1243. spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */
  1244. #endif
  1245. }
  1246. #endif
  1247. return;
  1248. }
  1249. #if SECUREC_ENABLE_SCANF_FILE
  1250. /*
  1251. * Adjust the pointer position of the file stream
  1252. */
  1253. SECUREC_INLINE void SecSeekStream(SecFileStream *stream)
  1254. {
  1255. if (stream->count == 0) {
  1256. if (feof(stream->pf) != 0) {
  1257. /* File pointer at the end of file, don't need to seek back */
  1258. stream->base[0] = '\0';
  1259. return;
  1260. }
  1261. }
  1262. /* Seek to original position, for file read, but nothing to input */
  1263. if (fseek(stream->pf, stream->oriFilePos, SEEK_SET) != 0) {
  1264. /* Seek failed, ignore it */
  1265. stream->oriFilePos = 0;
  1266. return;
  1267. }
  1268. if (stream->fileRealRead > 0) { /* Do not seek without input data */
  1269. #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
  1270. size_t residue = stream->fileRealRead % SECUREC_BUFFERED_BLOK_SIZE;
  1271. size_t loops;
  1272. for (loops = 0; loops < (stream->fileRealRead / SECUREC_BUFFERED_BLOK_SIZE); ++loops) {
  1273. if (fread(stream->base, (size_t)SECUREC_BUFFERED_BLOK_SIZE, (size_t)1, stream->pf) != (size_t)1) {
  1274. break;
  1275. }
  1276. }
  1277. if (residue != 0) {
  1278. long curFilePos;
  1279. if (fread(stream->base, residue, (size_t)1, stream->pf) != (size_t)1) {
  1280. return;
  1281. }
  1282. curFilePos = ftell(stream->pf);
  1283. if (curFilePos < stream->oriFilePos ||
  1284. (size_t)(unsigned long)(curFilePos - stream->oriFilePos) < stream->fileRealRead) {
  1285. /* Try to remedy the problem */
  1286. long adjustNum = (long)(stream->fileRealRead - (size_t)(unsigned long)(curFilePos - stream->oriFilePos));
  1287. (void)fseek(stream->pf, adjustNum, SEEK_CUR);
  1288. }
  1289. }
  1290. #else
  1291. /* Seek from oriFilePos. Regardless of the integer sign problem, call scanf will not read very large data */
  1292. if (fseek(stream->pf, (long)stream->fileRealRead, SEEK_CUR) != 0) {
  1293. /* Seek failed, ignore it */
  1294. stream->oriFilePos = 0;
  1295. return;
  1296. }
  1297. #endif
  1298. }
  1299. return;
  1300. }
  1301. /*
  1302. * Adjust the pointer position of the file stream and free memory
  1303. */
  1304. SECUREC_INLINE void SecAdjustStream(SecFileStream *stream)
  1305. {
  1306. if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0 && stream->base != NULL) {
  1307. SecSeekStream(stream);
  1308. SECUREC_FREE(stream->base);
  1309. stream->base = NULL;
  1310. }
  1311. return;
  1312. }
  1313. #endif
  1314. SECUREC_INLINE void SecSkipSpaceFormat(const SecUnsignedChar **format)
  1315. {
  1316. const SecUnsignedChar *fmt = *format;
  1317. while (SecIsSpace((SecInt)(int)(*fmt)) != 0) {
  1318. ++fmt;
  1319. }
  1320. *format = fmt;
  1321. }
  1322. #if !defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION)
  1323. /*
  1324. * Handling multi-character characters
  1325. */
  1326. SECUREC_INLINE int SecDecodeLeadByte(SecScanSpec *spec, const SecUnsignedChar **format, SecFileStream *stream)
  1327. {
  1328. #if SECUREC_HAVE_MBTOWC
  1329. const SecUnsignedChar *fmt = *format;
  1330. int ch1 = (int)spec->ch;
  1331. int ch2 = SecGetChar(stream, &(spec->charCount));
  1332. spec->ch = (SecInt)ch2;
  1333. if (*fmt == SECUREC_CHAR('\0') || (int)(*fmt) != ch2) {
  1334. /* in console mode, ungetc twice may cause problem */
  1335. SecUnGetChar(ch2, stream, &(spec->charCount));
  1336. SecUnGetChar(ch1, stream, &(spec->charCount));
  1337. return -1;
  1338. }
  1339. ++fmt;
  1340. if ((unsigned int)MB_CUR_MAX >= SECUREC_UTF8_BOM_HEADER_SIZE &&
  1341. (((unsigned char)ch1 & SECUREC_UTF8_LEAD_1ST) == SECUREC_UTF8_LEAD_1ST) &&
  1342. (((unsigned char)ch2 & SECUREC_UTF8_LEAD_2ND) == SECUREC_UTF8_LEAD_2ND)) {
  1343. /* This char is very likely to be a UTF-8 char */
  1344. wchar_t tempWChar;
  1345. char temp[SECUREC_MULTI_BYTE_MAX_LEN];
  1346. int ch3 = (int)SecGetChar(stream, &(spec->charCount));
  1347. spec->ch = (SecInt)ch3;
  1348. if (*fmt == SECUREC_CHAR('\0') || (int)(*fmt) != ch3) {
  1349. SecUnGetChar(ch3, stream, &(spec->charCount));
  1350. return -1;
  1351. }
  1352. temp[0] = (char)ch1;
  1353. temp[1] = (char)ch2; /* 1 index of second character */
  1354. temp[2] = (char)ch3; /* 2 index of third character */
  1355. temp[3] = '\0'; /* 3 of string terminator position */
  1356. if (mbtowc(&tempWChar, temp, sizeof(temp)) > 0) {
  1357. /* Succeed */
  1358. ++fmt;
  1359. --spec->charCount;
  1360. } else {
  1361. SecUnGetChar(ch3, stream, &(spec->charCount));
  1362. }
  1363. }
  1364. --spec->charCount; /* Only count as one character read */
  1365. *format = fmt;
  1366. return 0;
  1367. #else
  1368. SecUnGetChar(spec->ch, stream, &(spec->charCount));
  1369. (void)format; /* To clear e438 last value assigned not used , the compiler will optimize this code */
  1370. return -1;
  1371. #endif
  1372. }
  1373. SECUREC_INLINE int SecFilterWcharInFormat(SecScanSpec *spec, const SecUnsignedChar **format, SecFileStream *stream)
  1374. {
  1375. if (SecIsLeadByte(spec->ch) != 0) {
  1376. if (SecDecodeLeadByte(spec, format, stream) != 0) {
  1377. return -1;
  1378. }
  1379. }
  1380. return 0;
  1381. }
  1382. #endif
  1383. /*
  1384. * Resolving sequence of characters from %[ format, format wile point to ']'
  1385. */
  1386. SECUREC_INLINE int SecSetupBracketTable(const SecUnsignedChar **format, SecBracketTable *bracketTable)
  1387. {
  1388. const SecUnsignedChar *fmt = *format;
  1389. SecUnsignedChar prevChar = 0;
  1390. #if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))
  1391. if (*fmt == SECUREC_CHAR('{')) {
  1392. return -1;
  1393. }
  1394. #endif
  1395. /* For building "table" data */
  1396. ++fmt; /* Skip [ */
  1397. bracketTable->mask = 0; /* Set all bits to 0 */
  1398. if (*fmt == SECUREC_CHAR('^')) {
  1399. ++fmt;
  1400. bracketTable->mask = (unsigned char)0xffU; /* Use 0xffU to set all bits to 1 */
  1401. }
  1402. if (*fmt == SECUREC_CHAR(']')) {
  1403. prevChar = SECUREC_CHAR(']');
  1404. ++fmt;
  1405. SecBracketSetBit(bracketTable->table, SECUREC_CHAR(']'));
  1406. }
  1407. while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR(']')) {
  1408. SecUnsignedChar expCh = *fmt;
  1409. ++fmt;
  1410. if (expCh != SECUREC_CHAR('-') || prevChar == 0 || *fmt == SECUREC_CHAR(']')) {
  1411. /* Normal character */
  1412. prevChar = expCh;
  1413. SecBracketSetBit(bracketTable->table, expCh);
  1414. } else {
  1415. /* For %[a-z] */
  1416. expCh = *fmt; /* Get end of range */
  1417. ++fmt;
  1418. if (prevChar <= expCh) { /* %[a-z] %[a-a] */
  1419. SecBracketSetBitRange(bracketTable->table, prevChar, expCh);
  1420. } else {
  1421. /* For %[z-a] */
  1422. #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
  1423. /* Swap start and end characters */
  1424. SecBracketSetBitRange(bracketTable->table, expCh, prevChar);
  1425. #else
  1426. SecBracketSetBit(bracketTable->table, SECUREC_CHAR('-'));
  1427. SecBracketSetBit(bracketTable->table, expCh);
  1428. #endif
  1429. }
  1430. prevChar = 0;
  1431. }
  1432. }
  1433. *format = fmt;
  1434. return 0;
  1435. }
  1436. #ifdef SECUREC_FOR_WCHAR
  1437. SECUREC_INLINE int SecInputForWchar(SecScanSpec *spec)
  1438. {
  1439. void *endPtr = spec->argPtr;
  1440. if (spec->isWCharOrLong > 0) {
  1441. *(wchar_t UNALIGNED *)endPtr = (wchar_t)spec->ch;
  1442. endPtr = (wchar_t *)endPtr + 1;
  1443. --spec->arrayWidth;
  1444. } else {
  1445. #if SECUREC_HAVE_WCTOMB
  1446. int temp;
  1447. char tmpBuf[SECUREC_MB_LEN + 1];
  1448. SECUREC_MASK_MSVC_CRT_WARNING temp = wctomb(tmpBuf, (wchar_t)spec->ch);
  1449. SECUREC_END_MASK_MSVC_CRT_WARNING
  1450. if (temp <= 0 || (size_t)(unsigned int)temp > sizeof(tmpBuf)) {
  1451. /* If wctomb error, then ignore character */
  1452. return 0;
  1453. }
  1454. if (((size_t)(unsigned int)temp) > spec->arrayWidth) {
  1455. return -1;
  1456. }
  1457. if (memcpy_s(endPtr, spec->arrayWidth, tmpBuf, (size_t)(unsigned int)temp) != EOK) {
  1458. return -1;
  1459. }
  1460. endPtr = (char *)endPtr + temp;
  1461. spec->arrayWidth -= (size_t)(unsigned int)temp;
  1462. #else
  1463. return -1;
  1464. #endif
  1465. }
  1466. spec->argPtr = endPtr;
  1467. return 0;
  1468. }
  1469. #endif
  1470. #ifndef SECUREC_FOR_WCHAR
  1471. #if SECUREC_HAVE_WCHART
  1472. SECUREC_INLINE wchar_t SecConvertInputCharToWchar(SecScanSpec *spec, SecFileStream *stream)
  1473. {
  1474. wchar_t tempWChar = L'?'; /* Set default char is ? */
  1475. #if SECUREC_HAVE_MBTOWC
  1476. char temp[SECUREC_MULTI_BYTE_MAX_LEN + 1];
  1477. temp[0] = (char)spec->ch;
  1478. temp[1] = '\0';
  1479. #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
  1480. if (SecIsLeadByte(spec->ch) != 0) {
  1481. spec->ch = SecGetChar(stream, &(spec->charCount));
  1482. temp[1] = (char)spec->ch;
  1483. temp[2] = '\0'; /* 2 of string terminator position */
  1484. }
  1485. if (mbtowc(&tempWChar, temp, sizeof(temp)) <= 0) {
  1486. /* No string termination error for tool */
  1487. tempWChar = L'?';
  1488. }
  1489. #else
  1490. if (SecIsLeadByte(spec->ch) != 0) {
  1491. int convRes = 0;
  1492. int di = 1;
  1493. /* On Linux like system, the string is encoded in UTF-8 */
  1494. while (convRes <= 0 && di < (int)MB_CUR_MAX && di < SECUREC_MULTI_BYTE_MAX_LEN) {
  1495. spec->ch = SecGetChar(stream, &(spec->charCount));
  1496. temp[di] = (char)spec->ch;
  1497. ++di;
  1498. temp[di] = '\0';
  1499. convRes = mbtowc(&tempWChar, temp, sizeof(temp));
  1500. }
  1501. if (convRes <= 0) {
  1502. tempWChar = L'?';
  1503. }
  1504. } else {
  1505. if (mbtowc(&tempWChar, temp, sizeof(temp)) <= 0) {
  1506. tempWChar = L'?';
  1507. }
  1508. }
  1509. #endif
  1510. #else
  1511. (void)spec; /* To clear e438 last value assigned not used , the compiler will optimize this code */
  1512. (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */
  1513. #endif /* SECUREC_HAVE_MBTOWC */
  1514. return tempWChar;
  1515. }
  1516. #endif /* SECUREC_HAVE_WCHART */
  1517. SECUREC_INLINE int SecInputForChar(SecScanSpec *spec, SecFileStream *stream)
  1518. {
  1519. void *endPtr = spec->argPtr;
  1520. if (spec->isWCharOrLong > 0) {
  1521. #if SECUREC_HAVE_WCHART
  1522. *(wchar_t UNALIGNED *)endPtr = SecConvertInputCharToWchar(spec, stream);
  1523. endPtr = (wchar_t *)endPtr + 1;
  1524. --spec->arrayWidth;
  1525. #else
  1526. (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */
  1527. return -1;
  1528. #endif
  1529. } else {
  1530. *(char *)endPtr = (char)spec->ch;
  1531. endPtr = (char *)endPtr + 1;
  1532. --spec->arrayWidth;
  1533. }
  1534. spec->argPtr = endPtr;
  1535. return 0;
  1536. }
  1537. #endif
  1538. /*
  1539. * Scan digital part of %d %i %o %u %x %p.
  1540. * Return 0 OK
  1541. */
  1542. SECUREC_INLINE int SecInputNumberDigital(SecFileStream *stream, SecScanSpec *spec)
  1543. {
  1544. static void (* const secFinishNumber[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = {
  1545. SecFinishNumber, SecFinishNumber64
  1546. };
  1547. while (SECUREC_FILED_WIDTH_ENOUGH(spec)) {
  1548. spec->ch = SecGetChar(stream, &(spec->charCount));
  1549. /* Decode ch to number */
  1550. if (SecDecodeNumber(spec) != 0) {
  1551. SecUnGetChar(spec->ch, stream, &(spec->charCount));
  1552. break;
  1553. }
  1554. SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */
  1555. spec->numberState = SECUREC_NUMBER_STATE_STARTED;
  1556. }
  1557. /* Handling integer negative numbers and beyond max */
  1558. (*secFinishNumber[spec->numberArgType])(spec);
  1559. if (spec->numberState == SECUREC_NUMBER_STATE_STARTED) {
  1560. return 0;
  1561. }
  1562. return -1;
  1563. }
  1564. /*
  1565. * Scan %d %i %o %u %x %p.
  1566. * Return 0 OK
  1567. */
  1568. SECUREC_INLINE int SecInputNumber(SecFileStream *stream, SecScanSpec *spec)
  1569. {
  1570. /* Character already read */
  1571. if (spec->ch == SECUREC_CHAR('+') || spec->ch == SECUREC_CHAR('-')) {
  1572. if (spec->ch == SECUREC_CHAR('-')) {
  1573. spec->negative = 1;
  1574. #if SECUREC_IN_KERNEL
  1575. /* In kernel Refuse to enter negative number */
  1576. if (SECUREC_CONVERT_IS_UNSIGNED(spec->oriConvChr)) {
  1577. return -1;
  1578. }
  1579. #endif
  1580. }
  1581. SECUREC_FILED_WIDTH_DEC(spec); /* Do not need to check width here, must be greater than 0 */
  1582. spec->ch = SecGetChar(stream, &(spec->charCount)); /* Eat + or - */
  1583. spec->ch = SecGetChar(stream, &(spec->charCount)); /* Get next character, used for the '0' judgments */
  1584. SecUnGetChar(spec->ch, stream, &(spec->charCount)); /* Not sure if it was actually read, so push back */
  1585. }
  1586. if (spec->oriConvChr == 'i') {
  1587. spec->convChr = 'd'; /* The i could be d, o, or x, use d as default */
  1588. }
  1589. if (spec->ch == SECUREC_CHAR('0') && (spec->oriConvChr == 'x' || spec->oriConvChr == 'i') &&
  1590. SECUREC_FILED_WIDTH_ENOUGH(spec)) {
  1591. /* Input string begin with 0, may be 0x123 0X123 0123 0x 01 0yy 09 0 0ab 00 */
  1592. SECUREC_FILED_WIDTH_DEC(spec);
  1593. spec->ch = SecGetChar(stream, &(spec->charCount)); /* ch is '0' */
  1594. /* Read only '0' due to width limitation */
  1595. if (!SECUREC_FILED_WIDTH_ENOUGH(spec)) {
  1596. /* The number or number64 in spec has been set 0 */
  1597. return 0;
  1598. }
  1599. spec->ch = SecGetChar(stream, &(spec->charCount)); /* Get next char to check x or X, do not dec width */
  1600. if ((SecChar)spec->ch == SECUREC_CHAR('x') || (SecChar)spec->ch == SECUREC_CHAR('X')) {
  1601. spec->convChr = 'x';
  1602. SECUREC_FILED_WIDTH_DEC(spec); /* Make incorrect width for x or X */
  1603. } else {
  1604. if (spec->oriConvChr == 'i') {
  1605. spec->convChr = 'o';
  1606. }
  1607. /* For "0y" "08" "01" "0a" ... ,push the 'y' '8' '1' 'a' back */
  1608. SecUnGetChar(spec->ch, stream, &(spec->charCount));
  1609. /* Since 0 has been read, it indicates that a valid character has been read */
  1610. spec->numberState = SECUREC_NUMBER_STATE_STARTED;
  1611. }
  1612. }
  1613. return SecInputNumberDigital(stream, spec);
  1614. }
  1615. /*
  1616. * Scan %c %s %[
  1617. * Return 0 OK
  1618. */
  1619. SECUREC_INLINE int SecInputString(SecFileStream *stream, SecScanSpec *spec,
  1620. const SecBracketTable *bracketTable, int *doneCount)
  1621. {
  1622. void *startPtr = spec->argPtr;
  1623. int suppressed = 0;
  1624. int errNoMem = 0;
  1625. while (SECUREC_FILED_WIDTH_ENOUGH(spec)) {
  1626. SECUREC_FILED_WIDTH_DEC(spec);
  1627. spec->ch = SecGetChar(stream, &(spec->charCount));
  1628. /*
  1629. * The char condition or string condition and bracket condition.
  1630. * Only supports wide characters with a maximum length of two bytes
  1631. */
  1632. if (spec->ch != SECUREC_EOF && (SecCanInputCharacter(spec->convChr) != 0 ||
  1633. SecCanInputString(spec->convChr, spec->ch) != 0 ||
  1634. SecCanInputForBracket(spec->convChr, spec->ch, bracketTable) != 0)) {
  1635. if (spec->suppress != 0) {
  1636. /* Used to identify processed data for %*, use argPtr to identify will cause 613, so use suppressed */
  1637. suppressed = 1;
  1638. continue;
  1639. }
  1640. /* Now suppress is not set */
  1641. if (spec->arrayWidth == 0) {
  1642. errNoMem = 1; /* We have exhausted the user's buffer */
  1643. break;
  1644. }
  1645. #ifdef SECUREC_FOR_WCHAR
  1646. errNoMem = SecInputForWchar(spec);
  1647. #else
  1648. errNoMem = SecInputForChar(spec, stream);
  1649. #endif
  1650. if (errNoMem != 0) {
  1651. break;
  1652. }
  1653. } else {
  1654. SecUnGetChar(spec->ch, stream, &(spec->charCount));
  1655. break;
  1656. }
  1657. }
  1658. if (errNoMem != 0) {
  1659. /* In case of error, blank out the input buffer */
  1660. SecAddEndingZero(startPtr, spec);
  1661. return -1;
  1662. }
  1663. if ((spec->suppress != 0 && suppressed == 0) ||
  1664. (spec->suppress == 0 && startPtr == spec->argPtr)) {
  1665. /* No input was scanned */
  1666. return -1;
  1667. }
  1668. if (spec->convChr != 'c') {
  1669. /* Add null-terminate for strings */
  1670. SecAddEndingZero(spec->argPtr, spec);
  1671. }
  1672. if (spec->suppress == 0) {
  1673. *doneCount = *doneCount + 1;
  1674. }
  1675. return 0;
  1676. }
  1677. #ifdef SECUREC_FOR_WCHAR
  1678. /*
  1679. * Alloce buffer for wchar version of %[.
  1680. * Return 0 OK
  1681. */
  1682. SECUREC_INLINE int SecAllocBracketTable(SecBracketTable *bracketTable)
  1683. {
  1684. if (bracketTable->table == NULL) {
  1685. /* Table should be freed after use */
  1686. bracketTable->table = (unsigned char *)SECUREC_MALLOC(SECUREC_BRACKET_TABLE_SIZE);
  1687. if (bracketTable->table == NULL) {
  1688. return -1;
  1689. }
  1690. }
  1691. return 0;
  1692. }
  1693. /*
  1694. * Free buffer for wchar version of %[
  1695. */
  1696. SECUREC_INLINE void SecFreeBracketTable(SecBracketTable *bracketTable)
  1697. {
  1698. if (bracketTable->table != NULL) {
  1699. SECUREC_FREE(bracketTable->table);
  1700. bracketTable->table = NULL;
  1701. }
  1702. }
  1703. #endif
  1704. #ifdef SECUREC_FOR_WCHAR
  1705. /*
  1706. * Formatting input core functions for wchar version.Called by a function such as vswscanf_s
  1707. */
  1708. int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList)
  1709. #else
  1710. /*
  1711. * Formatting input core functions for char version.Called by a function such as vsscanf_s
  1712. */
  1713. int SecInputS(SecFileStream *stream, const char *cFormat, va_list argList)
  1714. #endif
  1715. {
  1716. const SecUnsignedChar *format = (const SecUnsignedChar *)cFormat;
  1717. SecBracketTable bracketTable = SECUREC_INIT_BRACKET_TABLE;
  1718. SecScanSpec spec;
  1719. int doneCount = 0;
  1720. int formatError = 0;
  1721. int paraIsNull = 0;
  1722. int match = 0; /* When % is found , inc this value */
  1723. int errRet = 0;
  1724. #if SECUREC_ENABLE_SCANF_FLOAT
  1725. SecFloatSpec floatSpec;
  1726. SecInitFloatSpec(&floatSpec);
  1727. #endif
  1728. spec.ch = 0; /* Need to initialize to 0 */
  1729. spec.charCount = 0; /* Need to initialize to 0 */
  1730. /* Format must not NULL, use err < 1 to claer 845 */
  1731. while (errRet < 1 && *format != SECUREC_CHAR('\0')) {
  1732. /* Skip space in format and space in input */
  1733. if (SecIsSpace((SecInt)(int)(*format)) != 0) {
  1734. /* Read first no space char */
  1735. spec.ch = SecSkipSpaceChar(stream, &(spec.charCount));
  1736. /* Read the EOF cannot be returned directly here, because the case of " %n" needs to be handled */
  1737. /* Put fist no space char backup. put EOF back is also OK, and to modify the character count */
  1738. SecUnGetChar(spec.ch, stream, &(spec.charCount));
  1739. SecSkipSpaceFormat(&format);
  1740. continue;
  1741. }
  1742. if (*format != SECUREC_CHAR('%')) {
  1743. spec.ch = SecGetChar(stream, &(spec.charCount));
  1744. if ((int)(*format) != (int)(spec.ch)) {
  1745. SecUnGetChar(spec.ch, stream, &(spec.charCount));
  1746. break;
  1747. }
  1748. ++format;
  1749. #if !defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION)
  1750. if (SecFilterWcharInFormat(&spec, &format, stream) != 0) {
  1751. break;
  1752. }
  1753. #endif
  1754. continue;
  1755. }
  1756. /* Now *format is % */
  1757. /* Set default value for each % */
  1758. SecSetDefaultScanSpec(&spec);
  1759. if (SecDecodeScanFlag(&format, &spec) != 0) {
  1760. formatError = 1;
  1761. ++errRet;
  1762. continue;
  1763. }
  1764. if (!SECUREC_FILED_WIDTH_ENOUGH(&spec)) {
  1765. /* 0 width in format */
  1766. ++errRet;
  1767. continue;
  1768. }
  1769. /* Update wchar flag for %S %C */
  1770. SecUpdateWcharFlagByType(*format, &spec);
  1771. spec.convChr = SECUREC_TO_LOWERCASE(*format);
  1772. spec.oriConvChr = spec.convChr; /* convChr may be modified to handle integer logic */
  1773. if (spec.convChr != 'n') {
  1774. if (spec.convChr != 'c' && spec.convChr != SECUREC_BRACE) {
  1775. spec.ch = SecSkipSpaceChar(stream, &(spec.charCount));
  1776. } else {
  1777. spec.ch = SecGetChar(stream, &(spec.charCount));
  1778. }
  1779. if (spec.ch == SECUREC_EOF) {
  1780. ++errRet;
  1781. continue;
  1782. }
  1783. }
  1784. /* Now no 0 width in format and get one char from input */
  1785. switch (spec.oriConvChr) {
  1786. case 'c': /* Also 'C' */
  1787. if (spec.widthSet == 0) {
  1788. spec.widthSet = 1;
  1789. spec.width = 1;
  1790. }
  1791. /* fall-through */ /* FALLTHRU */
  1792. case 's': /* Also 'S': */
  1793. /* fall-through */ /* FALLTHRU */
  1794. case SECUREC_BRACE:
  1795. /* Unset last char to stream */
  1796. SecUnGetChar(spec.ch, stream, &(spec.charCount));
  1797. /* Check dest buffer and size */
  1798. if (spec.suppress == 0) {
  1799. spec.argPtr = (void *)va_arg(argList, void *);
  1800. if (spec.argPtr == NULL) {
  1801. paraIsNull = 1;
  1802. ++errRet;
  1803. continue;
  1804. }
  1805. /* Get the next argument, size of the array in characters */
  1806. spec.arrayWidth = SECUREC_GET_ARRAYWIDTH(argList);
  1807. if (SECUREC_ARRAY_WIDTH_IS_WRONG(spec)) {
  1808. /* Do not clear buffer just go error */
  1809. ++errRet;
  1810. continue;
  1811. }
  1812. /* One element is needed for '\0' for %s and %[ */
  1813. if (spec.convChr != 'c') {
  1814. --spec.arrayWidth;
  1815. }
  1816. } else {
  1817. /* Set argPtr to NULL is necessary, in supress mode we don't use argPtr to store data */
  1818. spec.argPtr = NULL;
  1819. }
  1820. if (spec.convChr == SECUREC_BRACE) {
  1821. /* Malloc when first %[ is meet for wchar version */
  1822. #ifdef SECUREC_FOR_WCHAR
  1823. if (SecAllocBracketTable(&bracketTable) != 0) {
  1824. ++errRet;
  1825. continue;
  1826. }
  1827. #endif
  1828. (void)SECUREC_MEMSET_FUNC_OPT(bracketTable.table, 0, (size_t)SECUREC_BRACKET_TABLE_SIZE);
  1829. if (SecSetupBracketTable(&format, &bracketTable) != 0) {
  1830. ++errRet;
  1831. continue;
  1832. }
  1833. if (*format == SECUREC_CHAR('\0')) {
  1834. /* Default add string terminator */
  1835. SecAddEndingZero(spec.argPtr, &spec);
  1836. ++errRet;
  1837. /* Truncated format */
  1838. continue;
  1839. }
  1840. }
  1841. /* Set completed. Now read string or character */
  1842. if (SecInputString(stream, &spec, &bracketTable, &doneCount) != 0) {
  1843. ++errRet;
  1844. continue;
  1845. }
  1846. break;
  1847. case 'p':
  1848. /* Make %hp same as %p */
  1849. spec.numberWidth = SECUREC_NUM_WIDTH_INT;
  1850. #ifdef SECUREC_ON_64BITS
  1851. spec.numberArgType = 1;
  1852. #endif
  1853. /* fall-through */ /* FALLTHRU */
  1854. case 'o': /* fall-through */ /* FALLTHRU */
  1855. case 'u': /* fall-through */ /* FALLTHRU */
  1856. case 'd': /* fall-through */ /* FALLTHRU */
  1857. case 'i': /* fall-through */ /* FALLTHRU */
  1858. case 'x':
  1859. /* Unset last char to stream */
  1860. SecUnGetChar(spec.ch, stream, &(spec.charCount));
  1861. if (SecInputNumber(stream, &spec) != 0) {
  1862. ++errRet;
  1863. continue;
  1864. }
  1865. if (spec.suppress == 0) {
  1866. spec.argPtr = (void *)va_arg(argList, void *);
  1867. if (spec.argPtr == NULL) {
  1868. paraIsNull = 1;
  1869. ++errRet;
  1870. continue;
  1871. }
  1872. SecAssignNumber(&spec);
  1873. ++doneCount;
  1874. }
  1875. break;
  1876. case 'n': /* Char count */
  1877. if (spec.suppress == 0) {
  1878. spec.argPtr = (void *)va_arg(argList, void *);
  1879. if (spec.argPtr == NULL) {
  1880. paraIsNull = 1;
  1881. ++errRet;
  1882. continue;
  1883. }
  1884. spec.number = (unsigned long)(unsigned int)(spec.charCount);
  1885. spec.numberArgType = 0;
  1886. SecAssignNumber(&spec);
  1887. }
  1888. break;
  1889. case 'e': /* fall-through */ /* FALLTHRU */
  1890. case 'f': /* fall-through */ /* FALLTHRU */
  1891. case 'g': /* Scan a float */
  1892. /* Unset last char to stream */
  1893. SecUnGetChar(spec.ch, stream, &(spec.charCount));
  1894. #if SECUREC_ENABLE_SCANF_FLOAT
  1895. if (SecInputFloat(stream, &spec, &floatSpec) != 0) {
  1896. ++errRet;
  1897. continue;
  1898. }
  1899. if (spec.suppress == 0) {
  1900. spec.argPtr = (void *)va_arg(argList, void *);
  1901. if (spec.argPtr == NULL) {
  1902. ++errRet;
  1903. paraIsNull = 1;
  1904. continue;
  1905. }
  1906. if (SecAssignFloat(&floatSpec, &spec) != 0) {
  1907. ++errRet;
  1908. continue;
  1909. }
  1910. ++doneCount;
  1911. }
  1912. break;
  1913. #else /* SECUREC_ENABLE_SCANF_FLOAT */
  1914. ++errRet;
  1915. continue;
  1916. #endif
  1917. default:
  1918. if ((int)(*format) != (int)spec.ch) {
  1919. SecUnGetChar(spec.ch, stream, &(spec.charCount));
  1920. formatError = 1;
  1921. ++errRet;
  1922. continue;
  1923. } else {
  1924. --match; /* Compensate for the self-increment of the following code */
  1925. }
  1926. break;
  1927. }
  1928. ++match;
  1929. ++format;
  1930. }
  1931. #ifdef SECUREC_FOR_WCHAR
  1932. SecFreeBracketTable(&bracketTable);
  1933. #endif
  1934. #if SECUREC_ENABLE_SCANF_FLOAT
  1935. SecFreeFloatSpec(&floatSpec, &doneCount);
  1936. #endif
  1937. #if SECUREC_ENABLE_SCANF_FILE
  1938. SecAdjustStream(stream);
  1939. #endif
  1940. if (spec.ch == SECUREC_EOF) {
  1941. return ((doneCount != 0 || match != 0) ? doneCount : SECUREC_SCANF_EINVAL);
  1942. }
  1943. if (formatError != 0 || paraIsNull != 0) {
  1944. /* Invalid Input Format or parameter, but not meet EOF */
  1945. return SECUREC_SCANF_ERROR_PARA;
  1946. }
  1947. return doneCount;
  1948. }
  1949. #if SECUREC_ENABLE_SCANF_FILE
  1950. /*
  1951. * Get char from stream use std function
  1952. */
  1953. SECUREC_INLINE SecInt SecGetCharFromStream(const SecFileStream *stream)
  1954. {
  1955. SecInt ch;
  1956. ch = SECUREC_GETC(stream->pf);
  1957. return ch;
  1958. }
  1959. /*
  1960. * Try to read the BOM header, when meet a BOM head, discard it, then data is Aligned to base
  1961. */
  1962. SECUREC_INLINE void SecReadAndSkipBomHeader(SecFileStream *stream)
  1963. {
  1964. /* Use size_t type conversion to clean e747 */
  1965. stream->count = fread(stream->base, (size_t)1, (size_t)SECUREC_BOM_HEADER_SIZE, stream->pf);
  1966. if (stream->count > SECUREC_BOM_HEADER_SIZE) {
  1967. stream->count = 0;
  1968. }
  1969. if (SECUREC_BEGIN_WITH_BOM(stream->base, stream->count)) {
  1970. /* It's BOM header, discard it */
  1971. stream->count = 0;
  1972. }
  1973. }
  1974. /*
  1975. * Get char from file stream or buffer
  1976. */
  1977. SECUREC_INLINE SecInt SecGetCharFromFile(SecFileStream *stream)
  1978. {
  1979. SecInt ch;
  1980. if (stream->count < sizeof(SecChar)) {
  1981. /* Load file to buffer */
  1982. size_t len;
  1983. if (stream->base != NULL) {
  1984. /* Put the last unread data in the buffer head */
  1985. for (len = 0; len < stream->count; ++len) {
  1986. stream->base[len] = stream->cur[len];
  1987. }
  1988. } else {
  1989. stream->oriFilePos = ftell(stream->pf); /* Save original file read position */
  1990. if (stream->oriFilePos == -1) {
  1991. /* It may be a pipe stream */
  1992. stream->flag = SECUREC_PIPE_STREAM_FLAG;
  1993. return SecGetCharFromStream(stream);
  1994. }
  1995. /* Reserve the length of BOM head */
  1996. stream->base = (char *)SECUREC_MALLOC(SECUREC_BUFFERED_BLOK_SIZE +
  1997. SECUREC_BOM_HEADER_SIZE + sizeof(SecChar)); /* To store '\0' and aligned to wide char */
  1998. if (stream->base == NULL) {
  1999. return SECUREC_EOF;
  2000. }
  2001. /* First read file */
  2002. if (stream->oriFilePos == 0) {
  2003. /* Make sure the data is aligned to base */
  2004. SecReadAndSkipBomHeader(stream);
  2005. }
  2006. }
  2007. /* Skip existing data and read data */
  2008. len = fread(stream->base + stream->count, (size_t)1, (size_t)SECUREC_BUFFERED_BLOK_SIZE, stream->pf);
  2009. if (len > SECUREC_BUFFERED_BLOK_SIZE) { /* It won't happen, */
  2010. len = 0;
  2011. }
  2012. stream->count += len;
  2013. stream->cur = stream->base;
  2014. stream->flag |= SECUREC_LOAD_FILE_TO_MEM_FLAG;
  2015. stream->base[stream->count] = '\0'; /* For tool Warning string null */
  2016. }
  2017. SECUREC_GET_CHAR(stream, &ch);
  2018. if (ch != SECUREC_EOF) {
  2019. stream->fileRealRead += sizeof(SecChar);
  2020. }
  2021. return ch;
  2022. }
  2023. #endif
  2024. /*
  2025. * Get char for wchar version
  2026. */
  2027. SECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter)
  2028. {
  2029. *counter = *counter + 1; /* Always plus 1 */
  2030. /* The main scenario is scanf str */
  2031. if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) {
  2032. SecInt ch;
  2033. SECUREC_GET_CHAR(stream, &ch);
  2034. return ch;
  2035. }
  2036. #if SECUREC_ENABLE_SCANF_FILE
  2037. if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0) {
  2038. return SecGetCharFromFile(stream);
  2039. }
  2040. if ((stream->flag & SECUREC_PIPE_STREAM_FLAG) != 0) {
  2041. return SecGetCharFromStream(stream);
  2042. }
  2043. #endif
  2044. return SECUREC_EOF;
  2045. }
  2046. /*
  2047. * Unget Public realizatio char for wchar and char version
  2048. */
  2049. SECUREC_INLINE void SecUnGetCharImpl(SecInt ch, SecFileStream *stream)
  2050. {
  2051. if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) {
  2052. SECUREC_UN_GET_CHAR(stream);
  2053. return;
  2054. }
  2055. #if SECUREC_ENABLE_SCANF_FILE
  2056. if ((stream->flag & SECUREC_LOAD_FILE_TO_MEM_FLAG) != 0) {
  2057. SECUREC_UN_GET_CHAR(stream);
  2058. if (stream->fileRealRead > 0) {
  2059. stream->fileRealRead -= sizeof(SecChar);
  2060. }
  2061. return;
  2062. }
  2063. if ((stream->flag & SECUREC_PIPE_STREAM_FLAG) != 0) {
  2064. (void)SECUREC_UN_GETC(ch, stream->pf);
  2065. return;
  2066. }
  2067. #else
  2068. (void)ch; /* To clear e438 last value assigned not used , the compiler will optimize this code */
  2069. #endif
  2070. }
  2071. /*
  2072. * Unget char for char version
  2073. */
  2074. SECUREC_INLINE void SecUnGetChar(SecInt ch, SecFileStream *stream, int *counter)
  2075. {
  2076. *counter = *counter - 1; /* Always mius 1 */
  2077. if (ch != SECUREC_EOF) {
  2078. SecUnGetCharImpl(ch, stream);
  2079. }
  2080. }
  2081. /*
  2082. * Skip space char by isspace
  2083. */
  2084. SECUREC_INLINE SecInt SecSkipSpaceChar(SecFileStream *stream, int *counter)
  2085. {
  2086. SecInt ch;
  2087. do {
  2088. ch = SecGetChar(stream, counter);
  2089. if (ch == SECUREC_EOF) {
  2090. break;
  2091. }
  2092. } while (SecIsSpace(ch) != 0);
  2093. return ch;
  2094. }
  2095. #endif /* INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27 */