Add warnings on alloc failure, enforce alloc check style

This commit is contained in:
Christian W. Zuckschwerdt 2019-10-17 08:32:56 +02:00
parent 78a4fbed62
commit de8f73b0ed
16 changed files with 271 additions and 147 deletions

38
include/fatal.h Normal file
View file

@ -0,0 +1,38 @@
/** @file
Fatal abort and warning macros for allocs.
Copyright (C) 2019 Christian W. Zuckschwerdt <zany@triq.net>
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_ */

View file

@ -15,6 +15,7 @@
#include "bitbuffer.h" #include "bitbuffer.h"
#include "samp_grab.h" #include "samp_grab.h"
#include "fatal.h"
#include "am_analyze.h" #include "am_analyze.h"
@ -25,7 +26,9 @@ am_analyze_t *am_analyze_create(void)
{ {
am_analyze_t *a; am_analyze_t *a;
a = calloc(1, sizeof(am_analyze_t)); 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) void am_analyze_free(am_analyze_t *a)

View file

@ -20,6 +20,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "confparse.h" #include "confparse.h"
#include "fatal.h"
#ifdef _WIN32 #ifdef _WIN32
#include <io.h> #include <io.h>
@ -59,8 +60,9 @@ char *readconf(char const *path)
return NULL; return NULL;
} }
conf = (char *)malloc(file_size + 1); conf = malloc(file_size + 1);
if (conf == NULL) { if (!conf) {
WARN_MALLOC("readconf()");
fprintf(stderr, "Failed to allocate memory for \"%s\"\n", path); fprintf(stderr, "Failed to allocate memory for \"%s\"\n", path);
fclose(fp); fclose(fp);
return NULL; return NULL;

View file

@ -52,6 +52,7 @@
#include "term_ctl.h" #include "term_ctl.h"
#include "abuf.h" #include "abuf.h"
#include "fatal.h"
#include "data.h" #include "data.h"
@ -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 *data_array(int num_values, data_type_t type, void *values)
{ {
data_array_t *array = calloc(1, sizeof(data_array_t)); data_array_t *array = calloc(1, sizeof(data_array_t));
if (array) { if (!array) {
int element_size = dmt[type].array_element_size; WARN_CALLOC("data_array()");
array->values = calloc(num_values, element_size); return NULL; // NOTE: returns NULL on alloc failure.
if (!array->values)
goto alloc_error;
if (!import_values(array->values, values, num_values, type))
goto alloc_error;
array->num_values = num_values;
array->type = type;
} }
return array; // NOTE: might silently return NULL on alloc failure.
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;
}
if (!import_values(array->values, values, num_values, type))
goto alloc_error;
array->num_values = num_values;
array->type = type;
return array;
alloc_error: alloc_error:
if (array) if (array)
@ -198,8 +205,10 @@ static data_t *vdata_make(data_t *first, const char *key, const char *pretty_key
switch (type) { switch (type) {
case DATA_FORMAT: case DATA_FORMAT:
format = strdup(va_arg(ap, char *)); format = strdup(va_arg(ap, char *));
if (!format) if (!format) {
WARN_STRDUP("vdata_make()");
goto alloc_error; goto alloc_error;
}
type = va_arg(ap, data_type_t); type = va_arg(ap, data_type_t);
continue; continue;
break; break;
@ -211,16 +220,22 @@ static data_t *vdata_make(data_t *first, const char *key, const char *pretty_key
break; break;
case DATA_INT: case DATA_INT:
value = malloc(sizeof(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); *(int *)value = va_arg(ap, int);
break; break;
case DATA_DOUBLE: case DATA_DOUBLE:
value = malloc(sizeof(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); *(double *)value = va_arg(ap, double);
break; break;
case DATA_STRING: case DATA_STRING:
value = strdup(va_arg(ap, char *)); value = strdup(va_arg(ap, char *));
if (!value)
WARN_STRDUP("vdata_make()");
break; break;
case DATA_ARRAY: case DATA_ARRAY:
value = va_arg(ap, data_t *); value = va_arg(ap, data_t *);
@ -234,17 +249,23 @@ static data_t *vdata_make(data_t *first, const char *key, const char *pretty_key
goto alloc_error; goto alloc_error;
current = calloc(1, sizeof(*current)); current = calloc(1, sizeof(*current));
if (!current) if (!current) {
WARN_CALLOC("vdata_make()");
goto alloc_error; goto alloc_error;
}
if (prev) if (prev)
prev->next = current; prev->next = current;
current->key = strdup(key); current->key = strdup(key);
if (!current->key) if (!current->key) {
WARN_STRDUP("vdata_make()");
goto alloc_error; goto alloc_error;
}
current->pretty_key = strdup(pretty_key ? pretty_key : key); current->pretty_key = strdup(pretty_key ? pretty_key : key);
if (!current->pretty_key) if (!current->pretty_key) {
WARN_STRDUP("vdata_make()");
goto alloc_error; goto alloc_error;
}
current->type = type; current->type = type;
current->format = format; current->format = format;
current->value = value; current->value = value;
@ -484,8 +505,8 @@ struct data_output *data_output_json_create(FILE *file)
{ {
data_output_t *output = calloc(1, sizeof(data_output_t)); data_output_t *output = calloc(1, sizeof(data_output_t));
if (!output) { if (!output) {
fprintf(stderr, "calloc() failed"); WARN_CALLOC("data_output_json_create()");
return NULL; return NULL; // NOTE: returns NULL on alloc failure.
} }
output->print_data = print_json_data; output->print_data = print_json_data;
@ -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)); data_output_kv_t *kv = calloc(1, sizeof(data_output_kv_t));
if (!kv) { if (!kv) {
fprintf(stderr, "calloc() failed"); WARN_CALLOC("data_output_kv_create()");
return NULL; return NULL; // NOTE: returns NULL on alloc failure.
} }
kv->output.print_data = print_kv_data; kv->output.print_data = print_kv_data;
@ -766,8 +787,10 @@ static void data_output_csv_start(struct data_output *output, const char **field
csv->separator = ","; csv->separator = ",";
allowed = calloc(num_fields, sizeof(const char *)); allowed = calloc(num_fields, sizeof(const char *));
if (!allowed) if (!allowed) {
WARN_CALLOC("data_output_csv_start()");
goto alloc_error; goto alloc_error;
}
memcpy(allowed, fields, sizeof(const char *) * num_fields); memcpy(allowed, fields, sizeof(const char *) * num_fields);
qsort(allowed, num_fields, sizeof(char *), compare_strings); qsort(allowed, num_fields, sizeof(char *), compare_strings);
@ -789,12 +812,16 @@ static void data_output_csv_start(struct data_output *output, const char **field
num_unique_fields = i; num_unique_fields = i;
csv->fields = calloc(num_unique_fields + 1, sizeof(const char *)); 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; goto alloc_error;
}
use_count = calloc(num_unique_fields, sizeof(*use_count)); use_count = calloc(num_unique_fields, sizeof(*use_count));
if (!use_count) if (!use_count) {
WARN_CALLOC("data_output_csv_start()");
goto alloc_error; goto alloc_error;
}
for (i = 0; i < num_fields; ++i) { for (i = 0; i < num_fields; ++i) {
const char **field = bsearch(&fields[i], allowed, num_unique_fields, sizeof(const char *), const char **field = bsearch(&fields[i], allowed, num_unique_fields, sizeof(const char *),
@ -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)); data_output_csv_t *csv = calloc(1, sizeof(data_output_csv_t));
if (!csv) { if (!csv) {
fprintf(stderr, "calloc() failed"); WARN_CALLOC("data_output_csv_create()");
return NULL; return NULL; // NOTE: returns NULL on alloc failure.
} }
csv->output.print_data = print_csv_data; csv->output.print_data = print_csv_data;
@ -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)); data_output_syslog_t *syslog = calloc(1, sizeof(data_output_syslog_t));
if (!syslog) { if (!syslog) {
fprintf(stderr, "calloc() failed"); WARN_CALLOC("data_output_syslog_create()");
return NULL; return NULL; // NOTE: returns NULL on alloc failure.
} }
#ifdef _WIN32 #ifdef _WIN32
WSADATA wsa; WSADATA wsa;

View file

@ -14,16 +14,21 @@
#include "data.h" #include "data.h"
#include "util.h" #include "util.h"
#include "decoder_util.h" #include "decoder_util.h"
#include "fatal.h"
// create decoder functions // create decoder functions
r_device *create_device(r_device *dev_template) r_device *create_device(r_device *dev_template)
{ {
r_device *r_dev = malloc(sizeof (*r_dev)); 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 *r_dev = *dev_template; // copy
return r_dev; // NOTE: might silently return NULL on alloc failure. return r_dev;
} }
// variadic print functions // variadic print functions
@ -121,13 +126,39 @@ void decoder_output_message(r_device *decoder, char const *msg)
decoder_output_data(decoder, data); 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; char *row_bits, *p;
p = row_bits = malloc(bit_len + bit_len / 4 + 1); // "1..\0" (1 space per nibble) p = row_bits = malloc(bit_len + bit_len / 4 + 1); // "1..\0" (1 space per nibble)
if (!row_bits) if (!row_bits) {
return NULL; // NOTE: might silently return NULL on alloc failure. WARN_MALLOC("bitrow_asprint_bits()");
return NULL; // NOTE: returns NULL on alloc failure.
}
// print bit-wide with a space every nibble // print bit-wide with a space every nibble
for (unsigned i = 0; i < bit_len; ++i) { for (unsigned i = 0; i < bit_len; ++i) {
@ -151,25 +182,13 @@ void decoder_output_bitbuffer(r_device *decoder, bitbuffer_t const *bitbuffer, c
data_t *data; data_t *data;
char *row_codes[BITBUF_ROWS]; char *row_codes[BITBUF_ROWS];
char *row_bits[BITBUF_ROWS] = {0}; char *row_bits[BITBUF_ROWS] = {0};
char row_bytes[BITBUF_COLS * 2 + 1];
unsigned i; unsigned i;
for (i = 0; i < bitbuffer->num_rows; i++) { for (i = 0; i < bitbuffer->num_rows; i++) {
row_bytes[0] = '\0'; row_codes[i] = bitrow_asprint_code(bitbuffer->bb[i], bitbuffer->bits_per_row[i]);
// 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);
if (decoder->verbose_bits) { 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]);
} }
} }
@ -216,9 +235,7 @@ void decoder_output_bitbuffer_array(r_device *decoder, bitbuffer_t const *bitbuf
NULL); NULL);
// a simpler representation for csv output // a simpler representation for csv output
row_codes[i] = malloc(8 + BITBUF_COLS * 2 + 1); // "{nnn}..\0" row_codes[i] = bitrow_asprint_code(bitbuffer->bb[i], bitbuffer->bits_per_row[i]);
if (row_codes[i]) // NOTE: might silently skip on alloc failure.
sprintf(row_codes[i], "{%d}%s", bitbuffer->bits_per_row[i], row_bytes);
} }
data = data_make( data = data_make(
@ -239,20 +256,8 @@ void decoder_output_bitrow(r_device *decoder, bitrow_t const bitrow, unsigned bi
data_t *data; data_t *data;
char *row_code; char *row_code;
char *row_bits = NULL; char *row_bits = NULL;
char row_bytes[BITBUF_COLS * 2 + 1];
row_bytes[0] = '\0'; row_code = bitrow_asprint_code(bitrow, bit_len);
// 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);
data = data_make( data = data_make(
"msg", "", DATA_STRING, msg, "msg", "", DATA_STRING, msg,
@ -260,7 +265,7 @@ void decoder_output_bitrow(r_device *decoder, bitrow_t const bitrow, unsigned bi
NULL); NULL);
if (decoder->verbose_bits) { if (decoder->verbose_bits) {
row_bits = bitrow_print_bits(bitrow, bit_len); row_bits = bitrow_asprint_bits(bitrow, bit_len);
data_append(data, data_append(data,
"bits", "", DATA_STRING, row_bits, "bits", "", DATA_STRING, row_bits,
NULL); NULL);

View file

@ -11,6 +11,7 @@
*/ */
#include "decoder.h" #include "decoder.h"
#include "fatal.h"
#include <stdlib.h> #include <stdlib.h>
r_device fineoffset_WH2; r_device fineoffset_WH2;
@ -19,14 +20,14 @@ static r_device *fineoffset_WH2_create(char *arg)
{ {
r_device *r_dev = create_device(&fineoffset_WH2); r_device *r_dev = create_device(&fineoffset_WH2);
if (!r_dev) { if (!r_dev) {
fprintf(stderr, "create_device() failed"); fprintf(stderr, "fineoffset_WH2_create() failed");
return NULL; // NOTE: returns NULL on alloc failure. return NULL; // NOTE: returns NULL on alloc failure.
} }
if (arg && !strcmp(arg, "no-wh5")) { if (arg && !strcmp(arg, "no-wh5")) {
int *quirk = malloc(sizeof (*quirk)); int *quirk = malloc(sizeof (*quirk));
if (!quirk) { if (!quirk) {
fprintf(stderr, "malloc() failed"); WARN_MALLOC("fineoffset_WH2_create()");
free(r_dev); free(r_dev);
return NULL; // NOTE: returns NULL on alloc failure. return NULL; // NOTE: returns NULL on alloc failure.
} }

View file

@ -10,6 +10,7 @@
#include "decoder.h" #include "decoder.h"
#include "optparse.h" #include "optparse.h"
#include "fatal.h"
#include <stdlib.h> #include <stdlib.h>
static inline int bit(const uint8_t *bytes, unsigned bit) static inline int bit(const uint8_t *bytes, unsigned bit)
@ -263,8 +264,10 @@ static int flex_callback(r_device *decoder, bitbuffer_t *bitbuffer)
render_getters(row_data[i], bitbuffer->bb[i], params); render_getters(row_data[i], bitbuffer->bb[i], params);
// a simpler representation for csv output // a simpler representation for csv output
row_codes[i] = malloc(8 + BITBUF_COLS * 2 + 1); // "{nnn}..\0" row_codes[i] = malloc(8 + bitbuffer->bits_per_row[i] / 4 + 1); // "{nnnn}..\0"
if (row_codes[i]) // NOTE: might silently skip on alloc failure. if (!row_codes[i])
WARN_MALLOC("flex_decode()");
else // NOTE: skipped on alloc failure.
sprintf(row_codes[i], "{%d}%s", bitbuffer->bits_per_row[i], row_bytes); sprintf(row_codes[i], "{%d}%s", bitbuffer->bits_per_row[i], row_bytes);
} }
/* clang-format off */ /* clang-format off */
@ -427,7 +430,9 @@ const char *parse_map(const char *arg, struct flex_get *getter)
const char *e = c; const char *e = c;
while (*e != ' ' && *e != ']') e++; while (*e != ' ' && *e != ']') e++;
val = malloc(e - c + 1); val = malloc(e - c + 1);
if (val) { // NOTE: might silently skip on alloc failure. if (!val)
WARN_MALLOC("parse_map()");
else { // NOTE: skipped on alloc failure.
memcpy(val, c, e - c); memcpy(val, c, e - c);
val[e - c] = '\0'; val[e - c] = '\0';
} }
@ -458,8 +463,11 @@ static void parse_getter(const char *arg, struct flex_get *getter)
getter->bit_count = parse_bits(arg, bitrow); getter->bit_count = parse_bits(arg, bitrow);
getter->mask = extract_number(bitrow, 0, getter->bit_count); getter->mask = extract_number(bitrow, 0, getter->bit_count);
} }
else else {
getter->name = strdup(arg); getter->name = strdup(arg);
if (!getter->name)
FATAL_STRDUP("parse_getter()");
}
arg = p; arg = p;
} }
if (!getter->name) { if (!getter->name) {
@ -480,18 +488,23 @@ r_device *flex_create_device(char *spec)
} }
struct flex_params *params = calloc(1, sizeof(*params)); struct flex_params *params = calloc(1, sizeof(*params));
if (!params) if (!params) {
return NULL; // NOTE: might silently return NULL on alloc failure. WARN_CALLOC("flex_create_device()");
return NULL; // NOTE: returns NULL on alloc failure.
}
r_device *dev = calloc(1, sizeof(*dev)); r_device *dev = calloc(1, sizeof(*dev));
if (!dev) { if (!dev) {
WARN_CALLOC("flex_create_device()");
free(params); free(params);
return NULL; // NOTE: might silently return NULL on alloc failure. return NULL; // NOTE: returns NULL on alloc failure.
} }
dev->decode_ctx = params; dev->decode_ctx = params;
char *c, *o; char *c, *o;
int get_count = 0; int get_count = 0;
spec = strdup(spec); spec = strdup(spec);
if (!spec)
FATAL_STRDUP("flex_create_device()");
// locate optional args and terminate mandatory args // locate optional args and terminate mandatory args
char *args = strchr(spec, ','); char *args = strchr(spec, ',');
if (args) { if (args) {
@ -508,10 +521,13 @@ r_device *flex_create_device(char *spec)
if (!strncasecmp(c, "name=", 5)) if (!strncasecmp(c, "name=", 5))
c += 5; c += 5;
params->name = strdup(c); params->name = strdup(c);
if (!params->name)
FATAL_STRDUP("flex_create_device()");
int name_size = strlen(c) + 27; int name_size = strlen(c) + 27;
dev->name = malloc(name_size); dev->name = malloc(name_size);
if (dev->name) // NOTE: might silently skip on alloc failure. if (!dev->name)
snprintf(dev->name, name_size, "General purpose decoder '%s'", c); FATAL_MALLOC("flex_create_device()");
snprintf(dev->name, name_size, "General purpose decoder '%s'", c);
c = strtok(NULL, ":"); c = strtok(NULL, ":");
if (c != NULL) { if (c != NULL) {

View file

@ -10,6 +10,7 @@
*/ */
#include "list.h" #include "list.h"
#include "fatal.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -18,8 +19,7 @@ void list_ensure_size(list_t *list, size_t min_size)
if (!list->elems || list->size < min_size) { if (!list->elems || list->size < min_size) {
list->elems = realloc(list->elems, min_size * sizeof(*list->elems)); list->elems = realloc(list->elems, min_size * sizeof(*list->elems));
if (!list->elems) { if (!list->elems) {
fprintf(stderr, "realloc() failed"); FATAL_REALLOC("list_ensure_size()");
exit(1); // NOTE: abort on alloc failure.
} }
list->size = min_size; list->size = min_size;

View file

@ -13,6 +13,7 @@
#include "output_mqtt.h" #include "output_mqtt.h"
#include "optparse.h" #include "optparse.h"
#include "util.h" #include "util.h"
#include "fatal.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -95,16 +96,13 @@ static void mqtt_client_event(struct mg_connection *nc, int ev, void *ev_data)
static struct mg_mgr *mqtt_client_init(char const *host, char const *port, char const *user, char const *pass, char const *client_id, int retain) static struct mg_mgr *mqtt_client_init(char const *host, char const *port, char const *user, char const *pass, char const *client_id, int retain)
{ {
struct mg_mgr *mgr = calloc(1, sizeof(*mgr)); struct mg_mgr *mgr = calloc(1, sizeof(*mgr));
if (!mgr) { if (!mgr)
fprintf(stderr, "calloc() failed in %s() %s:%d\n", __func__, __FILE__, __LINE__); FATAL_CALLOC("mqtt_client_init()");
exit(1);
}
mqtt_client_t *ctx = calloc(1, sizeof(*ctx)); mqtt_client_t *ctx = calloc(1, sizeof(*ctx));
if (!ctx) { if (!ctx)
fprintf(stderr, "calloc() failed in %s() %s:%d\n", __func__, __FILE__, __LINE__); FATAL_CALLOC("mqtt_client_init()");
exit(1);
}
ctx->opts.user_name = user; ctx->opts.user_name = user;
ctx->opts.password = pass; ctx->opts.password = pass;
ctx->publish_flags = MG_MQTT_QOS(0) | (retain ? MG_MQTT_RETAIN : 0); ctx->publish_flags = MG_MQTT_QOS(0) | (retain ? MG_MQTT_RETAIN : 0);
@ -331,8 +329,8 @@ static void print_mqtt_data(data_output_t *output, data_t *data, char *format)
size_t message_size = 20000; // state message need a large buffer size_t message_size = 20000; // state message need a large buffer
char *message = malloc(message_size); char *message = malloc(message_size);
if (!message) { if (!message) {
fprintf(stderr, "malloc() failed\n"); WARN_MALLOC("print_mqtt_data()");
return; // NOTE: skip on alloc failure. return; // NOTE: skip output on alloc failure.
} }
data_print_jsons(data, message, message_size); data_print_jsons(data, message, message_size);
expand_topic(mqtt->topic, mqtt->states, data, mqtt->hostname); expand_topic(mqtt->topic, mqtt->states, data, mqtt->hostname);
@ -440,24 +438,30 @@ static void data_output_mqtt_free(data_output_t *output)
static char *mqtt_topic_default(char const *topic, char const *base, char const *suffix) static char *mqtt_topic_default(char const *topic, char const *base, char const *suffix)
{ {
if (topic) char const *p;
return strdup(topic); if (topic) {
p = topic;
}
else if (!base) {
p = suffix;
}
else {
char path[256];
snprintf(path, sizeof(path), "%s/%s", base, suffix);
p = path;
}
if (!base) char *ret = strdup(p);
return strdup(suffix); if (!ret)
WARN_STRDUP("mqtt_topic_default()");
char path[256]; return ret;
snprintf(path, sizeof(path), "%s/%s", base, suffix);
return strdup(path);
} }
struct data_output *data_output_mqtt_create(char const *host, char const *port, char *opts, char const *dev_hint) struct data_output *data_output_mqtt_create(char const *host, char const *port, char *opts, char const *dev_hint)
{ {
data_output_mqtt_t *mqtt = calloc(1, sizeof(data_output_mqtt_t)); data_output_mqtt_t *mqtt = calloc(1, sizeof(data_output_mqtt_t));
if (!mqtt) { if (!mqtt)
fprintf(stderr, "calloc() failed in %s() %s:%d\n", __func__, __FILE__, __LINE__); FATAL_CALLOC("data_output_mqtt_create()");
exit(1);
}
gethostname(mqtt->hostname, sizeof(mqtt->hostname) - 1); gethostname(mqtt->hostname, sizeof(mqtt->hostname) - 1);
mqtt->hostname[sizeof(mqtt->hostname) - 1] = '\0'; mqtt->hostname[sizeof(mqtt->hostname) - 1] = '\0';

View file

@ -13,6 +13,7 @@
#include "pulse_demod.h" #include "pulse_demod.h"
#include "util.h" #include "util.h"
#include "decoder.h" #include "decoder.h"
#include "fatal.h"
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -56,7 +57,6 @@ void pulse_data_dump_raw(uint8_t *buf, unsigned len, uint64_t buf_offset, pulse_
} }
} }
__attribute__((always_inline))
static inline void chk_ret(int ret) static inline void chk_ret(int ret)
{ {
if (ret < 0) { if (ret < 0) {
@ -364,7 +364,10 @@ struct pulse_detect {
pulse_detect_t *pulse_detect_create() pulse_detect_t *pulse_detect_create()
{ {
return calloc(1, sizeof(pulse_detect_t)); pulse_detect_t *pulse_detect = calloc(1, sizeof(pulse_detect_t));
if (!pulse_detect)
WARN_CALLOC("pulse_detect_create()");
return pulse_detect;
} }
void pulse_detect_free(pulse_detect_t *pulse_detect) void pulse_detect_free(pulse_detect_t *pulse_detect)

View file

@ -27,6 +27,7 @@
#include "optparse.h" #include "optparse.h"
#include "output_mqtt.h" #include "output_mqtt.h"
#include "compat_time.h" #include "compat_time.h"
#include "fatal.h"
#ifdef _WIN32 #ifdef _WIN32
#include <io.h> #include <io.h>
@ -81,10 +82,8 @@ void r_init_cfg(r_cfg_t *cfg)
list_ensure_size(&cfg->output_handler, 16); list_ensure_size(&cfg->output_handler, 16);
cfg->demod = calloc(1, sizeof(*cfg->demod)); cfg->demod = calloc(1, sizeof(*cfg->demod));
if (!cfg->demod) { if (!cfg->demod)
fprintf(stderr, "Could not create demod!\n"); FATAL_CALLOC("r_init_cfg()");
exit(1);
}
cfg->demod->level_limit = DEFAULT_LEVEL_LIMIT; cfg->demod->level_limit = DEFAULT_LEVEL_LIMIT;
@ -95,10 +94,8 @@ void r_init_cfg(r_cfg_t *cfg)
r_cfg_t *r_create_cfg(void) r_cfg_t *r_create_cfg(void)
{ {
r_cfg_t *cfg = calloc(1, sizeof(*cfg)); r_cfg_t *cfg = calloc(1, sizeof(*cfg));
if (!cfg) { if (!cfg)
fprintf(stderr, "Could not create cfg!\n"); FATAL_CALLOC("r_create_cfg()");
exit(1);
}
r_init_cfg(cfg); r_init_cfg(cfg);
@ -167,10 +164,8 @@ void register_protocol(r_cfg_t *cfg, r_device *r_dev, char *arg)
fprintf(stderr, "Protocol [%d] \"%s\" does not take arguments \"%s\"!\n", r_dev->protocol_num, r_dev->name, arg); fprintf(stderr, "Protocol [%d] \"%s\" does not take arguments \"%s\"!\n", r_dev->protocol_num, r_dev->name, arg);
} }
p = malloc(sizeof(*p)); p = malloc(sizeof(*p));
if (!p) { if (!p)
fprintf(stderr, "Could not register protocol\n"); FATAL_CALLOC("register_protocol()");
exit(1);
}
*p = *r_dev; // copy *p = *r_dev; // copy
} }
@ -485,12 +480,15 @@ void data_acquired_handler(r_device *r_dev, data_t *data)
if ((d->type == DATA_STRING) && !strcmp(d->key, "battery")) { if ((d->type == DATA_STRING) && !strcmp(d->key, "battery")) {
free(d->key); free(d->key);
d->key = strdup("battery_ok"); d->key = strdup("battery_ok");
if (!d->key)
FATAL_STRDUP("data_acquired_handler()");
int ok = d->value && !strcmp(d->value, "OK"); int ok = d->value && !strcmp(d->value, "OK");
free(d->value); free(d->value);
d->type = DATA_INT; d->type = DATA_INT;
d->value = malloc(sizeof(int)); d->value = malloc(sizeof(int));
if (d->value) // NOTE: might silently skip on alloc failure. if (!d->value)
*(int *)d->value = ok; FATAL_MALLOC("data_acquired_handler()");
*(int *)d->value = ok;
break; break;
} }
} }
@ -868,10 +866,8 @@ void add_null_output(r_cfg_t *cfg, char *param)
void add_dumper(r_cfg_t *cfg, char const *spec, int overwrite) void add_dumper(r_cfg_t *cfg, char const *spec, int overwrite)
{ {
file_info_t *dumper = calloc(1, sizeof(*dumper)); file_info_t *dumper = calloc(1, sizeof(*dumper));
if (!dumper) { if (!dumper)
fprintf(stderr, "Could not add dumper\n"); FATAL_CALLOC("add_dumper()");
exit(1);
}
list_push(&cfg->demod->dumper, dumper); list_push(&cfg->demod->dumper, dumper);
parse_file_info(spec, dumper); parse_file_info(spec, dumper);

View file

@ -10,6 +10,7 @@
*/ */
#include "r_util.h" #include "r_util.h"
#include "fatal.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -169,9 +170,10 @@ char *str_replace(char *orig, char *rep, char *with)
} }
tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1); tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
if (!result) {
if (!result) WARN_MALLOC("str_replace()");
return NULL; return NULL; // NOTE: returns NULL on alloc failure.
}
// first time through the loop, all the variables are set correctly // first time through the loop, all the variables are set correctly
// from here on, // from here on,

View file

@ -46,6 +46,7 @@
#include "confparse.h" #include "confparse.h"
#include "term_ctl.h" #include "term_ctl.h"
#include "compat_paths.h" #include "compat_paths.h"
#include "fatal.h"
#ifdef _WIN32 #ifdef _WIN32
#include <io.h> #include <io.h>
@ -1211,12 +1212,11 @@ int main(int argc, char **argv) {
// Special case for in files // Special case for in files
if (cfg.in_files.len) { if (cfg.in_files.len) {
unsigned char *test_mode_buf = malloc(DEFAULT_BUF_LENGTH * sizeof(unsigned char)); unsigned char *test_mode_buf = malloc(DEFAULT_BUF_LENGTH * sizeof(unsigned char));
if (!test_mode_buf)
FATAL_MALLOC("test_mode_buf");
float *test_mode_float_buf = malloc(DEFAULT_BUF_LENGTH / sizeof(int16_t) * sizeof(float)); float *test_mode_float_buf = malloc(DEFAULT_BUF_LENGTH / sizeof(int16_t) * sizeof(float));
if (!test_mode_buf || !test_mode_float_buf) if (!test_mode_float_buf)
{ FATAL_MALLOC("test_mode_float_buf");
fprintf(stderr, "Couldn't allocate read buffers!\n");
exit(1);
}
if (cfg.duration > 0) { if (cfg.duration > 0) {
time(&cfg.stop_time); time(&cfg.stop_time);

View file

@ -25,23 +25,25 @@
#endif #endif
#include "samp_grab.h" #include "samp_grab.h"
#include "fatal.h"
samp_grab_t *samp_grab_create(unsigned size) samp_grab_t *samp_grab_create(unsigned size)
{ {
samp_grab_t *g; samp_grab_t *g;
g = calloc(1, sizeof(*g)); g = calloc(1, sizeof(*g));
if (!g) { if (!g) {
return NULL; // NOTE: silently return NULL on alloc failure. WARN_CALLOC("samp_grab_create()");
return NULL; // NOTE: returns NULL on alloc failure.
} }
g->sg_buf = malloc(size);
g->sg_size = size; g->sg_size = size;
g->sg_counter = 1; g->sg_counter = 1;
g->sg_buf = malloc(size);
if (!g->sg_buf) { if (!g->sg_buf) {
WARN_MALLOC("samp_grab_create()");
free(g); free(g);
return NULL; // NOTE: silently return NULL on alloc failure. return NULL; // NOTE: returns NULL on alloc failure.
} }
return g; return g;

View file

@ -19,6 +19,7 @@
#include "sdr.h" #include "sdr.h"
#include "r_util.h" #include "r_util.h"
#include "optparse.h" #include "optparse.h"
#include "fatal.h"
#ifdef RTLSDR #ifdef RTLSDR
#include "rtl-sdr.h" #include "rtl-sdr.h"
#include <libusb.h> /* libusb_error_name(), libusb_strerror() */ #include <libusb.h> /* libusb_error_name(), libusb_strerror() */
@ -152,8 +153,10 @@ static int rtltcp_open(sdr_dev_t **out_dev, int *sample_size, char *dev_query, i
fprintf(stderr, "rtl_tcp connected to %s:%s (Tuner: %s)\n", host, port, tuner_name); fprintf(stderr, "rtl_tcp connected to %s:%s (Tuner: %s)\n", host, port, tuner_name);
sdr_dev_t *dev = calloc(1, sizeof(sdr_dev_t)); sdr_dev_t *dev = calloc(1, sizeof(sdr_dev_t));
if (!dev) if (!dev) {
return -1; // NOTE: silently return on alloc failure. WARN_CALLOC("rtltcp_open()");
return -1; // NOTE: returns error on alloc failure.
}
dev->rtl_tcp = sock; dev->rtl_tcp = sock;
dev->sample_size = sizeof(uint8_t); // CU8 dev->sample_size = sizeof(uint8_t); // CU8
@ -185,8 +188,10 @@ static int rtltcp_read_loop(sdr_dev_t *dev, sdr_read_cb_t cb, void *ctx, uint32_
if (dev->buffer_size != buf_len) { if (dev->buffer_size != buf_len) {
free(dev->buffer); free(dev->buffer);
dev->buffer = malloc(buf_len); dev->buffer = malloc(buf_len);
if (!dev->buffer) if (!dev->buffer) {
return -1; // NOTE: silently return on alloc failure. WARN_MALLOC("rtltcp_read_loop()");
return -1; // NOTE: returns error on alloc failure.
}
dev->buffer_size = buf_len; dev->buffer_size = buf_len;
} }
uint8_t *buffer = dev->buffer; uint8_t *buffer = dev->buffer;
@ -294,9 +299,10 @@ static int sdr_open_rtl(sdr_dev_t **out_dev, int *sample_size, char *dev_query,
char vendor[256] = "n/a", product[256] = "n/a", serial[256] = "n/a"; char vendor[256] = "n/a", product[256] = "n/a", serial[256] = "n/a";
int r = -1; int r = -1;
sdr_dev_t *dev = calloc(1, sizeof(sdr_dev_t)); sdr_dev_t *dev = calloc(1, sizeof(sdr_dev_t));
if (!dev) if (!dev) {
return -1; // NOTE: silently return on alloc failure. WARN_CALLOC("sdr_open_rtl()");
return -1; // NOTE: returns error on alloc failure.
}
for (uint32_t i = dev_query ? dev_index : 0; for (uint32_t i = dev_query ? dev_index : 0;
//cast quiets -Wsign-compare; if dev_index were < 0, would have returned -1 above //cast quiets -Wsign-compare; if dev_index were < 0, would have returned -1 above
i < (dev_query ? (unsigned)dev_index + 1 : device_count); i < (dev_query ? (unsigned)dev_index + 1 : device_count);
@ -605,8 +611,10 @@ static int sdr_open_soapy(sdr_dev_t **out_dev, int *sample_size, char *dev_query
SoapySDR_setLogLevel(SOAPY_SDR_DEBUG); SoapySDR_setLogLevel(SOAPY_SDR_DEBUG);
sdr_dev_t *dev = calloc(1, sizeof(sdr_dev_t)); sdr_dev_t *dev = calloc(1, sizeof(sdr_dev_t));
if (!dev) if (!dev) {
return -1; // NOTE: silently return on alloc failure. WARN_CALLOC("sdr_open_soapy()");
return -1; // NOTE: returns error on alloc failure.
}
dev->soapy_dev = SoapySDRDevice_makeStrArgs(dev_query); dev->soapy_dev = SoapySDRDevice_makeStrArgs(dev_query);
if (!dev->soapy_dev) { if (!dev->soapy_dev) {
@ -661,9 +669,10 @@ static int soapysdr_read_loop(sdr_dev_t *dev, sdr_read_cb_t cb, void *ctx, uint3
if (dev->buffer_size != buf_len) { if (dev->buffer_size != buf_len) {
free(dev->buffer); free(dev->buffer);
dev->buffer = malloc(buf_len); dev->buffer = malloc(buf_len);
if (!dev->buffer) if (!dev->buffer) {
return -1; // NOTE: silently return on alloc failure. WARN_CALLOC("soapysdr_read_loop()");
return -1; // NOTE: returns error on alloc failure.
}
dev->buffer_size = buf_len; dev->buffer_size = buf_len;
} }
int16_t *buffer = dev->buffer; int16_t *buffer = dev->buffer;

View file

@ -35,6 +35,7 @@ static int style_check(char *path)
int long_errors = 0; int long_errors = 0;
int crlf_errors = 0; int crlf_errors = 0;
int tabs_errors = 0; int tabs_errors = 0;
int memc_errors = 0;
int leading_tabs = 0; int leading_tabs = 0;
int leading_spcs = 0; int leading_spcs = 0;
@ -42,6 +43,8 @@ static int style_check(char *path)
int use_stdout = 0; int use_stdout = 0;
int use_printf = 0; int use_printf = 0;
int need_cond = 0;
char str[MAX_LEN]; char str[MAX_LEN];
while (fgets(str, MAX_LEN, fp)) { while (fgets(str, MAX_LEN, fp)) {
int len = strlen(str); int len = strlen(str);
@ -72,6 +75,17 @@ static int style_check(char *path)
use_printf++; use_printf++;
} }
} }
if (need_cond && !strstr(str, "if (!")) {
// we had an alloc but no check on the following line
memc_errors++;
}
need_cond = 0;
if (strstr(str, "alloc(") && !strstr(str, "alloc()")) {
need_cond++;
}
if (strstr(str, "strdup(") && !strstr(str, "strdup()")) {
need_cond++;
}
} }
if (leading_tabs && leading_spcs) { if (leading_tabs && leading_spcs) {
tabs_errors = leading_tabs > leading_spcs ? leading_spcs : leading_tabs; tabs_errors = leading_tabs > leading_spcs ? leading_spcs : leading_tabs;
@ -85,6 +99,8 @@ static int style_check(char *path)
printf("File \"%s\" has %d CRLF errors.\n", path, crlf_errors); printf("File \"%s\" has %d CRLF errors.\n", path, crlf_errors);
if (tabs_errors) if (tabs_errors)
printf("File \"%s\" has %d MIXED tab/spaces errors.\n", path, tabs_errors); printf("File \"%s\" has %d MIXED tab/spaces errors.\n", path, tabs_errors);
if (memc_errors)
printf("File \"%s\" has %d ALLOC check errors.\n", path, memc_errors);
if (leading_tabs) if (leading_tabs)
printf("File \"%s\" has %d TAB indented lines.\n", path, leading_tabs); printf("File \"%s\" has %d TAB indented lines.\n", path, leading_tabs);
if (strict && use_stdout) if (strict && use_stdout)
@ -92,7 +108,7 @@ static int style_check(char *path)
if (strict && use_printf) if (strict && use_printf)
printf("File \"%s\" has %d PRINTF lines.\n", path, use_printf); printf("File \"%s\" has %d PRINTF lines.\n", path, use_printf);
return read_errors + long_errors + crlf_errors + tabs_errors + leading_tabs + (strict ? use_stdout + use_printf : 0); return read_errors + long_errors + crlf_errors + tabs_errors + leading_tabs + (strict ? use_stdout + use_printf : 0) + memc_errors;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])