• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /* [Standardize-exceptions]: Performance-sensitive
16  * [reason]: Strict parameter verification has been done before use
17  */
18 
19 #ifndef __SECURECTYPE_H__A7BBB686_AADA_451B_B9F9_44DACDAE18A7
20 #define __SECURECTYPE_H__A7BBB686_AADA_451B_B9F9_44DACDAE18A7
21 
22 #ifndef SECUREC_ONLY_DECLARE_MEMSET
23 /* Shielding VC symbol redefinition warning */
24 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
25 #ifdef __STDC_WANT_SECURE_LIB__
26 #undef __STDC_WANT_SECURE_LIB__
27 #endif
28 #define __STDC_WANT_SECURE_LIB__ 0
29 #ifdef _CRTIMP_ALTERNATIVE
30 #undef _CRTIMP_ALTERNATIVE
31 #endif
32 #define _CRTIMP_ALTERNATIVE     //comment microsoft *_s function
33 #endif
34 #endif
35 
36 #if SECUREC_IN_KERNEL
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #else
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdlib.h>
43 #endif
44 
45 /* if enable SECUREC_COMPATIBLE_WIN_FORMAT, the output format will be compatible to Windows. */
46 #if (defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER))
47 #define SECUREC_COMPATIBLE_WIN_FORMAT
48 #endif
49 
50 #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
51 /* in windows platform, can't use optimized function for there is no __builtin_constant_p like function */
52 /* If need optimized macro, can define this: define __builtin_constant_p(x) 0 */
53 #ifdef SECUREC_WITH_PERFORMANCE_ADDONS
54 #undef SECUREC_WITH_PERFORMANCE_ADDONS
55 #define SECUREC_WITH_PERFORMANCE_ADDONS 0
56 #endif
57 #endif
58 
59 #if defined(__VXWORKS__) || defined(__vxworks) || defined(__VXWORKS) || defined(_VXWORKS_PLATFORM_)  || \
60     defined(SECUREC_VXWORKS_VERSION_5_4)
61 #if  !defined(SECUREC_VXWORKS_PLATFORM)
62 #define SECUREC_VXWORKS_PLATFORM
63 #endif
64 #endif
65 
66 /* if enable SECUREC_COMPATIBLE_LINUX_FORMAT, the output format will be compatible to Linux. */
67 #if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM))
68 #define SECUREC_COMPATIBLE_LINUX_FORMAT
69 #endif
70 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
71 #include <stddef.h>
72 #endif
73 
74 /* add  the -DSECUREC_SUPPORT_FORMAT_WARNING  compiler option to support  -Wformat.
75  * default does not check the format is that the same data type in the actual code
76  * in the product is different in the original data type definition of VxWorks and Linux.
77  */
78 #ifndef SECUREC_SUPPORT_FORMAT_WARNING
79 #define SECUREC_SUPPORT_FORMAT_WARNING 0
80 #endif
81 
82 /* SECUREC_PCLINT for tool do not recognize __attribute__  just for pclint */
83 #if SECUREC_SUPPORT_FORMAT_WARNING && !defined(SECUREC_PCLINT)
84 #define SECUREC_ATTRIBUTE(x, y)  __attribute__((format(printf, (x), (y))))
85 #else
86 #define SECUREC_ATTRIBUTE(x, y)
87 #endif
88 
89 /* SECUREC_PCLINT for tool do not recognize __builtin_expect ,just for pclint */
90 #if defined(__GNUC__) && \
91     ((__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3 /* above 3.4 */))) && \
92     !defined(SECUREC_PCLINT)
93 /* This is a built-in function that can be used without a declaration, if you encounter an undeclared compilation alarm,
94  * you can add -DSECUREC_NEED_BUILTIN_EXPECT_DECLARE to compiler options
95  */
96 #if defined(SECUREC_NEED_BUILTIN_EXPECT_DECLARE)
97 long __builtin_expect(long exp, long c);
98 #endif
99 #define SECUREC_LIKELY(x) __builtin_expect(!!(x), 1)
100 #define SECUREC_UNLIKELY(x) __builtin_expect(!!(x), 0)
101 #else
102 #define SECUREC_LIKELY(x) (x)
103 #define SECUREC_UNLIKELY(x) (x)
104 #endif
105 
106 /* define the max length of the string */
107 #define SECUREC_STRING_MAX_LEN (0x7fffffffUL)
108 #define SECUREC_WCHAR_STRING_MAX_LEN (SECUREC_STRING_MAX_LEN / sizeof(wchar_t))
109 
110 /* add SECUREC_MEM_MAX_LEN for memcpy and memmove */
111 #define SECUREC_MEM_MAX_LEN (0x7fffffffUL)
112 #define SECUREC_WCHAR_MEM_MAX_LEN (SECUREC_MEM_MAX_LEN / sizeof(wchar_t))
113 
114 #if SECUREC_STRING_MAX_LEN > 0x7fffffff
115 #error "max string is 2G"
116 #endif
117 
118 #if (defined(__GNUC__ ) && defined(__SIZEOF_POINTER__ ))
119 #if (__SIZEOF_POINTER__ != 4) && (__SIZEOF_POINTER__ != 8)
120 #error "unsupported system"
121 #endif
122 #endif
123 
124 #ifndef SECUREC_MALLOC
125 #define SECUREC_MALLOC(x) malloc((size_t)(x))
126 #endif
127 
128 #ifndef SECUREC_FREE
129 #define SECUREC_FREE(x)   free((void *)(x))
130 #endif
131 
132 #if defined(_WIN64) || defined(WIN64) || defined(__LP64__) || defined(_LP64)
133 #define SECUREC_ON_64BITS
134 #endif
135 
136 #if (!defined(SECUREC_ON_64BITS) && defined(__GNUC__ ) && defined(__SIZEOF_POINTER__ ))
137 #if __SIZEOF_POINTER__ == 8
138 #define SECUREC_ON_64BITS
139 #endif
140 #endif
141 
142 #if defined(__SVR4) || defined(__svr4__)
143 #define SECUREC_ON_SOLARIS
144 #endif
145 
146 #if (defined(__hpux) || defined(_AIX) || defined(SECUREC_ON_SOLARIS))
147 #define SECUREC_ON_UNIX
148 #endif
149 
150 /* codes should run under the macro SECUREC_COMPATIBLE_LINUX_FORMAT in unknown system on default,
151  * and strtold. The function
152  * strtold is referenced first at ISO9899:1999(C99), and some old compilers can
153  * not support these functions. Here provides a macro to open these functions:
154  * SECUREC_SUPPORT_STRTOLD  -- if defined, strtold will   be used
155  */
156 #ifndef SECUREC_SUPPORT_STRTOLD
157 #define SECUREC_SUPPORT_STRTOLD 0
158 #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT))
159 #if defined(__USE_ISOC99)  || \
160     (defined(_AIX) && defined(_ISOC99_SOURCE)) || \
161     (defined(__hpux) && defined(__ia64)) || \
162     (defined(SECUREC_ON_SOLARIS) &&  (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
163      defined(_STDC_C99) || defined(__EXTENSIONS__))
164 #undef  SECUREC_SUPPORT_STRTOLD
165 #define SECUREC_SUPPORT_STRTOLD 1
166 #endif
167 #endif
168 #if ((defined(SECUREC_WRLINUX_BELOW4) || defined(_WRLINUX_BELOW4_)))
169 #undef  SECUREC_SUPPORT_STRTOLD
170 #define SECUREC_SUPPORT_STRTOLD 0
171 #endif
172 #endif
173 
174 #if SECUREC_WITH_PERFORMANCE_ADDONS
175 
176 #ifndef SECUREC_TWO_MIN
177 #define SECUREC_TWO_MIN(a, b) ((a) < (b) ? (a) : (b))
178 #endif
179 
180 /* for strncpy_s performance optimization */
181 #define SECUREC_STRNCPY_SM(dest, destMax, src, count) \
182     (((void *)dest != NULL && (void *)src != NULL  && (size_t)destMax >0 && \
183         (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \
184         (SECUREC_TWO_MIN(count , strlen(src)) + 1) <= (size_t)destMax) ? \
185         ((count < strlen(src))? (memcpy(dest, src, count), *((char *)dest + count) = '\0', EOK): \
186         (memcpy(dest, src, strlen(src) + 1), EOK )) :(strncpy_error(dest, destMax, src, count)))
187 
188 #define SECUREC_STRCPY_SM(dest, destMax, src) \
189     (((void *)dest != NULL && (void *)src != NULL && (size_t)destMax >0 && \
190         (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \
191         (strlen(src) + 1) <= (size_t)destMax)? (memcpy(dest, src, strlen(src) + 1), EOK): \
192         (strcpy_error(dest, destMax, src)))
193 
194 /* for strcat_s performance optimization */
195 #if defined(__GNUC__)
196 #define SECUREC_STRCAT_SM(dest, destMax, src) \
197     ({ \
198         int catRet = EOK; \
199         if ((void *)dest != NULL && (void *)src != NULL && (size_t)(destMax) >0 && \
200             (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \
201             char *catTmpDst = (dest); \
202             size_t catRestSize = (destMax); \
203             while(catRestSize > 0 && *catTmpDst) { \
204                 ++catTmpDst; \
205                 --catRestSize; \
206             } \
207             if (catRestSize == 0) { \
208                 catRet = EINVAL; \
209             } else if ((strlen(src) + 1) <= catRestSize) { \
210                 (void)memcpy(catTmpDst, (src), strlen(src) + 1); \
211                 catRet = EOK; \
212             } else { \
213                 catRet = ERANGE; \
214             } \
215             if (catRet != EOK) { \
216                 catRet = strcat_s((dest), (destMax), (src)); \
217             } \
218         } else { \
219             catRet = strcat_s((dest), (destMax), (src)); \
220         } \
221         catRet; \
222     })
223 #else
224 #define SECUREC_STRCAT_SM(dest, destMax, src) strcat_s(dest, destMax, src)
225 #endif
226 
227 /* for strncat_s performance optimization */
228 #if defined(__GNUC__)
229 #define SECUREC_STRNCAT_SM(dest, destMax, src, count) \
230     ({ \
231         int ncatRet = EOK; \
232         if ((void *)dest != NULL && (void *)src != NULL && (size_t)destMax > 0 && \
233             (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)  && \
234             (((unsigned long long)(count) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \
235             char *ncatTmpDest = (dest); \
236             size_t ncatRestSize = (destMax); \
237             while(ncatRestSize > 0 && *ncatTmpDest) { \
238                 ++ncatTmpDest; \
239                 --ncatRestSize; \
240             } \
241             if (ncatRestSize == 0) { \
242                 ncatRet = EINVAL; \
243             } else if ((SECUREC_TWO_MIN((count) , strlen(src)) + 1) <= ncatRestSize ) { \
244                 if ((count) < strlen(src)) { \
245                     (void)memcpy(ncatTmpDest, (src), (count)); \
246                     *(ncatTmpDest + (count)) = '\0'; \
247                 } else { \
248                     (void)memcpy(ncatTmpDest, (src), strlen(src) + 1); \
249                 } \
250             } else { \
251                 ncatRet = ERANGE; \
252             } \
253             if (ncatRet != EOK) { \
254                 ncatRet = strncat_s((dest), (destMax), (src), (count)); \
255             } \
256         } else { \
257             ncatRet = strncat_s((dest), (destMax), (src), (count)); \
258         } \
259         ncatRet; \
260     })
261 #else
262 #define SECUREC_STRNCAT_SM(dest, destMax, src, count) strncat_s(dest, destMax, src, count)
263 #endif
264 
265 /* SECUREC_MEMCPY_SM do NOT check buffer overlap by default */
266 #define  SECUREC_MEMCPY_SM(dest, destMax, src, count) \
267     (!(((size_t)destMax == 0 )||(((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \
268         ((size_t)count > (size_t)destMax) || ((void *)dest) == NULL || ((void *)src == NULL))? \
269         (memcpy(dest, src, count), EOK) : \
270         (memcpy_s(dest, destMax, src, count)))
271 
272 #define  SECUREC_MEMSET_SM(dest, destMax, c, count) \
273     (!(((size_t)destMax == 0 ) || (((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \
274         ((void *)dest == NULL) || ((size_t)count > (size_t)destMax)) ? \
275         (memset(dest, c, count), EOK) : \
276         ( memset_s(dest, destMax, c, count)))
277 
278 #endif
279 #endif /* __SECURECTYPE_H__A7BBB686_AADA_451B_B9F9_44DACDAE18A7 */
280