Skip to content

Commit 70e4bc7

Browse files
GuillaumeLagrangeart049
authored andcommitted
feat(core): escape double colons in type URI bench arguments
1 parent e23214a commit 70e4bc7

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

core/include/codspeed.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,6 @@ void generate_codspeed_walltime_report(
4242
const std::vector<RawWalltimeBenchmark> &walltime_data_list);
4343

4444
std::string extract_lambda_namespace(const std::string &pretty_func);
45+
std::string sanitize_bench_args(std::string &text);
4546

4647
#endif // CODSPEED_H

core/src/codspeed.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,35 @@
44
#include <string>
55
#include <vector>
66

7+
// Remove any `::` between brackets at the end to not mess with the URI
8+
// parsing
9+
// FIXME: Remove this bandaid when we migrate to structured benchmark metadata
10+
std::string sanitize_bench_args(std::string &text) {
11+
std::string search = "::";
12+
std::string replace = "\\:\\:";
13+
14+
if (text.back() == ']') {
15+
size_t pos_open = text.rfind('[');
16+
if (pos_open != std::string::npos) {
17+
// Extract the substring between '[' and ']'
18+
size_t pos_close = text.size() - 1;
19+
std::string substring =
20+
text.substr(pos_open + 1, pos_close - pos_open - 1);
21+
22+
// Perform the search and replace within the substring
23+
size_t pos = substring.find(search);
24+
while (pos != std::string::npos) {
25+
substring.replace(pos, search.length(), replace);
26+
pos = substring.find(search, pos + replace.length());
27+
}
28+
29+
// Replace the original substring with the modified one
30+
text.replace(pos_open + 1, pos_close - pos_open - 1, substring);
31+
}
32+
}
33+
return text;
34+
}
35+
736
std::string join(const std::vector<std::string> &elements,
837
const std::string &delimiter) {
938
std::string result;
@@ -40,6 +69,8 @@ void CodSpeed::pop_group() {
4069
void CodSpeed::start_benchmark(const std::string &name) {
4170
std::string uri = name;
4271

72+
uri = sanitize_bench_args(uri);
73+
4374
// Sanity check URI and add a placeholder if format is wrong
4475
if (name.find("::") == std::string::npos) {
4576
std::string uri = "unknown_file::" + name;

core/src/walltime.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ void compute_iqr_and_outliers(const std::vector<double> &times_ns, double mean,
8787
});
8888
}
8989

90+
std::string escapeBackslashes(const std::string &input) {
91+
std::string output;
92+
for (char c : input) {
93+
if (c == '\\') {
94+
output += "\\\\";
95+
} else {
96+
output += c;
97+
}
98+
}
99+
return output;
100+
}
101+
90102
void write_codspeed_benchmarks_to_json(
91103
const std::vector<CodspeedWalltimeBenchmark> &benchmarks) {
92104
std::ostringstream oss;
@@ -113,8 +125,8 @@ void write_codspeed_benchmarks_to_json(
113125
const auto &metadata = benchmark.metadata;
114126

115127
oss << " {\n";
116-
oss << " \"name\": \"" << metadata.name << "\",\n";
117-
oss << " \"uri\": \"" << metadata.uri << "\",\n";
128+
oss << " \"name\": \"" << escapeBackslashes(metadata.name) << "\",\n";
129+
oss << " \"uri\": \"" << escapeBackslashes(metadata.uri) << "\",\n";
118130
// TODO: Manage config fields from actual configuration
119131
oss << " \"config\": {\n";
120132
oss << " \"warmup_time_ns\": null,\n";

google_benchmark/src/benchmark.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,8 @@ RawWalltimeBenchmark generate_raw_walltime_data(const RunResults& run_results) {
357357

358358
for (const auto& run : run_results.non_aggregates) {
359359
walltime_data.uri = run.benchmark_name();
360+
walltime_data.uri = sanitize_bench_args(walltime_data.uri);
361+
360362
size_t pos = walltime_data.uri.rfind("::");
361363

362364
if (pos != std::string::npos) {

0 commit comments

Comments
 (0)