prometheus-client-mmap 0.24.3-aarch64-linux → 0.24.4-aarch64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '036069dbaa72e29118060526349e03e4dc12ca727d3460bd984c151ec409dfc9'
|
4
|
+
data.tar.gz: 3291d33938421d272ff8322d842636055c5aa42fe11f0dc4752f144e84d17ee2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a301f93346803f1470e6be0be03102267b244778ee65029f68882cfcfd81d1189afe7e229c24418b4e236b7d9e42578f3a18e3503a9810b879f7819408ed48d7
|
7
|
+
data.tar.gz: ff90c64f85839fee802123c32de0c74a2d1da554bf849bb7a0713e70adf12e901961556befd40966db13071e290795f8d029ce9010f138f68c481f56f3997fb0
|
@@ -63,35 +63,35 @@ fn parse_names(json: &str) -> Option<MetricNames> {
|
|
63
63
|
return None;
|
64
64
|
}
|
65
65
|
|
66
|
-
//
|
67
|
-
|
68
|
-
|
69
|
-
let names_end = remainder.find('[')?;
|
70
|
-
|
71
|
-
// Save the rest of the slice to parse for labels later.
|
72
|
-
let label_json = remainder.get(names_end..)?;
|
73
|
-
|
74
|
-
// Now: family_name","metric_name",
|
75
|
-
let remainder = remainder.get(..names_end)?;
|
66
|
+
// Captured: "family_name","metric_name",
|
67
|
+
// ^^^^^^^^^^^
|
68
|
+
let (family_name, remainder) = scan_str(json.get(1..)?)?;
|
76
69
|
|
77
|
-
//
|
78
|
-
// family_name","metric_name",
|
79
|
-
//
|
80
|
-
|
70
|
+
// Validate comma separated names
|
71
|
+
// ["family_name","metric_name",[...
|
72
|
+
// ^
|
73
|
+
if !remainder.starts_with("\",") {
|
74
|
+
return None;
|
75
|
+
}
|
81
76
|
|
82
|
-
//
|
83
|
-
|
84
|
-
let family_name = token_iter.next()?.trim_end_matches('"');
|
77
|
+
// Now: "metric_name",[...
|
78
|
+
let remainder = remainder.get(2..)?;
|
85
79
|
|
86
80
|
// Captured: "family_name","metric_name",
|
87
81
|
// ^^^^^^^^^^^
|
88
|
-
let metric_name =
|
82
|
+
let (metric_name, remainder) = scan_str(remainder)?;
|
89
83
|
|
90
|
-
//
|
91
|
-
|
84
|
+
// Validate comma separated names
|
85
|
+
// ["family_name","metric_name",[...
|
86
|
+
// ^^
|
87
|
+
if !remainder.starts_with("\",") {
|
92
88
|
return None;
|
93
89
|
}
|
94
90
|
|
91
|
+
// Save the rest of the slice to parse for labels later.
|
92
|
+
// Now: [...
|
93
|
+
let label_json = remainder.get(2..)?;
|
94
|
+
|
95
95
|
Some(MetricNames {
|
96
96
|
label_json,
|
97
97
|
family_name,
|
@@ -101,76 +101,143 @@ fn parse_names(json: &str) -> Option<MetricNames> {
|
|
101
101
|
|
102
102
|
fn parse_label_values(json: &str) -> Option<MetricLabelVals> {
|
103
103
|
// Starting with: ["label_a","label_b"],["value_a", "value_b"]]
|
104
|
-
if !
|
104
|
+
if !json.starts_with('[') {
|
105
105
|
return None;
|
106
106
|
}
|
107
107
|
|
108
|
+
// Now: "label_a","label_b"],["value_a", "value_b"]]
|
109
|
+
let mut remainder = json.get(1..)?;
|
110
|
+
|
108
111
|
// Validate we either have the start of a label string or an
|
109
112
|
// empty array, e.g. `["` or `[]`.
|
110
113
|
if !matches!(json.as_bytes().get(1)?, b'"' | b']') {
|
111
114
|
return None;
|
112
115
|
}
|
113
116
|
|
114
|
-
// Now: "label_a","label_b"
|
115
|
-
let labels_end = json.find(']')?;
|
116
|
-
let label_range = json.get(1..labels_end)?;
|
117
|
-
|
118
117
|
let mut labels = SmallVec::new();
|
119
118
|
|
120
119
|
// Split on commas into:
|
121
120
|
// "label_a","label_b"
|
122
121
|
// ^^^one^^^ ^^^two^^^
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
122
|
+
loop {
|
123
|
+
let Some((label, label_rem)) = scan_str(remainder) else {
|
124
|
+
// No further keys.
|
125
|
+
break;
|
126
|
+
};
|
127
|
+
labels.push(label);
|
128
|
+
|
129
|
+
// Advance past trailing quote.
|
130
|
+
remainder = label_rem.get(1..)?;
|
131
|
+
match remainder.as_bytes().first() {
|
132
|
+
Some(b']') => break, // No further labels.
|
133
|
+
Some(b',') => {} // More labels expected.
|
134
|
+
_ => return None, // Invalid.
|
135
|
+
};
|
136
|
+
|
137
|
+
// Advance past comma.
|
138
|
+
remainder = remainder.get(1..)?;
|
130
139
|
}
|
131
140
|
|
132
|
-
|
133
|
-
let mut values_range = json.get(labels_end..)?;
|
134
|
-
|
135
|
-
// Validate we have a separating comma with one and only one leading bracket.
|
136
|
-
if !(values_range.starts_with("],[") && values_range.as_bytes().get(3)? != &b'[') {
|
141
|
+
if !remainder.starts_with("],[") {
|
137
142
|
return None;
|
138
143
|
}
|
139
|
-
|
140
144
|
// Now: "value_a", "value_b"]]
|
141
|
-
|
142
|
-
|
143
|
-
let values_end = values_range.find(']')?;
|
145
|
+
remainder = remainder.get(3..)?;
|
144
146
|
|
145
|
-
// Validate we have
|
146
|
-
if
|
147
|
+
// Validate we don't have extra brackets.
|
148
|
+
if remainder.starts_with('[') {
|
147
149
|
return None;
|
148
150
|
}
|
149
151
|
|
150
|
-
// Now: "value_a", "value_b"
|
151
|
-
values_range = values_range.get(..values_end)?;
|
152
|
-
|
153
152
|
let mut values = SmallVec::new();
|
154
|
-
|
155
153
|
// Split on commas into:
|
156
154
|
// "value_a","value_b"
|
157
155
|
// ^^^one^^^ ^^^two^^^
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
156
|
+
loop {
|
157
|
+
if remainder.starts_with('"') {
|
158
|
+
let (value, value_rem) = scan_str(remainder)?;
|
159
|
+
values.push(value);
|
160
|
+
|
161
|
+
// Advance past trailing quote.
|
162
|
+
remainder = value_rem.get(1..)?;
|
163
|
+
} else {
|
164
|
+
// An unquoted value, such as `true` or `404`.
|
165
|
+
let i = remainder.find(|c| c == ',' || c == ']')?;
|
166
|
+
let value = &remainder[..i];
|
167
|
+
|
168
|
+
match (value.is_empty(), is_valid_json_literal(value)) {
|
169
|
+
(true, _) => {} // Empty string, do nothing.
|
170
|
+
(false, true) => values.push(value), // Valid literal.
|
171
|
+
(false, false) => return None, // Invalid literal, fail.
|
172
|
+
}
|
173
|
+
|
174
|
+
remainder = &remainder[i..];
|
164
175
|
}
|
176
|
+
|
177
|
+
match remainder.as_bytes().first() {
|
178
|
+
Some(b']') => break, // End of values.
|
179
|
+
Some(b',') => {} // More values expected.
|
180
|
+
_ => return None, // Invalid.
|
181
|
+
};
|
182
|
+
|
183
|
+
// Advance past comma.
|
184
|
+
remainder = remainder.get(1..)?;
|
165
185
|
}
|
166
186
|
|
167
187
|
if values.len() != labels.len() {
|
168
188
|
return None;
|
169
189
|
}
|
170
190
|
|
191
|
+
// Now: ]]
|
192
|
+
if remainder != "]]" {
|
193
|
+
return None;
|
194
|
+
}
|
195
|
+
|
171
196
|
Some(MetricLabelVals { labels, values })
|
172
197
|
}
|
173
198
|
|
199
|
+
// Read a JSON-encoded str that includes starting and ending double quotes.
|
200
|
+
// Returns the validated str with the double quotes trimmed and the remainder
|
201
|
+
// of the input str.
|
202
|
+
fn scan_str(json: &str) -> Option<(&str, &str)> {
|
203
|
+
let mut escaping = false;
|
204
|
+
|
205
|
+
if !json.starts_with('"') {
|
206
|
+
return None;
|
207
|
+
}
|
208
|
+
|
209
|
+
// Trim leading double quote.
|
210
|
+
let json = json.get(1..)?;
|
211
|
+
|
212
|
+
for (i, &c) in json.as_bytes().iter().enumerate() {
|
213
|
+
if c == b'\\' {
|
214
|
+
escaping = true;
|
215
|
+
continue;
|
216
|
+
}
|
217
|
+
|
218
|
+
if c == b'"' && !escaping {
|
219
|
+
return Some((json.get(..i)?, json.get(i..)?));
|
220
|
+
}
|
221
|
+
|
222
|
+
escaping = false;
|
223
|
+
}
|
224
|
+
|
225
|
+
None
|
226
|
+
}
|
227
|
+
|
228
|
+
// Confirm an unquoted JSON literal is a boolean, null, or has a passing
|
229
|
+
// resemblance to a number. We do not confirm numeric formatting, only
|
230
|
+
// that all characters are valid. See https://www.json.org/json-en.html
|
231
|
+
// for details.
|
232
|
+
fn is_valid_json_literal(s: &str) -> bool {
|
233
|
+
match s {
|
234
|
+
"true" | "false" | "null" => true,
|
235
|
+
_ => s.chars().all(|c| {
|
236
|
+
c.is_ascii_digit() || c == '.' || c == '+' || c == '-' || c == 'e' || c == 'E'
|
237
|
+
}),
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
174
241
|
#[cfg(test)]
|
175
242
|
mod test {
|
176
243
|
use smallvec::smallvec;
|
@@ -217,6 +284,16 @@ mod test {
|
|
217
284
|
values: smallvec!["value_a", "403"],
|
218
285
|
}),
|
219
286
|
},
|
287
|
+
TestCase {
|
288
|
+
name: "scientific notation literal",
|
289
|
+
input: r#"["metric","name",["label_a"],[-2.0e-5]]"#,
|
290
|
+
expected: Some(MetricText {
|
291
|
+
family_name: "metric",
|
292
|
+
metric_name: "name",
|
293
|
+
labels: smallvec!["label_a"],
|
294
|
+
values: smallvec!["-2.0e-5"],
|
295
|
+
}),
|
296
|
+
},
|
220
297
|
TestCase {
|
221
298
|
name: "null value",
|
222
299
|
input: r#"["metric","name",["label_a","label_b"],[null,"value_b"]]"#,
|
@@ -237,6 +314,36 @@ mod test {
|
|
237
314
|
values: smallvec![],
|
238
315
|
}),
|
239
316
|
},
|
317
|
+
TestCase {
|
318
|
+
name: "comma in items",
|
319
|
+
input: r#"["met,ric","na,me",["label,_a","label_b"],["value,_a","value_b"]]"#,
|
320
|
+
expected: Some(MetricText {
|
321
|
+
family_name: "met,ric",
|
322
|
+
metric_name: "na,me",
|
323
|
+
labels: smallvec!["label,_a", "label_b"],
|
324
|
+
values: smallvec!["value,_a", "value_b"],
|
325
|
+
}),
|
326
|
+
},
|
327
|
+
TestCase {
|
328
|
+
name: "bracket in value",
|
329
|
+
input: r#"["met[r]ic","na[m]e",["label[_]a","label_b"],["value_a","val[ue]_b"]]"#,
|
330
|
+
expected: Some(MetricText {
|
331
|
+
family_name: "met[r]ic",
|
332
|
+
metric_name: "na[m]e",
|
333
|
+
labels: smallvec!["label[_]a", "label_b"],
|
334
|
+
values: smallvec!["value_a", "val[ue]_b"],
|
335
|
+
}),
|
336
|
+
},
|
337
|
+
TestCase {
|
338
|
+
name: "escaped quotes",
|
339
|
+
input: r#"["met\"ric","na\"me",["label\"_a","label_b"],["value\"_a","value_b"]]"#,
|
340
|
+
expected: Some(MetricText {
|
341
|
+
family_name: r#"met\"ric"#,
|
342
|
+
metric_name: r#"na\"me"#,
|
343
|
+
labels: smallvec![r#"label\"_a"#, "label_b"],
|
344
|
+
values: smallvec![r#"value\"_a"#, "value_b"],
|
345
|
+
}),
|
346
|
+
},
|
240
347
|
];
|
241
348
|
|
242
349
|
for case in tc {
|
@@ -313,23 +420,18 @@ mod test {
|
|
313
420
|
expected: None,
|
314
421
|
},
|
315
422
|
TestCase {
|
316
|
-
name: "
|
317
|
-
input: r#"["
|
318
|
-
expected: None,
|
319
|
-
},
|
320
|
-
TestCase {
|
321
|
-
name: "comma in metric name",
|
322
|
-
input: r#"["metric","na,me",["label_a","label_b"],["value_a","value_b"]]"#,
|
423
|
+
name: "misplaced bracket",
|
424
|
+
input: r#"["metric","name",["label_a","label_b"],]["value_a","value_b"]]"#,
|
323
425
|
expected: None,
|
324
426
|
},
|
325
427
|
TestCase {
|
326
|
-
name: "comma in value",
|
327
|
-
input: r#"["metric","
|
428
|
+
name: "comma in numeric value",
|
429
|
+
input: r#"["metric","name",["label_a","label_b"],[400,0,"value_b"]]"#,
|
328
430
|
expected: None,
|
329
431
|
},
|
330
432
|
TestCase {
|
331
|
-
name: "
|
332
|
-
input: r#"["metric","name",["label_a","label_b"],[
|
433
|
+
name: "non-e letter in numeric value",
|
434
|
+
input: r#"["metric","name",["label_a","label_b"],[400x0,"value_b"]]"#,
|
333
435
|
expected: None,
|
334
436
|
},
|
335
437
|
];
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prometheus-client-mmap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.24.
|
4
|
+
version: 0.24.4
|
5
5
|
platform: aarch64-linux
|
6
6
|
authors:
|
7
7
|
- Tobias Schmidt
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2023-
|
14
|
+
date: 2023-06-12 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rb_sys
|