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