1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 07:38:49 -05:00

realloc: use Curl_saferealloc to avoid common mistakes

Discussed: https://curl.haxx.se/mail/lib-2016-11/0087.html
This commit is contained in:
Daniel Stenberg 2016-11-07 10:55:25 +01:00
parent cdfda3ee82
commit 0649433da5
10 changed files with 48 additions and 27 deletions

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -28,8 +28,8 @@
#include <curl/curl.h> #include <curl/curl.h>
#include "sendf.h" #include "sendf.h"
#include "content_encoding.h" #include "content_encoding.h"
#include "strdup.h"
#include "curl_memory.h" #include "curl_memory.h"
#include "memdebug.h" #include "memdebug.h"
/* Comment this out if zlib is always going to be at least ver. 1.2.0.4 /* Comment this out if zlib is always going to be at least ver. 1.2.0.4
@ -371,12 +371,9 @@ Curl_unencode_gzip_write(struct connectdata *conn,
{ {
/* Need more gzip header data state */ /* Need more gzip header data state */
ssize_t hlen; ssize_t hlen;
unsigned char *oldblock = z->next_in;
z->avail_in += (uInt)nread; z->avail_in += (uInt)nread;
z->next_in = realloc(z->next_in, z->avail_in); z->next_in = Curl_saferealloc(z->next_in, z->avail_in);
if(z->next_in == NULL) { if(z->next_in == NULL) {
free(oldblock);
return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
} }
/* Append the new block of data to the previous one */ /* Append the new block of data to the previous one */

View File

@ -51,6 +51,7 @@
#include "curl_ntlm_wb.h" #include "curl_ntlm_wb.h"
#include "url.h" #include "url.h"
#include "strerror.h" #include "strerror.h"
#include "strdup.h"
/* The last 3 #include files should be in this order */ /* The last 3 #include files should be in this order */
#include "curl_printf.h" #include "curl_printf.h"
#include "curl_memory.h" #include "curl_memory.h"
@ -293,11 +294,10 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
buf[len_out - 1] = '\0'; buf[len_out - 1] = '\0';
break; break;
} }
newbuf = realloc(buf, len_out + NTLM_BUFSIZE); newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE);
if(!newbuf) { if(!newbuf)
free(buf);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
}
buf = newbuf; buf = newbuf;
} }

View File

@ -31,6 +31,7 @@
#include "warnless.h" #include "warnless.h"
#include "non-ascii.h" #include "non-ascii.h"
#include "escape.h" #include "escape.h"
#include "strdup.h"
/* The last 3 #include files should be in this order */ /* The last 3 #include files should be in this order */
#include "curl_printf.h" #include "curl_printf.h"
#include "curl_memory.h" #include "curl_memory.h"
@ -109,11 +110,9 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
newlen += 2; /* the size grows with two, since this'll become a %XX */ newlen += 2; /* the size grows with two, since this'll become a %XX */
if(newlen > alloc) { if(newlen > alloc) {
alloc *= 2; alloc *= 2;
testing_ptr = realloc(ns, alloc); testing_ptr = Curl_saferealloc(ns, alloc);
if(!testing_ptr) { if(!testing_ptr)
free(ns);
return NULL; return NULL;
}
else { else {
ns = testing_ptr; ns = testing_ptr;
} }

View File

@ -76,6 +76,7 @@
#include "pipeline.h" #include "pipeline.h"
#include "http2.h" #include "http2.h"
#include "connect.h" #include "connect.h"
#include "strdup.h"
/* The last 3 #include files should be in this order */ /* The last 3 #include files should be in this order */
#include "curl_printf.h" #include "curl_printf.h"
@ -1255,14 +1256,13 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
if(in->buffer) if(in->buffer)
/* we have a buffer, enlarge the existing one */ /* we have a buffer, enlarge the existing one */
new_rb = realloc(in->buffer, new_size); new_rb = Curl_saferealloc(in->buffer, new_size);
else else
/* create a new buffer */ /* create a new buffer */
new_rb = malloc(new_size); new_rb = malloc(new_size);
if(!new_rb) { if(!new_rb) {
/* If we failed, we cleanup the whole buffer and return error */ /* If we failed, we cleanup the whole buffer and return error */
Curl_safefree(in->buffer);
free(in); free(in);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }

View File

@ -35,7 +35,7 @@
#include "url.h" #include "url.h"
#include "connect.h" #include "connect.h"
#include "strtoofft.h" #include "strtoofft.h"
#include "strdup.h"
/* The last 3 #include files should be in this order */ /* The last 3 #include files should be in this order */
#include "curl_printf.h" #include "curl_printf.h"
#include "curl_memory.h" #include "curl_memory.h"
@ -841,10 +841,9 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
stream->push_headers_alloc) { stream->push_headers_alloc) {
char **headp; char **headp;
stream->push_headers_alloc *= 2; stream->push_headers_alloc *= 2;
headp = realloc(stream->push_headers, headp = Curl_saferealloc(stream->push_headers,
stream->push_headers_alloc * sizeof(char *)); stream->push_headers_alloc * sizeof(char *));
if(!headp) { if(!headp) {
free(stream->push_headers);
stream->push_headers = NULL; stream->push_headers = NULL;
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
} }

View File

@ -36,6 +36,7 @@
#include "strcase.h" #include "strcase.h"
#include "select.h" #include "select.h"
#include "connect.h" #include "connect.h"
#include "strdup.h"
/* The last 3 #include files should be in this order */ /* The last 3 #include files should be in this order */
#include "curl_printf.h" #include "curl_printf.h"
#include "curl_memory.h" #include "curl_memory.h"
@ -614,9 +615,9 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
if(rtspc->rtp_buf) { if(rtspc->rtp_buf) {
/* There was some leftover data the last time. Merge buffers */ /* There was some leftover data the last time. Merge buffers */
char *newptr = realloc(rtspc->rtp_buf, rtspc->rtp_bufsize + *nread); char *newptr = Curl_saferealloc(rtspc->rtp_buf,
rtspc->rtp_bufsize + *nread);
if(!newptr) { if(!newptr) {
Curl_safefree(rtspc->rtp_buf);
rtspc->rtp_buf = NULL; rtspc->rtp_buf = NULL;
rtspc->rtp_bufsize = 0; rtspc->rtp_bufsize = 0;
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;

View File

@ -62,7 +62,7 @@
#include "sendf.h" #include "sendf.h"
#include "strcase.h" #include "strcase.h"
#include "warnless.h" #include "warnless.h"
#include "strdup.h"
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
@ -202,7 +202,7 @@ static CURLcode read_data(struct connectdata *conn,
if(len) { if(len) {
/* only realloc if there was a length */ /* only realloc if there was a length */
len = ntohl(len); len = ntohl(len);
tmp = realloc(buf->data, len); tmp = Curl_saferealloc(buf->data, len);
} }
if(tmp == NULL) if(tmp == NULL)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;

View File

@ -71,7 +71,7 @@
#include "url.h" #include "url.h"
#include "speedcheck.h" #include "speedcheck.h"
#include "getinfo.h" #include "getinfo.h"
#include "strdup.h"
#include "strcase.h" #include "strcase.h"
#include "vtls/vtls.h" #include "vtls/vtls.h"
#include "connect.h" #include "connect.h"
@ -2112,9 +2112,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* get room for the filename and extra output */ /* get room for the filename and extra output */
sshc->readdir_totalLen += 4 + sshc->readdir_len; sshc->readdir_totalLen += 4 + sshc->readdir_len;
new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen); new_readdir_line = Curl_saferealloc(sshc->readdir_line,
sshc->readdir_totalLen);
if(!new_readdir_line) { if(!new_readdir_line) {
Curl_safefree(sshc->readdir_line); sshc->readdir_line = NULL;
Curl_safefree(sshc->readdir_filename); Curl_safefree(sshc->readdir_filename);
Curl_safefree(sshc->readdir_longentry); Curl_safefree(sshc->readdir_longentry);
state(conn, SSH_SFTP_CLOSE); state(conn, SSH_SFTP_CLOSE);

View File

@ -75,3 +75,26 @@ void *Curl_memdup(const void *src, size_t length)
return buffer; return buffer;
} }
/***************************************************************************
*
* Curl_saferealloc(ptr, size)
*
* Does a normal realloc(), but will free the data pointer if the realloc
* fails. If 'size' is zero, it will free the data and return a failure.
*
* This convenience function is provided and used to help us avoid a common
* mistake pattern when we could pass in a zero, catch the NULL return and end
* up free'ing the memory twice.
*
* Returns the new pointer or NULL on failure.
*
***************************************************************************/
void *Curl_saferealloc(void *ptr, size_t size)
{
void *datap = realloc(ptr, size);
if(size && !datap)
/* only free 'ptr' if size was non-zero */
free(ptr);
return datap;
}

View File

@ -27,5 +27,6 @@
extern char *curlx_strdup(const char *str); extern char *curlx_strdup(const char *str);
#endif #endif
void *Curl_memdup(const void *src, size_t buffer_length); void *Curl_memdup(const void *src, size_t buffer_length);
void *Curl_saferealloc(void *ptr, size_t size);
#endif /* HEADER_CURL_STRDUP_H */ #endif /* HEADER_CURL_STRDUP_H */