Check for nullptr return from malloc, calloc, and realloc. (#1023)

These are used in ntcore and cscore.  Add inline null-checking versions
to wpi/memory.h and use them throughout.
This commit is contained in:
Peter Johnson
2018-05-04 17:55:46 -07:00
committed by GitHub
parent e8d5759d95
commit 7a34f5d17d
9 changed files with 148 additions and 68 deletions

View File

@@ -7,6 +7,7 @@
#include <stdint.h>
#include <wpi/memory.h>
#include <wpi/timestamp.h>
#include "Value_internal.h"
@@ -113,7 +114,7 @@ void nt::ConvertToC(const Value& in, NT_Value* out) {
case NT_BOOLEAN_ARRAY: {
auto v = in.GetBooleanArray();
out->data.arr_boolean.arr =
static_cast<int*>(std::malloc(v.size() * sizeof(int)));
static_cast<int*>(wpi::CheckedMalloc(v.size() * sizeof(int)));
out->data.arr_boolean.size = v.size();
std::copy(v.begin(), v.end(), out->data.arr_boolean.arr);
break;
@@ -121,15 +122,15 @@ void nt::ConvertToC(const Value& in, NT_Value* out) {
case NT_DOUBLE_ARRAY: {
auto v = in.GetDoubleArray();
out->data.arr_double.arr =
static_cast<double*>(std::malloc(v.size() * sizeof(double)));
static_cast<double*>(wpi::CheckedMalloc(v.size() * sizeof(double)));
out->data.arr_double.size = v.size();
std::copy(v.begin(), v.end(), out->data.arr_double.arr);
break;
}
case NT_STRING_ARRAY: {
auto v = in.GetStringArray();
out->data.arr_string.arr =
static_cast<NT_String*>(std::malloc(v.size() * sizeof(NT_String)));
out->data.arr_string.arr = static_cast<NT_String*>(
wpi::CheckedMalloc(v.size() * sizeof(NT_String)));
for (size_t i = 0; i < v.size(); ++i)
ConvertToC(v[i], &out->data.arr_string.arr[i]);
out->data.arr_string.size = v.size();
@@ -144,7 +145,7 @@ void nt::ConvertToC(const Value& in, NT_Value* out) {
void nt::ConvertToC(wpi::StringRef in, NT_String* out) {
out->len = in.size();
out->str = static_cast<char*>(std::malloc(in.size() + 1));
out->str = static_cast<char*>(wpi::CheckedMalloc(in.size() + 1));
std::memcpy(out->str, in.data(), in.size());
out->str[in.size()] = '\0';
}

View File

@@ -15,6 +15,7 @@
#include <wpi/MathExtras.h>
#include <wpi/leb128.h>
#include <wpi/memory.h>
using namespace nt;
@@ -52,7 +53,7 @@ WireDecoder::WireDecoder(wpi::raw_istream& is, unsigned int proto_rev,
// Start with a 1K temporary buffer. Use malloc instead of new so we can
// realloc.
m_allocated = 1024;
m_buf = static_cast<char*>(std::malloc(m_allocated));
m_buf = static_cast<char*>(wpi::CheckedMalloc(m_allocated));
m_proto_rev = proto_rev;
m_error = nullptr;
}
@@ -71,7 +72,7 @@ void WireDecoder::Realloc(size_t len) {
if (m_allocated >= len) return;
size_t newlen = m_allocated * 2;
while (newlen < len) newlen *= 2;
m_buf = static_cast<char*>(std::realloc(m_buf, newlen));
m_buf = static_cast<char*>(wpi::CheckedRealloc(m_buf, newlen));
m_allocated = newlen;
}

View File

@@ -10,6 +10,7 @@
#include <cassert>
#include <cstdlib>
#include <wpi/memory.h>
#include <wpi/timestamp.h>
#include "Value_internal.h"
@@ -20,7 +21,7 @@ using namespace nt;
// Conversion helpers
static void ConvertToC(wpi::StringRef in, char** out) {
*out = static_cast<char*>(std::malloc(in.size() + 1));
*out = static_cast<char*>(wpi::CheckedMalloc(in.size() + 1));
std::memmove(*out, in.data(), in.size());
(*out)[in.size()] = '\0';
}
@@ -57,13 +58,13 @@ static void ConvertToC(const RpcDefinition& in, NT_RpcDefinition* out) {
out->num_params = in.params.size();
out->params = static_cast<NT_RpcParamDef*>(
std::malloc(in.params.size() * sizeof(NT_RpcParamDef)));
wpi::CheckedMalloc(in.params.size() * sizeof(NT_RpcParamDef)));
for (size_t i = 0; i < in.params.size(); ++i)
ConvertToC(in.params[i], &out->params[i]);
out->num_results = in.results.size();
out->results = static_cast<NT_RpcResultDef*>(
std::malloc(in.results.size() * sizeof(NT_RpcResultDef)));
wpi::CheckedMalloc(in.results.size() * sizeof(NT_RpcResultDef)));
for (size_t i = 0; i < in.results.size(); ++i)
ConvertToC(in.results[i], &out->results[i]);
}
@@ -107,9 +108,9 @@ static void ConvertToC(const std::vector<I>& in, O** out, size_t* out_len) {
*out = nullptr;
return;
}
*out = static_cast<O*>(std::malloc(sizeof(O*) * in.size()));
*out = static_cast<O*>(wpi::CheckedMalloc(sizeof(O*) * in.size()));
for (size_t i = 0; i < in.size(); ++i) {
out[i] = static_cast<O*>(std::malloc(sizeof(O)));
out[i] = static_cast<O*>(wpi::CheckedMalloc(sizeof(O)));
ConvertToC(in[i], out[i]);
}
}
@@ -191,8 +192,8 @@ NT_Entry* NT_GetEntries(NT_Inst inst, const char* prefix, size_t prefix_len,
if (info_v.size() == 0) return nullptr;
// create array and copy into it
NT_Entry* info =
static_cast<NT_Entry*>(std::malloc(info_v.size() * sizeof(NT_Entry)));
NT_Entry* info = static_cast<NT_Entry*>(
wpi::CheckedMalloc(info_v.size() * sizeof(NT_Entry)));
std::memcpy(info, info_v.data(), info_v.size() * sizeof(NT_Entry));
return info;
}
@@ -251,7 +252,7 @@ struct NT_EntryInfo* NT_GetEntryInfo(NT_Inst inst, const char* prefix,
// create array and copy into it
NT_EntryInfo* info = static_cast<NT_EntryInfo*>(
std::malloc(info_v.size() * sizeof(NT_EntryInfo)));
wpi::CheckedMalloc(info_v.size() * sizeof(NT_EntryInfo)));
for (size_t i = 0; i < info_v.size(); ++i) ConvertToC(info_v[i], &info[i]);
return info;
}
@@ -541,10 +542,10 @@ NT_Value** NT_UnpackRpcValues(const char* packed, size_t packed_len,
if (values_v.size() == 0) return nullptr;
// create array and copy into it
NT_Value** values =
static_cast<NT_Value**>(std::malloc(values_v.size() * sizeof(NT_Value*)));
NT_Value** values = static_cast<NT_Value**>(
wpi::CheckedMalloc(values_v.size() * sizeof(NT_Value*)));
for (size_t i = 0; i < values_v.size(); ++i) {
values[i] = static_cast<NT_Value*>(std::malloc(sizeof(NT_Value)));
values[i] = static_cast<NT_Value*>(wpi::CheckedMalloc(sizeof(NT_Value)));
ConvertToC(*values_v[i], values[i]);
}
return values;
@@ -628,7 +629,7 @@ struct NT_ConnectionInfo* NT_GetConnections(NT_Inst inst, size_t* count) {
// create array and copy into it
NT_ConnectionInfo* conn = static_cast<NT_ConnectionInfo*>(
std::malloc(conn_v.size() * sizeof(NT_ConnectionInfo)));
wpi::CheckedMalloc(conn_v.size() * sizeof(NT_ConnectionInfo)));
for (size_t i = 0; i < conn_v.size(); ++i) ConvertToC(conn_v[i], &conn[i]);
return conn;
}
@@ -836,26 +837,27 @@ void NT_DisposeRpcAnswer(NT_RpcAnswer* call_info) {
/* Allocates a char array of the specified size.*/
char* NT_AllocateCharArray(size_t size) {
char* retVal = static_cast<char*>(std::malloc(size * sizeof(char)));
char* retVal = static_cast<char*>(wpi::CheckedMalloc(size * sizeof(char)));
return retVal;
}
/* Allocates an integer or boolean array of the specified size. */
int* NT_AllocateBooleanArray(size_t size) {
int* retVal = static_cast<int*>(std::malloc(size * sizeof(int)));
int* retVal = static_cast<int*>(wpi::CheckedMalloc(size * sizeof(int)));
return retVal;
}
/* Allocates a double array of the specified size. */
double* NT_AllocateDoubleArray(size_t size) {
double* retVal = static_cast<double*>(std::malloc(size * sizeof(double)));
double* retVal =
static_cast<double*>(wpi::CheckedMalloc(size * sizeof(double)));
return retVal;
}
/* Allocates an NT_String array of the specified size. */
struct NT_String* NT_AllocateStringArray(size_t size) {
NT_String* retVal =
static_cast<NT_String*>(std::malloc(size * sizeof(NT_String)));
static_cast<NT_String*>(wpi::CheckedMalloc(size * sizeof(NT_String)));
return retVal;
}
@@ -976,7 +978,8 @@ char* NT_GetValueString(const struct NT_Value* value, uint64_t* last_change,
if (!value || value->type != NT_Type::NT_STRING) return nullptr;
*last_change = value->last_change;
*str_len = value->data.v_string.len;
char* str = static_cast<char*>(std::malloc(value->data.v_string.len + 1));
char* str =
static_cast<char*>(wpi::CheckedMalloc(value->data.v_string.len + 1));
std::memcpy(str, value->data.v_string.str, value->data.v_string.len + 1);
return str;
}
@@ -986,7 +989,8 @@ char* NT_GetValueRaw(const struct NT_Value* value, uint64_t* last_change,
if (!value || value->type != NT_Type::NT_RAW) return nullptr;
*last_change = value->last_change;
*raw_len = value->data.v_string.len;
char* raw = static_cast<char*>(std::malloc(value->data.v_string.len + 1));
char* raw =
static_cast<char*>(wpi::CheckedMalloc(value->data.v_string.len + 1));
std::memcpy(raw, value->data.v_string.str, value->data.v_string.len + 1);
return raw;
}
@@ -997,7 +1001,7 @@ NT_Bool* NT_GetValueBooleanArray(const struct NT_Value* value,
*last_change = value->last_change;
*arr_size = value->data.arr_boolean.size;
NT_Bool* arr = static_cast<int*>(
std::malloc(value->data.arr_boolean.size * sizeof(NT_Bool)));
wpi::CheckedMalloc(value->data.arr_boolean.size * sizeof(NT_Bool)));
std::memcpy(arr, value->data.arr_boolean.arr,
value->data.arr_boolean.size * sizeof(NT_Bool));
return arr;
@@ -1009,7 +1013,7 @@ double* NT_GetValueDoubleArray(const struct NT_Value* value,
*last_change = value->last_change;
*arr_size = value->data.arr_double.size;
double* arr = static_cast<double*>(
std::malloc(value->data.arr_double.size * sizeof(double)));
wpi::CheckedMalloc(value->data.arr_double.size * sizeof(double)));
std::memcpy(arr, value->data.arr_double.arr,
value->data.arr_double.size * sizeof(double));
return arr;
@@ -1021,11 +1025,11 @@ NT_String* NT_GetValueStringArray(const struct NT_Value* value,
*last_change = value->last_change;
*arr_size = value->data.arr_string.size;
NT_String* arr = static_cast<NT_String*>(
std::malloc(value->data.arr_string.size * sizeof(NT_String)));
wpi::CheckedMalloc(value->data.arr_string.size * sizeof(NT_String)));
for (size_t i = 0; i < value->data.arr_string.size; ++i) {
size_t len = value->data.arr_string.arr[i].len;
arr[i].len = len;
arr[i].str = static_cast<char*>(std::malloc(len + 1));
arr[i].str = static_cast<char*>(wpi::CheckedMalloc(len + 1));
std::memcpy(arr[i].str, value->data.arr_string.arr[i].str, len + 1);
}
return arr;
@@ -1129,7 +1133,8 @@ NT_Bool* NT_GetEntryBooleanArray(NT_Entry entry, uint64_t* last_change,
if (!v || !v->IsBooleanArray()) return nullptr;
*last_change = v->last_change();
auto vArr = v->GetBooleanArray();
NT_Bool* arr = static_cast<int*>(std::malloc(vArr.size() * sizeof(NT_Bool)));
NT_Bool* arr =
static_cast<int*>(wpi::CheckedMalloc(vArr.size() * sizeof(NT_Bool)));
*arr_size = vArr.size();
std::copy(vArr.begin(), vArr.end(), arr);
return arr;
@@ -1141,7 +1146,8 @@ double* NT_GetEntryDoubleArray(NT_Entry entry, uint64_t* last_change,
if (!v || !v->IsDoubleArray()) return nullptr;
*last_change = v->last_change();
auto vArr = v->GetDoubleArray();
double* arr = static_cast<double*>(std::malloc(vArr.size() * sizeof(double)));
double* arr =
static_cast<double*>(wpi::CheckedMalloc(vArr.size() * sizeof(double)));
*arr_size = vArr.size();
std::copy(vArr.begin(), vArr.end(), arr);
return arr;
@@ -1153,8 +1159,8 @@ NT_String* NT_GetEntryStringArray(NT_Entry entry, uint64_t* last_change,
if (!v || !v->IsStringArray()) return nullptr;
*last_change = v->last_change();
auto vArr = v->GetStringArray();
NT_String* arr =
static_cast<NT_String*>(std::malloc(vArr.size() * sizeof(NT_String)));
NT_String* arr = static_cast<NT_String*>(
wpi::CheckedMalloc(vArr.size() * sizeof(NT_String)));
for (size_t i = 0; i < vArr.size(); ++i) {
ConvertToC(vArr[i], &arr[i]);
}

View File

@@ -7,12 +7,14 @@
#include "ntcore_test.h"
#include <wpi/memory.h>
#include "Value_internal.h"
extern "C" {
struct NT_String* NT_GetStringForTesting(const char* string, int* struct_size) {
struct NT_String* str =
static_cast<NT_String*>(std::calloc(1, sizeof(NT_String)));
static_cast<NT_String*>(wpi::CheckedCalloc(1, sizeof(NT_String)));
nt::ConvertToC(wpi::StringRef(string), str);
*struct_size = sizeof(NT_String);
return str;
@@ -24,7 +26,7 @@ struct NT_EntryInfo* NT_GetEntryInfoForTesting(const char* name,
uint64_t last_change,
int* struct_size) {
struct NT_EntryInfo* entry_info =
static_cast<NT_EntryInfo*>(std::calloc(1, sizeof(NT_EntryInfo)));
static_cast<NT_EntryInfo*>(wpi::CheckedCalloc(1, sizeof(NT_EntryInfo)));
nt::ConvertToC(wpi::StringRef(name), &entry_info->name);
entry_info->type = type;
entry_info->flags = flags;
@@ -42,7 +44,7 @@ struct NT_ConnectionInfo* NT_GetConnectionInfoForTesting(
const char* remote_id, const char* remote_ip, unsigned int remote_port,
uint64_t last_update, unsigned int protocol_version, int* struct_size) {
struct NT_ConnectionInfo* conn_info = static_cast<NT_ConnectionInfo*>(
std::calloc(1, sizeof(NT_ConnectionInfo)));
wpi::CheckedCalloc(1, sizeof(NT_ConnectionInfo)));
nt::ConvertToC(wpi::StringRef(remote_id), &conn_info->remote_id);
nt::ConvertToC(wpi::StringRef(remote_ip), &conn_info->remote_ip);
conn_info->remote_port = remote_port;
@@ -61,7 +63,7 @@ void NT_FreeConnectionInfoForTesting(struct NT_ConnectionInfo* info) {
struct NT_Value* NT_GetValueBooleanForTesting(uint64_t last_change, int val,
int* struct_size) {
struct NT_Value* value =
static_cast<NT_Value*>(std::calloc(1, sizeof(NT_Value)));
static_cast<NT_Value*>(wpi::CheckedCalloc(1, sizeof(NT_Value)));
value->type = NT_BOOLEAN;
value->last_change = last_change;
value->data.v_boolean = val;
@@ -72,7 +74,7 @@ struct NT_Value* NT_GetValueBooleanForTesting(uint64_t last_change, int val,
struct NT_Value* NT_GetValueDoubleForTesting(uint64_t last_change, double val,
int* struct_size) {
struct NT_Value* value =
static_cast<NT_Value*>(std::calloc(1, sizeof(NT_Value)));
static_cast<NT_Value*>(wpi::CheckedCalloc(1, sizeof(NT_Value)));
value->type = NT_DOUBLE;
value->last_change = last_change;
value->data.v_double = val;
@@ -84,7 +86,7 @@ struct NT_Value* NT_GetValueStringForTesting(uint64_t last_change,
const char* str,
int* struct_size) {
struct NT_Value* value =
static_cast<NT_Value*>(std::calloc(1, sizeof(NT_Value)));
static_cast<NT_Value*>(wpi::CheckedCalloc(1, sizeof(NT_Value)));
value->type = NT_STRING;
value->last_change = last_change;
nt::ConvertToC(wpi::StringRef(str), &value->data.v_string);
@@ -95,7 +97,7 @@ struct NT_Value* NT_GetValueStringForTesting(uint64_t last_change,
struct NT_Value* NT_GetValueRawForTesting(uint64_t last_change, const char* raw,
int raw_len, int* struct_size) {
struct NT_Value* value =
static_cast<NT_Value*>(std::calloc(1, sizeof(NT_Value)));
static_cast<NT_Value*>(wpi::CheckedCalloc(1, sizeof(NT_Value)));
value->type = NT_RAW;
value->last_change = last_change;
nt::ConvertToC(wpi::StringRef(raw, raw_len), &value->data.v_string);
@@ -108,7 +110,7 @@ struct NT_Value* NT_GetValueBooleanArrayForTesting(uint64_t last_change,
size_t array_len,
int* struct_size) {
struct NT_Value* value =
static_cast<NT_Value*>(std::calloc(1, sizeof(NT_Value)));
static_cast<NT_Value*>(wpi::CheckedCalloc(1, sizeof(NT_Value)));
value->type = NT_BOOLEAN_ARRAY;
value->last_change = last_change;
value->data.arr_boolean.arr = NT_AllocateBooleanArray(array_len);
@@ -124,7 +126,7 @@ struct NT_Value* NT_GetValueDoubleArrayForTesting(uint64_t last_change,
size_t array_len,
int* struct_size) {
struct NT_Value* value =
static_cast<NT_Value*>(std::calloc(1, sizeof(NT_Value)));
static_cast<NT_Value*>(wpi::CheckedCalloc(1, sizeof(NT_Value)));
value->type = NT_BOOLEAN;
value->last_change = last_change;
value->data.arr_double.arr = NT_AllocateDoubleArray(array_len);
@@ -140,7 +142,7 @@ struct NT_Value* NT_GetValueStringArrayForTesting(uint64_t last_change,
size_t array_len,
int* struct_size) {
struct NT_Value* value =
static_cast<NT_Value*>(std::calloc(1, sizeof(NT_Value)));
static_cast<NT_Value*>(wpi::CheckedCalloc(1, sizeof(NT_Value)));
value->type = NT_BOOLEAN;
value->last_change = last_change;
value->data.arr_string.arr = NT_AllocateStringArray(array_len);
@@ -149,7 +151,7 @@ struct NT_Value* NT_GetValueStringArrayForTesting(uint64_t last_change,
size_t len = arr[i].len;
value->data.arr_string.arr[i].len = len;
value->data.arr_string.arr[i].str =
static_cast<char*>(std::malloc(len + 1));
static_cast<char*>(wpi::CheckedMalloc(len + 1));
std::memcpy(value->data.arr_string.arr[i].str, arr[i].str, len + 1);
}
*struct_size = sizeof(NT_Value);
@@ -171,8 +173,8 @@ static void CopyNtString(const struct NT_String* copy_from,
struct NT_RpcParamDef* NT_GetRpcParamDefForTesting(const char* name,
const struct NT_Value* val,
int* struct_size) {
struct NT_RpcParamDef* def =
static_cast<NT_RpcParamDef*>(std::calloc(1, sizeof(NT_RpcParamDef)));
struct NT_RpcParamDef* def = static_cast<NT_RpcParamDef*>(
wpi::CheckedCalloc(1, sizeof(NT_RpcParamDef)));
nt::ConvertToC(wpi::StringRef(name), &def->name);
CopyNtValue(val, &def->def_value);
*struct_size = sizeof(NT_RpcParamDef);
@@ -188,8 +190,8 @@ void NT_FreeRpcParamDefForTesting(struct NT_RpcParamDef* def) {
struct NT_RpcResultDef* NT_GetRpcResultsDefForTesting(const char* name,
enum NT_Type type,
int* struct_size) {
struct NT_RpcResultDef* def =
static_cast<NT_RpcResultDef*>(std::calloc(1, sizeof(NT_RpcResultDef)));
struct NT_RpcResultDef* def = static_cast<NT_RpcResultDef*>(
wpi::CheckedCalloc(1, sizeof(NT_RpcResultDef)));
nt::ConvertToC(wpi::StringRef(name), &def->name);
def->type = type;
*struct_size = sizeof(NT_RpcResultDef);
@@ -205,20 +207,20 @@ struct NT_RpcDefinition* NT_GetRpcDefinitionForTesting(
unsigned int version, const char* name, size_t num_params,
const struct NT_RpcParamDef* params, size_t num_results,
const struct NT_RpcResultDef* results, int* struct_size) {
struct NT_RpcDefinition* def =
static_cast<NT_RpcDefinition*>(std::calloc(1, sizeof(NT_RpcDefinition)));
struct NT_RpcDefinition* def = static_cast<NT_RpcDefinition*>(
wpi::CheckedCalloc(1, sizeof(NT_RpcDefinition)));
def->version = version;
nt::ConvertToC(wpi::StringRef(name), &def->name);
def->num_params = num_params;
def->params = static_cast<NT_RpcParamDef*>(
std::malloc(num_params * sizeof(NT_RpcParamDef)));
wpi::CheckedMalloc(num_params * sizeof(NT_RpcParamDef)));
for (size_t i = 0; i < num_params; ++i) {
CopyNtString(&params[i].name, &def->params[i].name);
CopyNtValue(&params[i].def_value, &def->params[i].def_value);
}
def->num_results = num_results;
def->results = static_cast<NT_RpcResultDef*>(
std::malloc(num_results * sizeof(NT_RpcResultDef)));
wpi::CheckedMalloc(num_results * sizeof(NT_RpcResultDef)));
for (size_t i = 0; i < num_results; ++i) {
CopyNtString(&results[i].name, &def->results[i].name);
def->results[i].type = results[i].type;
@@ -232,7 +234,7 @@ struct NT_RpcAnswer* NT_GetRpcAnswerForTesting(
unsigned int rpc_id, unsigned int call_uid, const char* name,
const char* params, size_t params_len, int* struct_size) {
struct NT_RpcAnswer* info =
static_cast<NT_RpcAnswer*>(std::calloc(1, sizeof(NT_RpcAnswer)));
static_cast<NT_RpcAnswer*>(wpi::CheckedCalloc(1, sizeof(NT_RpcAnswer)));
info->entry = rpc_id;
info->call = call_uid;
nt::ConvertToC(wpi::StringRef(name), &info->name);