Ticket #2996: 0003-Make-qmake-happy.patch
File 0003-Make-qmake-happy.patch, 19.2 KB (added by , 9 years ago) |
---|
-
source/lib/secure_crt.cpp
From 353bff26a63d4ce50d02f1117fa24fc731727562 Mon Sep 17 00:00:00 2001 From: BogDan Vatra <bogdan@kde.org> Date: Tue, 27 Jan 2015 14:10:24 +0200 Subject: [PATCH 3/6] Make qmake happy. --- source/lib/secure_crt.cpp | 272 +---------------------------------------- source/lib/secure_crt.inl | 295 +++++++++++++++++++++++++++++++++++++++++++++ source/lib/wsecure_crt.cpp | 2 +- 3 files changed, 298 insertions(+), 271 deletions(-) create mode 100644 source/lib/secure_crt.inl diff --git a/source/lib/secure_crt.cpp b/source/lib/secure_crt.cpp index 861c189..4eb7312 100644
a b 20 20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 21 */ 22 22 23 /* 24 * partial implementation of VC8's secure CRT functions 25 */ 23 // unicode version of secure_crt 26 24 27 25 #include "precompiled.h" 28 26 29 #include <stdio.h> 30 #include <errno.h> 31 #include <stdarg.h> 32 33 #include "lib/secure_crt.h" 34 35 #if OS_ANDROID 36 # include <boost/algorithm/string/replace.hpp> 37 #endif 38 39 // we were included from wsecure_crt.cpp; skip all stuff that 40 // must only be done once. 41 #ifndef WSECURE_CRT 42 static const StatusDefinition secureCrtStatusDefinitions[] = { 43 { ERR::STRING_NOT_TERMINATED, L"Invalid string (no 0 terminator found in buffer)" } 44 }; 45 STATUS_ADD_DEFINITIONS(secureCrtStatusDefinitions); 46 #endif 47 48 49 // written against http://std.dkuug.dk/jtc1/sc22/wg14/www/docs/n1031.pdf . 50 // optimized for size - e.g. strcpy calls strncpy with n = SIZE_MAX. 51 52 // since char and wide versions of these functions are basically the same, 53 // this source file implements generic versions and bridges the differences 54 // with these macros. wsecure_crt.cpp #defines WSECURE_CRT and 55 // includes this file. 56 57 // Note: These defines are all #undef:ed at the end of the file - remember to 58 // add a corresponding #undef when adding a #define. 59 #ifdef WSECURE_CRT 60 # define tchar wchar_t 61 # define tstring std::wstring 62 # define T(string_literal) L ## string_literal 63 # define tnlen wcsnlen 64 # define tncpy_s wcsncpy_s 65 # define tcpy_s wcscpy_s 66 # define tncat_s wcsncat_s 67 # define tcat_s wcscat_s 68 # define tcmp wcscmp 69 # define tcpy wcscpy 70 # define tvsnprintf vswprintf // used by implementation 71 # define tvsprintf_s vswprintf_s 72 # define tsprintf_s swprintf_s 73 #else 74 # define tchar char 75 # define tstring std::string 76 # define T(string_literal) string_literal 77 # define tnlen strnlen 78 # define tncpy_s strncpy_s 79 # define tcpy_s strcpy_s 80 # define tncat_s strncat_s 81 # define tcat_s strcat_s 82 # define tcmp strcmp 83 # define tcpy strcpy 84 # define tvsnprintf vsnprintf // used by implementation 85 # define tvsprintf_s vsprintf_s 86 # define tsprintf_s sprintf_s 87 #endif // #ifdef WSECURE_CRT 88 89 90 // return <retval> and raise an assertion if <condition> doesn't hold. 91 // usable as a statement. 92 #define ENFORCE(condition, err_to_warn, retval) STMT(\ 93 if(!(condition)) \ 94 { \ 95 DEBUG_WARN_ERR(err_to_warn); \ 96 return retval; \ 97 } \ 98 ) 99 100 // raise a debug warning if <len> is the size of a pointer. 101 // catches bugs such as: tchar* s = ..; tcpy_s(s, sizeof(s), T("..")); 102 // if warnings get annoying, replace with debug_printf. usable as a statement. 103 // 104 // currently disabled due to high risk of false positives. 105 #define WARN_IF_PTR_LEN(len)\ 106 /* 107 ENSURE(len != sizeof(char*)); 108 */ 109 110 111 // skip our implementation if already available, but not the 112 // self-test and the t* defines (needed for test). 113 #if EMULATE_SECURE_CRT 114 115 #if !OS_UNIX || OS_MACOSX || OS_OPENBSD 116 // return length [in characters] of a string, not including the trailing 117 // null character. to protect against access violations, only the 118 // first <max_len> characters are examined; if the null character is 119 // not encountered by then, <max_len> is returned. 120 size_t tnlen(const tchar* str, size_t max_len) 121 { 122 // note: we can't bail - what would the return value be? 123 ENSURE(str != 0); 124 125 WARN_IF_PTR_LEN(max_len); 126 127 size_t len; 128 for(len = 0; len < max_len; len++) 129 if(*str++ == '\0') 130 break; 131 132 return len; 133 } 134 #endif // !OS_UNIX 135 136 #if OS_ANDROID 137 static tstring androidFormat(const tchar *fmt) 138 { 139 // FIXME handle %%hs, %%ls, etc 140 tstring ret(fmt); 141 boost::algorithm::replace_all(ret, T("%ls"), T("%S")); 142 boost::algorithm::replace_all(ret, T("%hs"), T("%s")); 143 return ret; 144 } 145 #endif 146 147 // copy at most <max_src_chars> (not including trailing null) from 148 // <src> into <dst>, which must not overlap. 149 // if thereby <max_dst_chars> (including null) would be exceeded, 150 // <dst> is set to the empty string and ERANGE returned; otherwise, 151 // 0 is returned to indicate success and that <dst> is null-terminated. 152 // 153 // note: padding with zeroes is not called for by N1031. 154 int tncpy_s(tchar* dst, size_t max_dst_chars, const tchar* src, size_t max_src_chars) 155 { 156 // the MS implementation returns EINVAL and allows dst = 0 if 157 // max_dst_chars = max_src_chars = 0. no mention of this in 158 // 3.6.2.1.1, so don't emulate that behavior. 159 ENFORCE(dst != 0, ERR::INVALID_POINTER, EINVAL); 160 ENFORCE(max_dst_chars != 0, ERR::INVALID_SIZE, EINVAL); // N1031 says ERANGE, MSDN/MSVC says EINVAL 161 *dst = '\0'; // in case src ENFORCE is triggered 162 ENFORCE(src != 0, ERR::INVALID_POINTER, EINVAL); 163 164 WARN_IF_PTR_LEN(max_dst_chars); 165 WARN_IF_PTR_LEN(max_src_chars); 166 167 // copy string until null character encountered or limit reached. 168 // optimized for size (less comparisons than MS impl) and 169 // speed (due to well-predicted jumps; we don't bother unrolling). 170 tchar* p = dst; 171 size_t chars_left = std::min(max_dst_chars, max_src_chars); 172 while(chars_left != 0) 173 { 174 // success: reached end of string normally. 175 if((*p++ = *src++) == '\0') 176 return 0; 177 chars_left--; 178 } 179 180 // which limit did we hit? 181 // .. dst, and last character wasn't null: overflow. 182 if(max_dst_chars <= max_src_chars) 183 { 184 *dst = '\0'; 185 ENFORCE(0, ERR::INVALID_SIZE, ERANGE); 186 } 187 // .. source: success, but still need to null-terminate the destination. 188 *p = '\0'; 189 return 0; 190 } 191 192 193 // copy <src> (including trailing null) into <dst>, which must not overlap. 194 // if thereby <max_dst_chars> (including null) would be exceeded, 195 // <dst> is set to the empty string and ERANGE returned; otherwise, 196 // 0 is returned to indicate success and that <dst> is null-terminated. 197 int tcpy_s(tchar* dst, size_t max_dst_chars, const tchar* src) 198 { 199 return tncpy_s(dst, max_dst_chars, src, SIZE_MAX); 200 } 201 202 203 // append <src> to <dst>, which must not overlap. 204 // if thereby <max_dst_chars> (including null) would be exceeded, 205 // <dst> is set to the empty string and ERANGE returned; otherwise, 206 // 0 is returned to indicate success and that <dst> is null-terminated. 207 int tncat_s(tchar* dst, size_t max_dst_chars, const tchar* src, size_t max_src_chars) 208 { 209 ENFORCE(dst != 0, ERR::INVALID_POINTER, EINVAL); 210 ENFORCE(max_dst_chars != 0, ERR::INVALID_SIZE, EINVAL); // N1031 says ERANGE, MSDN/MSVC says EINVAL 211 // src is checked in tncpy_s 212 213 // WARN_IF_PTR_LEN not necessary: both max_dst_chars and max_src_chars 214 // are checked by tnlen / tncpy_s (respectively). 215 216 const size_t dst_len = tnlen(dst, max_dst_chars); 217 if(dst_len == max_dst_chars) 218 { 219 *dst = '\0'; 220 ENFORCE(0, ERR::STRING_NOT_TERMINATED, EINVAL); // N1031/MSDN says ERANGE, MSVC says EINVAL 221 } 222 223 tchar* const end = dst+dst_len; 224 const size_t chars_left = max_dst_chars-dst_len; 225 int ret = tncpy_s(end, chars_left, src, max_src_chars); 226 // if tncpy_s overflowed, we need to clear the start of our string 227 // (not just the appended part). can't do that by default, because 228 // the beginning of dst is not changed in normal operation. 229 if(ret != 0) 230 *dst = '\0'; 231 return ret; 232 } 233 234 235 // append <src> to <dst>, which must not overlap. 236 // if thereby <max_dst_chars> (including null) would be exceeded, 237 // <dst> is set to the empty string and ERANGE returned; otherwise, 238 // 0 is returned to indicate success and that <dst> is null-terminated. 239 // 240 // note: implemented as tncat_s(dst, max_dst_chars, src, SIZE_MAX) 241 int tcat_s(tchar* dst, size_t max_dst_chars, const tchar* src) 242 { 243 return tncat_s(dst, max_dst_chars, src, SIZE_MAX); 244 } 245 246 247 int tvsprintf_s(tchar* dst, size_t max_dst_chars, const tchar* fmt, va_list ap) 248 { 249 if(!dst || !fmt || max_dst_chars == 0) 250 { 251 errno = EINVAL; 252 return -1; 253 } 254 255 #if OS_ANDROID 256 // Workaround for https://code.google.com/p/android/issues/detail?id=109074 257 // (vswprintf doesn't null-terminate strings) 258 memset(dst, 0, max_dst_chars * sizeof(tchar)); 259 260 const int ret = tvsnprintf(dst, max_dst_chars, androidFormat(fmt).c_str(), ap); 261 #else 262 const int ret = tvsnprintf(dst, max_dst_chars, fmt, ap); 263 #endif 264 if(ret < 0 || ret >= int(max_dst_chars)) // not enough space 265 { 266 dst[0] = '\0'; 267 return -1; 268 } 269 return ret; // negative if error, else # chars written (excluding '\0') 270 } 271 272 273 int tsprintf_s(tchar* buf, size_t max_chars, const tchar* fmt, ...) 274 { 275 va_list ap; 276 va_start(ap, fmt); 277 int len = tvsprintf_s(buf, max_chars, fmt, ap); 278 va_end(ap); 279 return len; 280 } 281 282 #endif // #if EMULATE_SECURE_CRT 283 284 #undef tchar 285 #undef T 286 #undef tnlen 287 #undef tncpy_s 288 #undef tcpy_s 289 #undef tncat_s 290 #undef tcat_s 291 #undef tcmp 292 #undef tcpy 293 #undef tvsnprintf 294 #undef tvsprintf_s 295 #undef tsprintf_s 27 #include "secure_crt.inl" -
new file source/lib/secure_crt.inl
diff --git a/source/lib/secure_crt.inl b/source/lib/secure_crt.inl new file mode 100644 index 0000000..861c189
- + 1 /* Copyright (c) 2010 Wildfire Games 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining 4 * a copy of this software and associated documentation files (the 5 * "Software"), to deal in the Software without restriction, including 6 * without limitation the rights to use, copy, modify, merge, publish, 7 * distribute, sublicense, and/or sell copies of the Software, and to 8 * permit persons to whom the Software is furnished to do so, subject to 9 * the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23 /* 24 * partial implementation of VC8's secure CRT functions 25 */ 26 27 #include "precompiled.h" 28 29 #include <stdio.h> 30 #include <errno.h> 31 #include <stdarg.h> 32 33 #include "lib/secure_crt.h" 34 35 #if OS_ANDROID 36 # include <boost/algorithm/string/replace.hpp> 37 #endif 38 39 // we were included from wsecure_crt.cpp; skip all stuff that 40 // must only be done once. 41 #ifndef WSECURE_CRT 42 static const StatusDefinition secureCrtStatusDefinitions[] = { 43 { ERR::STRING_NOT_TERMINATED, L"Invalid string (no 0 terminator found in buffer)" } 44 }; 45 STATUS_ADD_DEFINITIONS(secureCrtStatusDefinitions); 46 #endif 47 48 49 // written against http://std.dkuug.dk/jtc1/sc22/wg14/www/docs/n1031.pdf . 50 // optimized for size - e.g. strcpy calls strncpy with n = SIZE_MAX. 51 52 // since char and wide versions of these functions are basically the same, 53 // this source file implements generic versions and bridges the differences 54 // with these macros. wsecure_crt.cpp #defines WSECURE_CRT and 55 // includes this file. 56 57 // Note: These defines are all #undef:ed at the end of the file - remember to 58 // add a corresponding #undef when adding a #define. 59 #ifdef WSECURE_CRT 60 # define tchar wchar_t 61 # define tstring std::wstring 62 # define T(string_literal) L ## string_literal 63 # define tnlen wcsnlen 64 # define tncpy_s wcsncpy_s 65 # define tcpy_s wcscpy_s 66 # define tncat_s wcsncat_s 67 # define tcat_s wcscat_s 68 # define tcmp wcscmp 69 # define tcpy wcscpy 70 # define tvsnprintf vswprintf // used by implementation 71 # define tvsprintf_s vswprintf_s 72 # define tsprintf_s swprintf_s 73 #else 74 # define tchar char 75 # define tstring std::string 76 # define T(string_literal) string_literal 77 # define tnlen strnlen 78 # define tncpy_s strncpy_s 79 # define tcpy_s strcpy_s 80 # define tncat_s strncat_s 81 # define tcat_s strcat_s 82 # define tcmp strcmp 83 # define tcpy strcpy 84 # define tvsnprintf vsnprintf // used by implementation 85 # define tvsprintf_s vsprintf_s 86 # define tsprintf_s sprintf_s 87 #endif // #ifdef WSECURE_CRT 88 89 90 // return <retval> and raise an assertion if <condition> doesn't hold. 91 // usable as a statement. 92 #define ENFORCE(condition, err_to_warn, retval) STMT(\ 93 if(!(condition)) \ 94 { \ 95 DEBUG_WARN_ERR(err_to_warn); \ 96 return retval; \ 97 } \ 98 ) 99 100 // raise a debug warning if <len> is the size of a pointer. 101 // catches bugs such as: tchar* s = ..; tcpy_s(s, sizeof(s), T("..")); 102 // if warnings get annoying, replace with debug_printf. usable as a statement. 103 // 104 // currently disabled due to high risk of false positives. 105 #define WARN_IF_PTR_LEN(len)\ 106 /* 107 ENSURE(len != sizeof(char*)); 108 */ 109 110 111 // skip our implementation if already available, but not the 112 // self-test and the t* defines (needed for test). 113 #if EMULATE_SECURE_CRT 114 115 #if !OS_UNIX || OS_MACOSX || OS_OPENBSD 116 // return length [in characters] of a string, not including the trailing 117 // null character. to protect against access violations, only the 118 // first <max_len> characters are examined; if the null character is 119 // not encountered by then, <max_len> is returned. 120 size_t tnlen(const tchar* str, size_t max_len) 121 { 122 // note: we can't bail - what would the return value be? 123 ENSURE(str != 0); 124 125 WARN_IF_PTR_LEN(max_len); 126 127 size_t len; 128 for(len = 0; len < max_len; len++) 129 if(*str++ == '\0') 130 break; 131 132 return len; 133 } 134 #endif // !OS_UNIX 135 136 #if OS_ANDROID 137 static tstring androidFormat(const tchar *fmt) 138 { 139 // FIXME handle %%hs, %%ls, etc 140 tstring ret(fmt); 141 boost::algorithm::replace_all(ret, T("%ls"), T("%S")); 142 boost::algorithm::replace_all(ret, T("%hs"), T("%s")); 143 return ret; 144 } 145 #endif 146 147 // copy at most <max_src_chars> (not including trailing null) from 148 // <src> into <dst>, which must not overlap. 149 // if thereby <max_dst_chars> (including null) would be exceeded, 150 // <dst> is set to the empty string and ERANGE returned; otherwise, 151 // 0 is returned to indicate success and that <dst> is null-terminated. 152 // 153 // note: padding with zeroes is not called for by N1031. 154 int tncpy_s(tchar* dst, size_t max_dst_chars, const tchar* src, size_t max_src_chars) 155 { 156 // the MS implementation returns EINVAL and allows dst = 0 if 157 // max_dst_chars = max_src_chars = 0. no mention of this in 158 // 3.6.2.1.1, so don't emulate that behavior. 159 ENFORCE(dst != 0, ERR::INVALID_POINTER, EINVAL); 160 ENFORCE(max_dst_chars != 0, ERR::INVALID_SIZE, EINVAL); // N1031 says ERANGE, MSDN/MSVC says EINVAL 161 *dst = '\0'; // in case src ENFORCE is triggered 162 ENFORCE(src != 0, ERR::INVALID_POINTER, EINVAL); 163 164 WARN_IF_PTR_LEN(max_dst_chars); 165 WARN_IF_PTR_LEN(max_src_chars); 166 167 // copy string until null character encountered or limit reached. 168 // optimized for size (less comparisons than MS impl) and 169 // speed (due to well-predicted jumps; we don't bother unrolling). 170 tchar* p = dst; 171 size_t chars_left = std::min(max_dst_chars, max_src_chars); 172 while(chars_left != 0) 173 { 174 // success: reached end of string normally. 175 if((*p++ = *src++) == '\0') 176 return 0; 177 chars_left--; 178 } 179 180 // which limit did we hit? 181 // .. dst, and last character wasn't null: overflow. 182 if(max_dst_chars <= max_src_chars) 183 { 184 *dst = '\0'; 185 ENFORCE(0, ERR::INVALID_SIZE, ERANGE); 186 } 187 // .. source: success, but still need to null-terminate the destination. 188 *p = '\0'; 189 return 0; 190 } 191 192 193 // copy <src> (including trailing null) into <dst>, which must not overlap. 194 // if thereby <max_dst_chars> (including null) would be exceeded, 195 // <dst> is set to the empty string and ERANGE returned; otherwise, 196 // 0 is returned to indicate success and that <dst> is null-terminated. 197 int tcpy_s(tchar* dst, size_t max_dst_chars, const tchar* src) 198 { 199 return tncpy_s(dst, max_dst_chars, src, SIZE_MAX); 200 } 201 202 203 // append <src> to <dst>, which must not overlap. 204 // if thereby <max_dst_chars> (including null) would be exceeded, 205 // <dst> is set to the empty string and ERANGE returned; otherwise, 206 // 0 is returned to indicate success and that <dst> is null-terminated. 207 int tncat_s(tchar* dst, size_t max_dst_chars, const tchar* src, size_t max_src_chars) 208 { 209 ENFORCE(dst != 0, ERR::INVALID_POINTER, EINVAL); 210 ENFORCE(max_dst_chars != 0, ERR::INVALID_SIZE, EINVAL); // N1031 says ERANGE, MSDN/MSVC says EINVAL 211 // src is checked in tncpy_s 212 213 // WARN_IF_PTR_LEN not necessary: both max_dst_chars and max_src_chars 214 // are checked by tnlen / tncpy_s (respectively). 215 216 const size_t dst_len = tnlen(dst, max_dst_chars); 217 if(dst_len == max_dst_chars) 218 { 219 *dst = '\0'; 220 ENFORCE(0, ERR::STRING_NOT_TERMINATED, EINVAL); // N1031/MSDN says ERANGE, MSVC says EINVAL 221 } 222 223 tchar* const end = dst+dst_len; 224 const size_t chars_left = max_dst_chars-dst_len; 225 int ret = tncpy_s(end, chars_left, src, max_src_chars); 226 // if tncpy_s overflowed, we need to clear the start of our string 227 // (not just the appended part). can't do that by default, because 228 // the beginning of dst is not changed in normal operation. 229 if(ret != 0) 230 *dst = '\0'; 231 return ret; 232 } 233 234 235 // append <src> to <dst>, which must not overlap. 236 // if thereby <max_dst_chars> (including null) would be exceeded, 237 // <dst> is set to the empty string and ERANGE returned; otherwise, 238 // 0 is returned to indicate success and that <dst> is null-terminated. 239 // 240 // note: implemented as tncat_s(dst, max_dst_chars, src, SIZE_MAX) 241 int tcat_s(tchar* dst, size_t max_dst_chars, const tchar* src) 242 { 243 return tncat_s(dst, max_dst_chars, src, SIZE_MAX); 244 } 245 246 247 int tvsprintf_s(tchar* dst, size_t max_dst_chars, const tchar* fmt, va_list ap) 248 { 249 if(!dst || !fmt || max_dst_chars == 0) 250 { 251 errno = EINVAL; 252 return -1; 253 } 254 255 #if OS_ANDROID 256 // Workaround for https://code.google.com/p/android/issues/detail?id=109074 257 // (vswprintf doesn't null-terminate strings) 258 memset(dst, 0, max_dst_chars * sizeof(tchar)); 259 260 const int ret = tvsnprintf(dst, max_dst_chars, androidFormat(fmt).c_str(), ap); 261 #else 262 const int ret = tvsnprintf(dst, max_dst_chars, fmt, ap); 263 #endif 264 if(ret < 0 || ret >= int(max_dst_chars)) // not enough space 265 { 266 dst[0] = '\0'; 267 return -1; 268 } 269 return ret; // negative if error, else # chars written (excluding '\0') 270 } 271 272 273 int tsprintf_s(tchar* buf, size_t max_chars, const tchar* fmt, ...) 274 { 275 va_list ap; 276 va_start(ap, fmt); 277 int len = tvsprintf_s(buf, max_chars, fmt, ap); 278 va_end(ap); 279 return len; 280 } 281 282 #endif // #if EMULATE_SECURE_CRT 283 284 #undef tchar 285 #undef T 286 #undef tnlen 287 #undef tncpy_s 288 #undef tcpy_s 289 #undef tncat_s 290 #undef tcat_s 291 #undef tcmp 292 #undef tcpy 293 #undef tvsnprintf 294 #undef tvsprintf_s 295 #undef tsprintf_s -
source/lib/wsecure_crt.cpp
diff --git a/source/lib/wsecure_crt.cpp b/source/lib/wsecure_crt.cpp index 1fa5555..5b40633 100644
a b 25 25 #include "precompiled.h" 26 26 27 27 #define WSECURE_CRT 28 #include "secure_crt. cpp"28 #include "secure_crt.inl" 29 29 #undef WSECURE_CRT