diff options
| author | Daniel Stenberg <daniel@haxx.se> | 2016-11-07 10:55:25 +0100 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2016-11-11 10:03:48 +0100 | 
| commit | 0649433da53c7165f839e24e889e131e2894dd32 (patch) | |
| tree | 7e516c1702fe87c09f190e5dc47ecd3a9bede1b8 | |
| parent | cdfda3ee827da069f1871722278fd82e7cbb4194 (diff) | |
realloc: use Curl_saferealloc to avoid common mistakes
Discussed: https://curl.haxx.se/mail/lib-2016-11/0087.html
| -rw-r--r-- | lib/content_encoding.c | 9 | ||||
| -rw-r--r-- | lib/curl_ntlm_wb.c | 8 | ||||
| -rw-r--r-- | lib/escape.c | 7 | ||||
| -rw-r--r-- | lib/http.c | 4 | ||||
| -rw-r--r-- | lib/http2.c | 7 | ||||
| -rw-r--r-- | lib/rtsp.c | 5 | ||||
| -rw-r--r-- | lib/security.c | 4 | ||||
| -rw-r--r-- | lib/ssh.c | 7 | ||||
| -rw-r--r-- | lib/strdup.c | 23 | ||||
| -rw-r--r-- | lib/strdup.h | 1 | 
10 files changed, 48 insertions, 27 deletions
diff --git a/lib/content_encoding.c b/lib/content_encoding.c index fa36aca4c..5a5824db4 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -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   * you should have received as part of this distribution. The terms @@ -28,8 +28,8 @@  #include <curl/curl.h>  #include "sendf.h"  #include "content_encoding.h" +#include "strdup.h"  #include "curl_memory.h" -  #include "memdebug.h"  /* 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 */      ssize_t hlen; -    unsigned char *oldblock = z->next_in; -      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) { -      free(oldblock);        return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);      }      /* Append the new block of data to the previous one */ diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c index afdea16c0..1d1b3a3f2 100644 --- a/lib/curl_ntlm_wb.c +++ b/lib/curl_ntlm_wb.c @@ -51,6 +51,7 @@  #include "curl_ntlm_wb.h"  #include "url.h"  #include "strerror.h" +#include "strdup.h"  /* The last 3 #include files should be in this order */  #include "curl_printf.h"  #include "curl_memory.h" @@ -293,11 +294,10 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,        buf[len_out - 1] = '\0';        break;      } -    newbuf = realloc(buf, len_out + NTLM_BUFSIZE); -    if(!newbuf) { -      free(buf); +    newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE); +    if(!newbuf)        return CURLE_OUT_OF_MEMORY; -    } +      buf = newbuf;    } diff --git a/lib/escape.c b/lib/escape.c index 66570076e..9fb8d3e15 100644 --- a/lib/escape.c +++ b/lib/escape.c @@ -31,6 +31,7 @@  #include "warnless.h"  #include "non-ascii.h"  #include "escape.h" +#include "strdup.h"  /* The last 3 #include files should be in this order */  #include "curl_printf.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 */        if(newlen > alloc) {          alloc *= 2; -        testing_ptr = realloc(ns, alloc); -        if(!testing_ptr) { -          free(ns); +        testing_ptr = Curl_saferealloc(ns, alloc); +        if(!testing_ptr)            return NULL; -        }          else {            ns = testing_ptr;          } diff --git a/lib/http.c b/lib/http.c index e7788e767..999d6da87 100644 --- a/lib/http.c +++ b/lib/http.c @@ -76,6 +76,7 @@  #include "pipeline.h"  #include "http2.h"  #include "connect.h" +#include "strdup.h"  /* The last 3 #include files should be in this order */  #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)        /* we have a buffer, enlarge the existing one */ -      new_rb = realloc(in->buffer, new_size); +      new_rb = Curl_saferealloc(in->buffer, new_size);      else        /* create a new buffer */        new_rb = malloc(new_size);      if(!new_rb) {        /* If we failed, we cleanup the whole buffer and return error */ -      Curl_safefree(in->buffer);        free(in);        return CURLE_OUT_OF_MEMORY;      } diff --git a/lib/http2.c b/lib/http2.c index b0301da56..1484e1515 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -35,7 +35,7 @@  #include "url.h"  #include "connect.h"  #include "strtoofft.h" - +#include "strdup.h"  /* The last 3 #include files should be in this order */  #include "curl_printf.h"  #include "curl_memory.h" @@ -841,10 +841,9 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,              stream->push_headers_alloc) {        char **headp;        stream->push_headers_alloc *= 2; -      headp = realloc(stream->push_headers, -                      stream->push_headers_alloc * sizeof(char *)); +      headp = Curl_saferealloc(stream->push_headers, +                               stream->push_headers_alloc * sizeof(char *));        if(!headp) { -        free(stream->push_headers);          stream->push_headers = NULL;          return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;        } diff --git a/lib/rtsp.c b/lib/rtsp.c index d1bad19da..5da33d42c 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -36,6 +36,7 @@  #include "strcase.h"  #include "select.h"  #include "connect.h" +#include "strdup.h"  /* The last 3 #include files should be in this order */  #include "curl_printf.h"  #include "curl_memory.h" @@ -614,9 +615,9 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,    if(rtspc->rtp_buf) {      /* 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) { -      Curl_safefree(rtspc->rtp_buf);        rtspc->rtp_buf = NULL;        rtspc->rtp_bufsize = 0;        return CURLE_OUT_OF_MEMORY; diff --git a/lib/security.c b/lib/security.c index ff2606669..87c22da07 100644 --- a/lib/security.c +++ b/lib/security.c @@ -62,7 +62,7 @@  #include "sendf.h"  #include "strcase.h"  #include "warnless.h" - +#include "strdup.h"  /* The last #include file should be: */  #include "memdebug.h" @@ -202,7 +202,7 @@ static CURLcode read_data(struct connectdata *conn,    if(len) {      /* only realloc if there was a length */      len = ntohl(len); -    tmp = realloc(buf->data, len); +    tmp = Curl_saferealloc(buf->data, len);    }    if(tmp == NULL)      return CURLE_OUT_OF_MEMORY; @@ -71,7 +71,7 @@  #include "url.h"  #include "speedcheck.h"  #include "getinfo.h" - +#include "strdup.h"  #include "strcase.h"  #include "vtls/vtls.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 */        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) { -        Curl_safefree(sshc->readdir_line); +        sshc->readdir_line = NULL;          Curl_safefree(sshc->readdir_filename);          Curl_safefree(sshc->readdir_longentry);          state(conn, SSH_SFTP_CLOSE); diff --git a/lib/strdup.c b/lib/strdup.c index 5a15c2b16..136b69377 100644 --- a/lib/strdup.c +++ b/lib/strdup.c @@ -75,3 +75,26 @@ void *Curl_memdup(const void *src, size_t length)    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; +} diff --git a/lib/strdup.h b/lib/strdup.h index c74a3b730..ae3d5d011 100644 --- a/lib/strdup.h +++ b/lib/strdup.h @@ -27,5 +27,6 @@  extern char *curlx_strdup(const char *str);  #endif  void *Curl_memdup(const void *src, size_t buffer_length); +void *Curl_saferealloc(void *ptr, size_t size);  #endif /* HEADER_CURL_STRDUP_H */  | 
