X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fbuffer%2Fbuffer.c;h=a6b590c3b2b2e3add87de35d1ad413b50e40537b;hp=fcc153013b7ca83bf50d4f382686a9be8e4034cc;hb=0bcb17a7776b7f740e855932890edfb7acfd7124;hpb=6b691a5c85ddc4e407e32781841fee5c029506cd diff --git a/crypto/buffer/buffer.c b/crypto/buffer/buffer.c index fcc153013b..a6b590c3b2 100644 --- a/crypto/buffer/buffer.c +++ b/crypto/buffer/buffer.c @@ -58,13 +58,18 @@ #include #include "cryptlib.h" -#include "buffer.h" +#include + +/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That + * function is applied in several functions in this file and this limit ensures + * that the result fits in an int. */ +#define LIMIT_BEFORE_EXPANSION 0x5ffffffc BUF_MEM *BUF_MEM_new(void) { BUF_MEM *ret; - ret=(BUF_MEM *)Malloc(sizeof(BUF_MEM)); + ret=OPENSSL_malloc(sizeof(BUF_MEM)); if (ret == NULL) { BUFerr(BUF_F_BUF_MEM_NEW,ERR_R_MALLOC_FAILURE); @@ -84,15 +89,15 @@ void BUF_MEM_free(BUF_MEM *a) if (a->data != NULL) { memset(a->data,0,(unsigned int)a->max); - Free(a->data); + OPENSSL_free(a->data); } - Free(a); + OPENSSL_free(a); } -int BUF_MEM_grow(BUF_MEM *str, int len) +int BUF_MEM_grow(BUF_MEM *str, size_t len) { char *ret; - unsigned int n; + size_t n; if (str->length >= len) { @@ -101,15 +106,21 @@ int BUF_MEM_grow(BUF_MEM *str, int len) } if (str->max >= len) { - memset(&(str->data[str->length]),0,len-str->length); + memset(&str->data[str->length],0,len-str->length); str->length=len; return(len); } + /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ + if (len > LIMIT_BEFORE_EXPANSION) + { + BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); + return 0; + } n=(len+3)/3*4; if (str->data == NULL) - ret=(char *)Malloc(n); + ret=OPENSSL_malloc(n); else - ret=(char *)Realloc(str->data,n); + ret=OPENSSL_realloc(str->data,n); if (ret == NULL) { BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); @@ -118,27 +129,75 @@ int BUF_MEM_grow(BUF_MEM *str, int len) else { str->data=ret; - str->length=len; str->max=n; + memset(&str->data[str->length],0,len-str->length); + str->length=len; } return(len); } -char *BUF_strdup(const char *str) +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len) { char *ret; - int n; - - if (str == NULL) return(NULL); + size_t n; - n=strlen(str); - ret=Malloc(n+1); - if (ret == NULL) + if (str->length >= len) { - BUFerr(BUF_F_BUF_STRDUP,ERR_R_MALLOC_FAILURE); - return(NULL); + memset(&str->data[len],0,str->length-len); + str->length=len; + return(len); } - memcpy(ret,str,n+1); - return(ret); + if (str->max >= len) + { + memset(&str->data[str->length],0,len-str->length); + str->length=len; + return(len); + } + /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ + if (len > LIMIT_BEFORE_EXPANSION) + { + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); + return 0; + } + n=(len+3)/3*4; + if (str->data == NULL) + ret=OPENSSL_malloc(n); + else + ret=OPENSSL_realloc_clean(str->data,str->max,n); + if (ret == NULL) + { + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); + len=0; + } + else + { + str->data=ret; + str->max=n; + memset(&str->data[str->length],0,len-str->length); + str->length=len; + } + return(len); } +void BUF_reverse(unsigned char *out, unsigned char *in, size_t size) + { + size_t i; + if (in) + { + out += size - 1; + for (i = 0; i < size; i++) + *out-- = *in++; + } + else + { + unsigned char *q; + char c; + q = out + size - 1; + for (i = 0; i < size/2; i++) + { + c = *q; + *q-- = *out; + *out++ = c; + } + } + }