• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. 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: By defining corresponding macro for ANSI string and including "output.inl",
12  *              this file generates real underlying function used by printf family API.
13  * Author: lishunda
14  * Create: 2014-02-25
15  */
16 
17 #define SECUREC_FORMAT_OUTPUT_INPUT 1
18 
19 #ifdef SECUREC_FOR_WCHAR
20 #undef SECUREC_FOR_WCHAR
21 #endif
22 
23 #include "secureprintoutput.h"
24 #if SECUREC_WARP_OUTPUT
25 #define SECUREC_FORMAT_FLAG_TABLE_SIZE 128
SecSkipKnownFlags(const char * format)26 SECUREC_INLINE const char *SecSkipKnownFlags(const char *format)
27 {
28     static const unsigned char flagTable[SECUREC_FORMAT_FLAG_TABLE_SIZE] = {
29         /*
30          * Known flag is  "0123456789 +-#hlLwZzjqt*I$"
31          */
32         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34         0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00,
35         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
37         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
38         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
39         0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
40     };
41     const char *fmt = format;
42     while (*fmt != '\0') {
43         char fmtChar = *fmt;
44         if ((unsigned char)fmtChar > 0x7f) { /* 0x7f is upper limit of format char value */
45             break;
46         }
47         if (flagTable[(unsigned char)fmtChar] == 0) {
48             break;
49         }
50         ++fmt;
51     }
52     return fmt;
53 }
54 
SecFormatContainN(const char * format)55 SECUREC_INLINE int SecFormatContainN(const char *format)
56 {
57     const char *fmt = format;
58     while (*fmt != '\0') {
59         ++fmt;
60         /* Skip normal char */
61         if (*(fmt - 1) != '%') {
62             continue;
63         }
64         /* Meet %% */
65         if (*fmt == '%') {
66             ++fmt; /* Point to  the character after the %. Correct handling %%xx */
67             continue;
68         }
69         /* Now parse %..., fmt point to the character after the % */
70         fmt = SecSkipKnownFlags(fmt);
71         if (*fmt == 'n') {
72             return 1;
73         }
74     }
75     return 0;
76 }
77 /*
78  * Multi character formatted output implementation, the count include \0 character, must be greater than zero
79  */
SecVsnprintfImpl(char * string,size_t count,const char * format,va_list argList)80 int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList)
81 {
82     int retVal;
83     if (SecFormatContainN(format) != 0) {
84         string[0] = '\0';
85         return -1;
86     }
87     retVal = vsnprintf(string, count, format, argList);
88     if (retVal >= (int)count) { /* The size_t to int is ok, count max is SECUREC_STRING_MAX_LEN */
89         /* The buffer was too small; we return truncation */
90         string[count - 1] = '\0';
91         return SECUREC_PRINTF_TRUNCATE;
92     }
93     if (retVal < 0) {
94         string[0] = '\0'; /* Empty the dest strDest */
95         return -1;
96     }
97     return retVal;
98 }
99 #else
100 #if SECUREC_IN_KERNEL
101 #include <linux/ctype.h>
102 #endif
103 
104 #ifndef EOF
105 #define EOF (-1)
106 #endif
107 
108 #include "output.inl"
109 
110 /*
111  * Multi character formatted output implementation
112  */
SecVsnprintfImpl(char * string,size_t count,const char * format,va_list argList)113 int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList)
114 {
115     SecPrintfStream str;
116     int retVal;
117 
118     str.count = (int)count; /* The count include \0 character, must be greater than zero */
119     str.cur = string;
120 
121     retVal = SecOutputS(&str, format, argList);
122     if (retVal >= 0) {
123         if (SecPutZeroChar(&str) == 0) {
124             return retVal;
125         }
126     }
127     if (str.count < 0) {
128         /* The buffer was too small, then truncate */
129         string[count - 1] = '\0';
130         return SECUREC_PRINTF_TRUNCATE;
131     }
132     string[0] = '\0'; /* Empty the dest string */
133     return -1;
134 }
135 
136 /*
137  * Write a wide character
138  */
SecWriteMultiChar(char ch,int num,SecPrintfStream * f,int * pnumwritten)139 SECUREC_INLINE void SecWriteMultiChar(char ch, int num, SecPrintfStream *f, int *pnumwritten)
140 {
141     int count;
142     for (count = num; count > 0; --count) {
143         --f->count; /* f -> count may be negative,indicating insufficient space */
144         if (f->count < 0) {
145             *pnumwritten = -1;
146             return;
147         }
148         *(f->cur) = ch;
149         ++f->cur;
150         *pnumwritten = *pnumwritten + 1;
151     }
152 }
153 
154 /*
155  * Write string function, where this function is called, make sure that len is greater than 0
156  */
SecWriteString(const char * string,int len,SecPrintfStream * f,int * pnumwritten)157 SECUREC_INLINE void SecWriteString(const char *string, int len, SecPrintfStream *f, int *pnumwritten)
158 {
159     const char *str = string;
160     int count;
161     for (count = len; count > 0; --count) {
162         --f->count; /* f -> count may be negative,indicating insufficient space */
163         if (f->count < 0) {
164             *pnumwritten = -1;
165             return;
166         }
167         *(f->cur) = *str;
168         ++f->cur;
169         ++str;
170     }
171     *pnumwritten = *pnumwritten + (int)(size_t)(str - string);
172 }
173 #endif
174 
175