You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

input.inl 72 kB

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