Skip to content

Commit dc5ff0d

Browse files
committed
web: harden saveReport with early file check, escaping, and encoding
- Open output file before expensive rendering to fail fast on bad paths - Escape tile cache keys with json_escape() for valid JavaScript output - Specify encoding='utf-8' in embed_report_assets.py for portability Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
1 parent a63f34d commit dc5ff0d

2 files changed

Lines changed: 10 additions & 10 deletions

File tree

src/web/src/embed_report_assets.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,17 @@ def main():
104104
# Read and process JS files.
105105
js_parts = []
106106
for path in args.js:
107-
with open(path) as f:
107+
with open(path, encoding="utf-8") as f:
108108
content = f.read()
109109
js_parts.append(f'// ── {path.split("/")[-1]} ──')
110110
js_parts.append(process_js_file(content))
111111
combined_js = "\n".join(js_parts)
112112

113113
# Read CSS.
114-
with open(args.css) as f:
114+
with open(args.css, encoding="utf-8") as f:
115115
css_content = f.read()
116116

117-
with open(args.output, "w") as out:
117+
with open(args.output, "w", encoding="utf-8") as out:
118118
out.write("// Auto-generated — do not edit.\n")
119119
out.write("#include <string_view>\n")
120120
out.write("namespace web {\n")

src/web/src/web.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,12 @@ void WebServer::saveReport(const std::string& filename,
10501050
return;
10511051
}
10521052

1053+
std::ofstream out(filename);
1054+
if (!out) {
1055+
logger_->error(utl::WEB, 31, "Cannot open file: {}", filename);
1056+
return;
1057+
}
1058+
10531059
// ── Serialize JSON cache responses ──
10541060

10551061
std::string setup_json, hold_json, hist_setup, hist_hold, filters;
@@ -1156,12 +1162,6 @@ void WebServer::saveReport(const std::string& filename,
11561162

11571163
// ── Write the HTML ──
11581164

1159-
std::ofstream out(filename);
1160-
if (!out) {
1161-
logger_->error(utl::WEB, 31, "Cannot open file: {}", filename);
1162-
return;
1163-
}
1164-
11651165
// HTML head — same CDN deps as index.html.
11661166
out << R"(<!DOCTYPE html>
11671167
<html>
@@ -1216,7 +1216,7 @@ window.__STATIC_CACHE__ = {
12161216
if (i > 0) {
12171217
out << ",";
12181218
}
1219-
out << "\n \"" << tile_entries[i].first << "\":\""
1219+
out << "\n \"" << json_escape(tile_entries[i].first) << "\":\""
12201220
<< tile_entries[i].second << "\"";
12211221
}
12221222

0 commit comments

Comments
 (0)