Skip to content

Commit

Permalink
Add warnings on alloc failure, enforce alloc check style
Browse files Browse the repository at this point in the history
  • Loading branch information
zuckschwerdt committed Oct 17, 2019
1 parent 78a4fbe commit de8f73b
Show file tree
Hide file tree
Showing 16 changed files with 270 additions and 146 deletions.
38 changes: 38 additions & 0 deletions include/fatal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/** @file
Fatal abort and warning macros for allocs.
Copyright (C) 2019 Christian W. Zuckschwerdt <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
*/

#ifndef INCLUDE_FATAL_H_
#define INCLUDE_FATAL_H_

#define STR(x) #x
#define STRINGIFY(x) STR(x)
#define FILE_LINE __FILE__ ":" STRINGIFY(__LINE__)
#define FATAL(what) do { fprintf(stderr, "FATAL: " what " from " FILE_LINE "\n"); exit(1); } while (0)
#define FATAL_MALLOC(what) FATAL("low memory? malloc() failed in " what)
#define FATAL_CALLOC(what) FATAL("low memory? calloc() failed in " what)
#define FATAL_REALLOC(what) FATAL("low memory? realloc() failed in " what)
#define FATAL_STRDUP(what) FATAL("low memory? strdup() failed in " what)
#define WARN(what) fprintf(stderr, "WARNING: " what " from " FILE_LINE "\n")
#define WARN_MALLOC(what) WARN("low memory? malloc() failed in " what)
#define WARN_CALLOC(what) WARN("low memory? calloc() failed in " what)
#define WARN_REALLOC(what) WARN("low memory? realloc() failed in " what)
#define WARN_STRDUP(what) WARN("low memory? strdup() failed in " what)

/*
Use like this:
char *buf = malloc(size);
if (!buf)
FATAL_MALLOC("my_func()");
*/

#endif /* INCLUDE_FATAL_H_ */
5 changes: 4 additions & 1 deletion src/am_analyze.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "bitbuffer.h"
#include "samp_grab.h"
#include "fatal.h"

#include "am_analyze.h"

Expand All @@ -25,7 +26,9 @@ am_analyze_t *am_analyze_create(void)
{
am_analyze_t *a;
a = calloc(1, sizeof(am_analyze_t));
return a; // NOTE: might silently return NULL on alloc failure.
if (!a)
WARN_CALLOC("am_analyze_create()");
return a; // NOTE: returns NULL on alloc failure.
}

void am_analyze_free(am_analyze_t *a)
Expand Down
6 changes: 4 additions & 2 deletions src/confparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include "confparse.h"
#include "fatal.h"

#ifdef _WIN32
#include <io.h>
Expand Down Expand Up @@ -59,8 +60,9 @@ char *readconf(char const *path)
return NULL;
}

conf = (char *)malloc(file_size + 1);
if (conf == NULL) {
conf = malloc(file_size + 1);
if (!conf) {
WARN_MALLOC("readconf()");
fprintf(stderr, "Failed to allocate memory for \"%s\"\n", path);
fclose(fp);
return NULL;
Expand Down
81 changes: 54 additions & 27 deletions src/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

#include "term_ctl.h"
#include "abuf.h"
#include "fatal.h"

#include "data.h"

Expand Down Expand Up @@ -163,18 +164,24 @@ static bool import_values(void *dst, void *src, int num_values, data_type_t type
data_array_t *data_array(int num_values, data_type_t type, void *values)
{
data_array_t *array = calloc(1, sizeof(data_array_t));
if (array) {
int element_size = dmt[type].array_element_size;
array->values = calloc(num_values, element_size);
if (!array->values)
goto alloc_error;
if (!import_values(array->values, values, num_values, type))
goto alloc_error;
if (!array) {
WARN_CALLOC("data_array()");
return NULL; // NOTE: returns NULL on alloc failure.
}

array->num_values = num_values;
array->type = type;
int element_size = dmt[type].array_element_size;
array->values = calloc(num_values, element_size);
if (!array->values) {
WARN_CALLOC("data_array()");
goto alloc_error;
}
return array; // NOTE: might silently return NULL on alloc failure.
if (!import_values(array->values, values, num_values, type))
goto alloc_error;

array->num_values = num_values;
array->type = type;

return array;

alloc_error:
if (array)
Expand All @@ -198,8 +205,10 @@ static data_t *vdata_make(data_t *first, const char *key, const char *pretty_key
switch (type) {
case DATA_FORMAT:
format = strdup(va_arg(ap, char *));
if (!format)
if (!format) {
WARN_STRDUP("vdata_make()");
goto alloc_error;
}
type = va_arg(ap, data_type_t);
continue;
break;
Expand All @@ -211,16 +220,22 @@ static data_t *vdata_make(data_t *first, const char *key, const char *pretty_key
break;
case DATA_INT:
value = malloc(sizeof(int));
if (value)
if (!value)
WARN_MALLOC("vdata_make()");
else // NOTE: skipped on alloc failure
*(int *)value = va_arg(ap, int);
break;
case DATA_DOUBLE:
value = malloc(sizeof(double));
if (value)
if (!value)
WARN_MALLOC("vdata_make()");
else // NOTE: skipped on alloc failure
*(double *)value = va_arg(ap, double);
break;
case DATA_STRING:
value = strdup(va_arg(ap, char *));
if (!value)
WARN_STRDUP("vdata_make()");
break;
case DATA_ARRAY:
value = va_arg(ap, data_t *);
Expand All @@ -234,17 +249,23 @@ static data_t *vdata_make(data_t *first, const char *key, const char *pretty_key
goto alloc_error;

current = calloc(1, sizeof(*current));
if (!current)
if (!current) {
WARN_CALLOC("vdata_make()");
goto alloc_error;
}
if (prev)
prev->next = current;

current->key = strdup(key);
if (!current->key)
if (!current->key) {
WARN_STRDUP("vdata_make()");
goto alloc_error;
}
current->pretty_key = strdup(pretty_key ? pretty_key : key);
if (!current->pretty_key)
if (!current->pretty_key) {
WARN_STRDUP("vdata_make()");
goto alloc_error;
}
current->type = type;
current->format = format;
current->value = value;
Expand Down Expand Up @@ -484,8 +505,8 @@ struct data_output *data_output_json_create(FILE *file)
{
data_output_t *output = calloc(1, sizeof(data_output_t));
if (!output) {
fprintf(stderr, "calloc() failed");
return NULL;
WARN_CALLOC("data_output_json_create()");
return NULL; // NOTE: returns NULL on alloc failure.
}

output->print_data = print_json_data;
Expand Down Expand Up @@ -670,8 +691,8 @@ struct data_output *data_output_kv_create(FILE *file)
{
data_output_kv_t *kv = calloc(1, sizeof(data_output_kv_t));
if (!kv) {
fprintf(stderr, "calloc() failed");
return NULL;
WARN_CALLOC("data_output_kv_create()");
return NULL; // NOTE: returns NULL on alloc failure.
}

kv->output.print_data = print_kv_data;
Expand Down Expand Up @@ -766,8 +787,10 @@ static void data_output_csv_start(struct data_output *output, const char **field
csv->separator = ",";

allowed = calloc(num_fields, sizeof(const char *));
if (!allowed)
if (!allowed) {
WARN_CALLOC("data_output_csv_start()");
goto alloc_error;
}
memcpy(allowed, fields, sizeof(const char *) * num_fields);

qsort(allowed, num_fields, sizeof(char *), compare_strings);
Expand All @@ -789,12 +812,16 @@ static void data_output_csv_start(struct data_output *output, const char **field
num_unique_fields = i;

csv->fields = calloc(num_unique_fields + 1, sizeof(const char *));
if (!csv->fields)
if (!csv->fields) {
WARN_CALLOC("data_output_csv_start()");
goto alloc_error;
}

use_count = calloc(num_unique_fields, sizeof(*use_count));
if (!use_count)
if (!use_count) {
WARN_CALLOC("data_output_csv_start()");
goto alloc_error;
}

for (i = 0; i < num_fields; ++i) {
const char **field = bsearch(&fields[i], allowed, num_unique_fields, sizeof(const char *),
Expand Down Expand Up @@ -847,8 +874,8 @@ struct data_output *data_output_csv_create(FILE *file)
{
data_output_csv_t *csv = calloc(1, sizeof(data_output_csv_t));
if (!csv) {
fprintf(stderr, "calloc() failed");
return NULL;
WARN_CALLOC("data_output_csv_create()");
return NULL; // NOTE: returns NULL on alloc failure.
}

csv->output.print_data = print_csv_data;
Expand Down Expand Up @@ -1102,8 +1129,8 @@ struct data_output *data_output_syslog_create(const char *host, const char *port
{
data_output_syslog_t *syslog = calloc(1, sizeof(data_output_syslog_t));
if (!syslog) {
fprintf(stderr, "calloc() failed");
return NULL;
WARN_CALLOC("data_output_syslog_create()");
return NULL; // NOTE: returns NULL on alloc failure.
}
#ifdef _WIN32
WSADATA wsa;
Expand Down
77 changes: 41 additions & 36 deletions src/decoder_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,21 @@
#include "data.h"
#include "util.h"
#include "decoder_util.h"
#include "fatal.h"

// create decoder functions

r_device *create_device(r_device *dev_template)
{
r_device *r_dev = malloc(sizeof (*r_dev));
if (r_dev && dev_template)
if (!r_dev) {
WARN_MALLOC("create_device()");
return NULL; // NOTE: returns NULL on alloc failure.
}
if (dev_template)
*r_dev = *dev_template; // copy

return r_dev; // NOTE: might silently return NULL on alloc failure.
return r_dev;
}

// variadic print functions
Expand Down Expand Up @@ -121,13 +126,39 @@ void decoder_output_message(r_device *decoder, char const *msg)
decoder_output_data(decoder, data);
}

static char *bitrow_print_bits(bitrow_t const bitrow, unsigned bit_len)
static char *bitrow_asprint_code(bitrow_t const bitrow, unsigned bit_len)
{
char *row_code;
char row_bytes[BITBUF_COLS * 2 + 1];

row_bytes[0] = '\0';
// print byte-wide
for (unsigned col = 0; col < (unsigned)(bit_len + 7) / 8; ++col) {
sprintf(&row_bytes[2 * col], "%02x", bitrow[col]);
}
// remove last nibble if needed
row_bytes[2 * (bit_len + 3) / 8] = '\0';

// a simple bitrow representation
row_code = malloc(8 + bit_len / 4 + 1); // "{nnnn}..\0"
if (!row_code) {
WARN_MALLOC("decoder_output_bitbuffer()");
return NULL; // NOTE: returns NULL on alloc failure.
}
sprintf(row_code, "{%d}%s", bit_len, row_bytes);

return row_code;
}

static char *bitrow_asprint_bits(bitrow_t const bitrow, unsigned bit_len)
{
char *row_bits, *p;

p = row_bits = malloc(bit_len + bit_len / 4 + 1); // "1..\0" (1 space per nibble)
if (!row_bits)
return NULL; // NOTE: might silently return NULL on alloc failure.
if (!row_bits) {
WARN_MALLOC("bitrow_asprint_bits()");
return NULL; // NOTE: returns NULL on alloc failure.
}

// print bit-wide with a space every nibble
for (unsigned i = 0; i < bit_len; ++i) {
Expand All @@ -151,25 +182,13 @@ void decoder_output_bitbuffer(r_device *decoder, bitbuffer_t const *bitbuffer, c
data_t *data;
char *row_codes[BITBUF_ROWS];
char *row_bits[BITBUF_ROWS] = {0};
char row_bytes[BITBUF_COLS * 2 + 1];
unsigned i;

for (i = 0; i < bitbuffer->num_rows; i++) {
row_bytes[0] = '\0';
// print byte-wide
for (unsigned col = 0; col < (unsigned)(bitbuffer->bits_per_row[i] + 7) / 8; ++col) {
sprintf(&row_bytes[2 * col], "%02x", bitbuffer->bb[i][col]);
}
// remove last nibble if needed
row_bytes[2 * (bitbuffer->bits_per_row[i] + 3) / 8] = '\0';

// a simpler representation for csv output
row_codes[i] = malloc(8 + BITBUF_COLS * 2 + 1); // "{nnn}..\0"
if (row_codes[i]) // NOTE: might silently skip on alloc failure.
sprintf(row_codes[i], "{%d}%s", bitbuffer->bits_per_row[i], row_bytes);
row_codes[i] = bitrow_asprint_code(bitbuffer->bb[i], bitbuffer->bits_per_row[i]);

if (decoder->verbose_bits) {
row_bits[i] = bitrow_print_bits(bitbuffer->bb[i], bitbuffer->bits_per_row[i]);
row_bits[i] = bitrow_asprint_bits(bitbuffer->bb[i], bitbuffer->bits_per_row[i]);
}
}

Expand Down Expand Up @@ -216,9 +235,7 @@ void decoder_output_bitbuffer_array(r_device *decoder, bitbuffer_t const *bitbuf
NULL);

// a simpler representation for csv output
row_codes[i] = malloc(8 + BITBUF_COLS * 2 + 1); // "{nnn}..\0"
if (row_codes[i]) // NOTE: might silently skip on alloc failure.
sprintf(row_codes[i], "{%d}%s", bitbuffer->bits_per_row[i], row_bytes);
row_codes[i] = bitrow_asprint_code(bitbuffer->bb[i], bitbuffer->bits_per_row[i]);
}

data = data_make(
Expand All @@ -239,28 +256,16 @@ void decoder_output_bitrow(r_device *decoder, bitrow_t const bitrow, unsigned bi
data_t *data;
char *row_code;
char *row_bits = NULL;
char row_bytes[BITBUF_COLS * 2 + 1];

row_bytes[0] = '\0';
// print byte-wide
for (unsigned col = 0; col < (bit_len + 7) / 8; ++col) {
sprintf(&row_bytes[2 * col], "%02x", bitrow[col]);
}
// remove last nibble if needed
row_bytes[2 * (bit_len + 3) / 8] = '\0';

// a simpler representation for csv output
row_code = malloc(8 + BITBUF_COLS * 2 + 1); // "{nnn}..\0"
if (row_code) // NOTE: might silently skip on alloc failure.
sprintf(row_code, "{%d}%s", bit_len, row_bytes);
row_code = bitrow_asprint_code(bitrow, bit_len);

data = data_make(
"msg", "", DATA_STRING, msg,
"codes", "", DATA_STRING, row_code,
NULL);

if (decoder->verbose_bits) {
row_bits = bitrow_print_bits(bitrow, bit_len);
row_bits = bitrow_asprint_bits(bitrow, bit_len);
data_append(data,
"bits", "", DATA_STRING, row_bits,
NULL);
Expand Down
Loading

0 comments on commit de8f73b

Please sign in to comment.