strdup.c (4034B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 25 #include "curl_setup.h" 26 27 #include <curl/curl.h> 28 29 #ifdef _WIN32 30 #include <wchar.h> 31 #endif 32 33 #include "strdup.h" 34 #include "curl_memory.h" 35 36 /* The last #include file should be: */ 37 #include "memdebug.h" 38 39 #ifndef HAVE_STRDUP 40 char *Curl_strdup(const char *str) 41 { 42 size_t len; 43 char *newstr; 44 45 if(!str) 46 return (char *)NULL; 47 48 len = strlen(str) + 1; 49 50 newstr = malloc(len); 51 if(!newstr) 52 return (char *)NULL; 53 54 memcpy(newstr, str, len); 55 return newstr; 56 } 57 #endif 58 59 #ifdef _WIN32 60 /*************************************************************************** 61 * 62 * Curl_wcsdup(source) 63 * 64 * Copies the 'source' wchar string to a newly allocated buffer (that is 65 * returned). 66 * 67 * Returns the new pointer or NULL on failure. 68 * 69 ***************************************************************************/ 70 wchar_t *Curl_wcsdup(const wchar_t *src) 71 { 72 size_t length = wcslen(src); 73 74 if(length > (SIZE_T_MAX / sizeof(wchar_t)) - 1) 75 return (wchar_t *)NULL; /* integer overflow */ 76 77 return (wchar_t *)Curl_memdup(src, (length + 1) * sizeof(wchar_t)); 78 } 79 #endif 80 81 /*************************************************************************** 82 * 83 * Curl_memdup(source, length) 84 * 85 * Copies the 'source' data to a newly allocated buffer (that is 86 * returned). Copies 'length' bytes. 87 * 88 * Returns the new pointer or NULL on failure. 89 * 90 ***************************************************************************/ 91 void *Curl_memdup(const void *src, size_t length) 92 { 93 void *buffer = malloc(length); 94 if(!buffer) 95 return NULL; /* fail */ 96 97 memcpy(buffer, src, length); 98 99 return buffer; 100 } 101 102 /*************************************************************************** 103 * 104 * Curl_memdup0(source, length) 105 * 106 * Copies the 'source' string to a newly allocated buffer (that is returned). 107 * Copies 'length' bytes then adds a null-terminator. 108 * 109 * Returns the new pointer or NULL on failure. 110 * 111 ***************************************************************************/ 112 void *Curl_memdup0(const char *src, size_t length) 113 { 114 char *buf = malloc(length + 1); 115 if(!buf) 116 return NULL; 117 if(length) { 118 DEBUGASSERT(src); /* must never be NULL */ 119 memcpy(buf, src, length); 120 } 121 buf[length] = 0; 122 return buf; 123 } 124 125 /*************************************************************************** 126 * 127 * Curl_saferealloc(ptr, size) 128 * 129 * Does a normal realloc(), but will free the data pointer if the realloc 130 * fails. If 'size' is non-zero, it will free the data and return a failure. 131 * 132 * This convenience function is provided and used to help us avoid a common 133 * mistake pattern when we could pass in a zero, catch the NULL return and end 134 * up free'ing the memory twice. 135 * 136 * Returns the new pointer or NULL on failure. 137 * 138 ***************************************************************************/ 139 void *Curl_saferealloc(void *ptr, size_t size) 140 { 141 void *datap = realloc(ptr, size); 142 if(size && !datap) 143 /* only free 'ptr' if size was non-zero */ 144 free(ptr); 145 return datap; 146 }