forked from uber-archive/statsrelay
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvalidate.c
134 lines (115 loc) · 2.73 KB
/
validate.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "validate.h"
#include "log.h"
#include <string.h>
static char *valid_stat_types[6] = {
"c",
"ms",
"kv",
"g",
"h",
"s"
};
static size_t valid_stat_types_len = 6;
int validate_statsd(const char *line, size_t len) {
size_t plen;
char c;
int i, valid;
// FIXME: this is dumb, don't do a memory copy
char *line_copy = strndup(line, len);
char *start, *end;
char *err;
start = line_copy;
plen = len;
end = memchr(start, ':', plen);
if (end == NULL) {
stats_log("validate: Invalid line \"%.*s\" missing ':'", len, line);
goto statsd_err;
}
if ((end - start) < 1) {
stats_log("validate: Invalid line \"%.*s\" zero length key", len, line);
goto statsd_err;
}
start = end + 1;
plen = len - (start - line_copy);
c = end[0];
end[0] = '\0';
if ((strtod(start, &err) == 0.0) && (err == start)) {
stats_log("validate: Invalid line \"%.*s\" unable to parse value as double", len, line);
goto statsd_err;
}
end[0] = c;
end = memchr(start, '|', plen);
if (end == NULL) {
stats_log("validate: Invalid line \"%.*s\" missing '|'", len, line);
goto statsd_err;
}
start = end + 1;
plen = len - (start - line_copy);
end = memchr(start, '|', plen);
if (end != NULL) {
c = end[0];
end[0] = '\0';
plen = end - start;
}
valid = 0;
for (i = 0; i < valid_stat_types_len; i++) {
if (strlen(valid_stat_types[i]) != plen) {
continue;
}
if (strncmp(start, valid_stat_types[i], plen) == 0) {
valid = 1;
break;
}
}
if (valid == 0) {
stats_log("validate: Invalid line \"%.*s\" unknown stat type \"%.*s\"", len, line, plen, start);
goto statsd_err;
}
if (end != NULL) {
end[0] = c;
// end[0] is currently the second | char
// test if we have at least 1 char following it (@)
if ((len - (end - line_copy) > 1) && (end[1] == '@')) {
start = end + 2;
plen = len - (start - line_copy);
if (plen == 0) {
stats_log("validate: Invalid line \"%.*s\" @ sample with no rate", len, line);
goto statsd_err;
}
if ((strtod(start, &err) == 0.0) && err == start) {
stats_log("validate: Invalid line \"%.*s\" invalid sample rate", len, line);
goto statsd_err;
}
} else {
stats_log("validate: Invalid line \"%.*s\" no @ sample rate specifier", len, line);
goto statsd_err;
}
}
free(line_copy);
return 0;
statsd_err:
free(line_copy);
return 1;
}
int validate_carbon(const char *line, size_t len) {
int spaces_found = 0;
const char *p = line;
size_t n = len;
while (1) {
const char *s = memchr(p, ' ', n);
if (s == NULL) {
break;
}
spaces_found++;
n = len - (s - line) - 1;
p = s + 1;
if (spaces_found > 2) {
break;
}
}
if (spaces_found != 2) {
stats_log("validate: found %d spaces in invalid carbon line", spaces_found);
return 1;
}
return 0;
}