Remove VLA (variable-length arrays) (dbengine and health) (#22209)
thiagoftsm committed
Apr 16, 2026 at 11:18 UTC
50b95d6eca0a490262d0b3062ea0744faeffcaa6
5 files changed
+47
-28
src/database/rrdlabels.c
+3
-4
@@ -798,8 +798,7 @@ static SIMPLE_PATTERN_RESULT simple_pattern_match_name_and_value_callback(const
798
t->searches++;
799
if(simple_pattern_matches(t->pattern, name)) return -1;
800
801
- size_t len = RRDLABELS_MAX_NAME_LENGTH + RRDLABELS_MAX_VALUE_LENGTH + 2; // +1 for =, +1 for \0
802
- char tmp[len], *dst = &tmp[0];
801
+ char tmp[RRDLABELS_MAX_NAME_LENGTH + RRDLABELS_MAX_VALUE_LENGTH + 2], *dst = &tmp[0];
802
const char *v = value;
803
804
// copy the name
@@ -904,8 +903,8 @@ static int label_to_buffer_callback(const RRDLABEL *lb, void *value __maybe_unus
903
size_t n_size = (t->name_sanitizer ) ? ( RRDLABELS_MAX_NAME_LENGTH * 2 ) : 1;
904
size_t v_size = (t->value_sanitizer) ? ( RRDLABELS_MAX_VALUE_LENGTH * 2 ) : 1;
905
907
- char n[n_size];
908
- char v[v_size];
906
+ char n[RRDLABELS_MAX_NAME_LENGTH * 2];
907
+ char v[RRDLABELS_MAX_VALUE_LENGTH * 2];
908
909
const char *name = string2str(lb->index.key);
910
src/health/health_config.c
+7
-2
@@ -523,8 +523,12 @@ static void lookup_data_source_from_rrdr_options(RRD_ALERT_PROTOTYPE *ap) {
523
\
524
if(value) { \
525
typeof(ax->member) _old = ax->member; \
526
- char _buf[strlen(value) + string_strlen(_old) + (_label ? strlen(_label) : 0) + 3]; \
527
- snprintfz(_buf, sizeof(_buf), "%s%s%s%s%s", \
526
+ size_t _label_len = _label ? strlen(_label) : 0; \
527
+ size_t _value_len = strlen(value); \
528
+ size_t _old_len = _old ? string_strlen(_old) : 0; \
529
+ size_t _buf_len = _label_len + (_label ? 1 : 0) + _value_len + (_old ? 1 : 0) + _old_len + 1; \
530
+ char *_buf = mallocz(_buf_len); \
531
+ snprintfz(_buf, _buf_len, "%s%s%s%s%s", \
532
_label ? _label : "", \
533
_label ? "=" : "", \
534
value, \
@@ -532,6 +536,7 @@ static void lookup_data_source_from_rrdr_options(RRD_ALERT_PROTOTYPE *ap) {
536
_old ? string2str(_old) : ""); \
537
string_freez(_old); \
538
ax->member = string_strdupz(_buf); \
539
+ freez(_buf); \
540
} \
541
} while(0)
542
src/health/health_dyncfg.c
+17
-10
@@ -6,6 +6,19 @@
6
7
static void health_dyncfg_register_prototype(RRD_ALERT_PROTOTYPE *ap);
8
9
+static char *health_dyncfg_alert_prototype_id_strdupz(const char *alert_name) {
10
+ size_t prefix_len = strlen(DYNCFG_HEALTH_ALERT_PROTOTYPE_PREFIX);
11
+ size_t alert_name_len = strlen(alert_name);
12
+ size_t id_len = prefix_len + 1 + alert_name_len;
13
+ char *id = mallocz(id_len + 1);
14
+
15
+ int written = snprintfz(id, id_len + 1, DYNCFG_HEALTH_ALERT_PROTOTYPE_PREFIX ":%s", alert_name);
16
+ internal_fatal((size_t)written != id_len,
17
+ "HEALTH DYNCFG: failed to build dyncfg id for alert '%s'", alert_name);
18
+
19
+ return id;
20
+}
21
+
22
// ---------------------------------------------------------------------------------------------------------------------
23
// parse the json object of an alert definition
24
@@ -632,9 +645,7 @@ static int dyncfg_health_prototype_job_action(BUFFER *result, DYNCFG_CMDS cmd, B
645
return dyncfg_default_response(result, HTTP_RESP_NOT_FOUND, "no alert prototype is available by the name given");
646
647
RRD_ALERT_PROTOTYPE *ap = dictionary_acquired_item_value(item);
635
-
636
- char alert_name_dyncfg[strlen(DYNCFG_HEALTH_ALERT_PROTOTYPE_PREFIX) + strlen(alert_name) + 10];
637
- snprintfz(alert_name_dyncfg, sizeof(alert_name_dyncfg), DYNCFG_HEALTH_ALERT_PROTOTYPE_PREFIX ":%s", alert_name);
648
+ CLEAN_CHAR_P *alert_name_dyncfg = health_dyncfg_alert_prototype_id_strdupz(alert_name);
649
650
int code = HTTP_RESP_INTERNAL_SERVER_ERROR;
651
@@ -744,9 +755,7 @@ static int dyncfg_health_prototype_job_action(BUFFER *result, DYNCFG_CMDS cmd, B
755
int dyncfg_health_cb(const char *transaction __maybe_unused, const char *id, DYNCFG_CMDS cmd, const char *add_name,
756
BUFFER *payload, usec_t *stop_monotonic_ut __maybe_unused, bool *cancelled __maybe_unused,
757
BUFFER *result, HTTP_ACCESS access __maybe_unused, const char *source, void *data __maybe_unused) {
747
-
748
- char buf[strlen(id) + 1];
749
- memcpy(buf, id, sizeof(buf));
758
+ CLEAN_CHAR_P *buf = strdupz(id);
759
760
char *words[100] = { NULL };
761
size_t num_words = quoted_strings_splitter_dyncfg_id(buf, words, 100);
@@ -780,14 +789,13 @@ int dyncfg_health_cb(const char *transaction __maybe_unused, const char *id, DYN
789
}
790
791
void health_dyncfg_unregister_all_prototypes(void) {
783
- char key[HEALTH_CONF_MAX_LINE];
792
RRD_ALERT_PROTOTYPE *ap;
793
794
// remove dyncfg
795
// it is ok if they are not added before
796
797
dfe_start_read(health_globals.prototypes.dict, ap) {
790
- snprintfz(key, sizeof(key), DYNCFG_HEALTH_ALERT_PROTOTYPE_PREFIX ":%s", string2str(ap->config.name));
798
+ CLEAN_CHAR_P *key = health_dyncfg_alert_prototype_id_strdupz(string2str(ap->config.name));
799
dyncfg_del(localhost, key);
800
}
801
dfe_done(ap);
@@ -795,13 +803,12 @@ void health_dyncfg_unregister_all_prototypes(void) {
803
}
804
805
static void health_dyncfg_register_prototype(RRD_ALERT_PROTOTYPE *ap) {
798
- char key[HEALTH_CONF_MAX_LINE];
806
+ CLEAN_CHAR_P *key = health_dyncfg_alert_prototype_id_strdupz(string2str(ap->config.name));
807
808
// bool trace = false;
809
// if(string_strcmp(ap->config.name, "ram_available") == 0)
810
// trace = true;
811
804
- snprintfz(key, sizeof(key), DYNCFG_HEALTH_ALERT_PROTOTYPE_PREFIX ":%s", string2str(ap->config.name));
812
dyncfg_add(localhost, key, "/health/alerts/prototypes",
813
ap->_internal.enabled ? DYNCFG_STATUS_ACCEPTED : DYNCFG_STATUS_DISABLED, DYNCFG_TYPE_JOB,
814
ap->config.source_type, string2str(ap->config.source),
src/health/health_prototypes.c
+17
-9
@@ -295,15 +295,19 @@ void health_init_prototypes(void) {
295
296
static inline struct pattern_array *health_config_add_key_to_values(struct pattern_array *pa, const char *input_key, char *value)
297
{
298
- char key[HEALTH_CONF_MAX_LINE + 1];
299
- char data[HEALTH_CONF_MAX_LINE + 1];
298
+ size_t value_len = strlen(value);
299
+ size_t input_key_len = input_key ? strlen(input_key) : 0;
300
+ size_t key_len = value_len > input_key_len ? value_len : input_key_len;
301
+ size_t pair_len = key_len + value_len + 4;
302
+ char *key = mallocz(key_len + 1);
303
+ char *data = mallocz(value_len + 1);
304
+ char *pair = mallocz(pair_len);
305
306
char *s = value;
307
size_t i = 0;
308
304
- char pair[HEALTH_CONF_MAX_LINE + 1];
309
if (input_key)
306
- strncpyz(key, input_key, HEALTH_CONF_MAX_LINE);
310
+ strncpyz(key, input_key, key_len);
311
else
312
key[0] = '\0';
313
@@ -311,14 +315,14 @@ static inline struct pattern_array *health_config_add_key_to_values(struct patte
315
if (*s == '=') {
316
//hold the key
317
data[i]='\0';
314
- strncpyz(key, data, HEALTH_CONF_MAX_LINE);
318
+ strncpyz(key, data, key_len);
319
i=0;
320
} else if (*s == ' ') {
321
data[i]='\0';
322
if (data[0]=='!')
319
- snprintfz(pair, HEALTH_CONF_MAX_LINE, "!%s=%s ", key, data + 1);
323
+ snprintfz(pair, pair_len, "!%s=%s ", key, data + 1);
324
else
321
- snprintfz(pair, HEALTH_CONF_MAX_LINE, "%s=%s ", key, data);
325
+ snprintfz(pair, pair_len, "%s=%s ", key, data);
326
327
pa = pattern_array_add_key_simple_pattern(pa, key, simple_pattern_create(pair, NULL, SIMPLE_PATTERN_EXACT, true));
328
i=0;
@@ -330,13 +334,17 @@ static inline struct pattern_array *health_config_add_key_to_values(struct patte
334
data[i]='\0';
335
if (data[0]) {
336
if (data[0]=='!')
333
- snprintfz(pair, HEALTH_CONF_MAX_LINE, "!%s=%s ", key, data + 1);
337
+ snprintfz(pair, pair_len, "!%s=%s ", key, data + 1);
338
else
335
- snprintfz(pair, HEALTH_CONF_MAX_LINE, "%s=%s ", key, data);
339
+ snprintfz(pair, pair_len, "%s=%s ", key, data);
340
341
pa = pattern_array_add_key_simple_pattern(pa, key, simple_pattern_create(pair, NULL, SIMPLE_PATTERN_EXACT, true));
342
}
343
344
+ freez(key);
345
+ freez(data);
346
+ freez(pair);
347
+
348
return pa;
349
}
350
src/health/health_variable.c
+3
-3
@@ -380,9 +380,7 @@ bool alert_variable_lookup_internal(STRING *variable, void *data, NETDATA_DOUBLE
380
381
// find the components of the variable
382
{
383
- char id[string_strlen(vbd.dim) + 1];
384
- memcpy(id, string2str(vbd.dim), string_strlen(vbd.dim));
385
- id[string_strlen(vbd.dim)] = '\0';
383
+ char *id = strdupz(string2str(vbd.dim));
384
385
char *dot = strrchr(id, '.');
386
while(dot) {
@@ -397,6 +395,8 @@ bool alert_variable_lookup_internal(STRING *variable, void *data, NETDATA_DOUBLE
395
*dot = '.';
396
dot = dot2;
397
}
398
+
399
+ freez(id);
400
}
401
402
find_best_scored: