1 /* 2 * Copyright (c) 2022 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 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 supoort -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))) && \ 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 #if defined(_WIN64) || defined(WIN64) || defined(__LP64__) || defined(_LP64) 125 #define SECUREC_ON_64BITS 126 #endif 127 128 #if (!defined(SECUREC_ON_64BITS) && defined(__GNUC__ ) && defined(__SIZEOF_POINTER__ )) 129 #if __SIZEOF_POINTER__ == 8 130 #define SECUREC_ON_64BITS 131 #endif 132 #endif 133 134 #if defined(__SVR4) || defined(__svr4__) 135 #define SECUREC_ON_SOLARIS 136 #endif 137 138 #if (defined(__hpux) || defined(_AIX) || defined(SECUREC_ON_SOLARIS)) 139 #define SECUREC_ON_UNIX 140 #endif 141 142 /* codes should run under the macro SECUREC_COMPATIBLE_LINUX_FORMAT in unknown system on default, 143 * and strtold. The function 144 * strtold is referenced first at ISO9899:1999(C99), and some old compilers can 145 * not support these functions. Here provides a macro to open these functions: 146 * SECUREC_SUPPORT_STRTOLD -- if defined, strtold will be used 147 */ 148 #ifndef SECUREC_SUPPORT_STRTOLD 149 #define SECUREC_SUPPORT_STRTOLD 0 150 #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) 151 #if defined(__USE_ISOC99) || \ 152 (defined(_AIX) && defined(_ISOC99_SOURCE)) || \ 153 (defined(__hpux) && defined(__ia64)) || \ 154 (defined(SECUREC_ON_SOLARIS) && (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \ 155 defined(_STDC_C99) || defined(__EXTENSIONS__)) 156 #undef SECUREC_SUPPORT_STRTOLD 157 #define SECUREC_SUPPORT_STRTOLD 1 158 #endif 159 #endif 160 #if ((defined(SECUREC_WRLINUX_BELOW4) || defined(_WRLINUX_BELOW4_))) 161 #undef SECUREC_SUPPORT_STRTOLD 162 #define SECUREC_SUPPORT_STRTOLD 0 163 #endif 164 #endif 165 166 #if SECUREC_WITH_PERFORMANCE_ADDONS 167 168 #ifndef SECUREC_TWO_MIN 169 #define SECUREC_TWO_MIN(a, b) ((a) < (b) ? (a) : (b)) 170 #endif 171 172 /* for strncpy_s performance optimization */ 173 #define SECUREC_STRNCPY_SM(dest, destMax, src, count) \ 174 (((void *)dest != NULL && (void *)src != NULL && (size_t)destMax >0 && \ 175 (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ 176 (SECUREC_TWO_MIN(count, strlen(src)) + 1) <= (size_t)destMax ) ? \ 177 ((count < strlen(src))? (memcpy(dest, src, count), *((char *)dest + count) = '\0', EOK): \ 178 (memcpy(dest, src, strlen(src) + 1), EOK)) : (strncpy_error(dest, destMax, src, count))) 179 180 #define SECUREC_STRCPY_SM(dest, destMax, src) \ 181 (((void *)dest != NULL && (void *)src != NULL && (size_t)destMax >0 && \ 182 (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ 183 (strlen(src) + 1) <= (size_t)destMax) ? (memcpy(dest, src, strlen(src) + 1), EOK): \ 184 (strcpy_error(dest, destMax, src))) 185 186 /* for strcat_s performance optimization */ 187 #if defined(__GNUC__) 188 #define SECUREC_STRCAT_SM(dest, destMax, src) \ 189 ( { \ 190 int catRet = EOK; \ 191 if ((void *)dest != NULL && (void *)src != NULL && (size_t)(destMax) >0 && \ 192 (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \ 193 char *catTmpDst = (dest); \ 194 size_t catRestSize = (destMax); \ 195 while (catRestSize > 0 && *catTmpDst) { \ 196 ++catTmpDst; \ 197 --catRestSize; \ 198 } \ 199 if (catRestSize == 0) { \ 200 catRet = EINVAL; \ 201 } else if ((strlen(src) + 1) <= catRestSize) { \ 202 memcpy(catTmpDst, (src), strlen(src) + 1); \ 203 catRet = EOK; \ 204 } else { \ 205 catRet = ERANGE; \ 206 } \ 207 if (catRet != EOK) { \ 208 catRet = strcat_s((dest), (destMax), (src)); \ 209 } \ 210 } else { \ 211 catRet = strcat_s((dest), (destMax), (src)); \ 212 } \ 213 catRet; \ 214 }) 215 #else 216 #define SECUREC_STRCAT_SM(dest, destMax, src) strcat_s(dest, destMax, src) 217 #endif 218 219 /* for strncat_s performance optimization */ 220 #if defined(__GNUC__) 221 #define SECUREC_STRNCAT_SM(dest, destMax, src, count) \ 222 ({ \ 223 int ncatRet = EOK; \ 224 if ((void *)dest != NULL && (void *)src != NULL && (size_t)destMax > 0 && \ 225 (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ 226 (((unsigned long long)(count) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \ 227 char *ncatTmpDest = (dest); \ 228 size_t ncatRestSize = (destMax); \ 229 while (ncatRestSize > 0 && *ncatTmpDest) { \ 230 ++ncatTmpDest; \ 231 --ncatRestSize; \ 232 } \ 233 if (ncatRestSize == 0) { \ 234 ncatRet = EINVAL; \ 235 } else if ((SECUREC_TWO_MIN((count), strlen(src)) + 1) <= ncatRestSize ) { \ 236 if ((count) < strlen(src)) { \ 237 memcpy(ncatTmpDest, (src), (count)); \ 238 *(ncatTmpDest + (count)) = '\0'; \ 239 } else { \ 240 memcpy(ncatTmpDest, (src), strlen(src) + 1); \ 241 } \ 242 } else { \ 243 ncatRet = ERANGE; \ 244 } \ 245 if (ncatRet != EOK) { \ 246 ncatRet = strncat_s((dest), (destMax), (src), (count)); \ 247 } \ 248 } else { \ 249 ncatRet = strncat_s((dest), (destMax), (src), (count)); \ 250 } \ 251 ncatRet; \ 252 }) 253 #else 254 #define SECUREC_STRNCAT_SM(dest, destMax, src, count) strncat_s(dest, destMax, src, count) 255 #endif 256 257 /* SECUREC_MEMCPY_SM do NOT check buffer overlap by default */ 258 #define SECUREC_MEMCPY_SM(dest, destMax, src, count) \ 259 (!(((size_t)destMax == 0 ) || (((unsigned long long)(destMax) & \ 260 (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \ 261 ((size_t)count > (size_t)destMax) || ((void *)dest) == NULL || ((void *)src == NULL))? \ 262 (memcpy(dest, src, count), EOK) : \ 263 (memcpy_s(dest, destMax, src, count))) 264 265 #define SECUREC_MEMSET_SM(dest, destMax, c, count) \ 266 (!(((size_t)destMax == 0 ) || (((unsigned long long)(destMax) & \ 267 (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \ 268 ((void *)dest == NULL) || ((size_t)count > (size_t)destMax)) ? \ 269 (memset(dest, c, count), EOK) : \ 270 (memset_s(dest, destMax, c, count))) 271 272 #endif 273 #endif /* __SECURECTYPE_H__A7BBB686_AADA_451B_B9F9_44DACDAE18A7 */ 274