@cryptotaxi247 / netdata-1 / commits / 50b95d6ec

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: