An experiment to disambiguate "\x" in JSON output.

This commit is contained in:
Christian Kreibich 2025-09-11 14:11:57 -07:00
parent c6cf1ee3ae
commit 74772128ac
3 changed files with 24 additions and 4 deletions

View file

@ -35,7 +35,10 @@ bool JSON::Describe(ODesc* desc, int num_fields, const Field* const* fields, Val
}
writer.EndObject();
desc->Add(buffer.GetString());
std::string json{buffer.GetString()};
Finalize(json);
desc->Add(std::move(json));
return true;
}
@ -57,10 +60,25 @@ bool JSON::Describe(ODesc* desc, Value* val, const std::string& name) const {
BuildJSON(writer, val, name);
writer.EndObject();
desc->Add(buffer.GetString());
std::string json{buffer.GetString()};
Finalize(json);
desc->Add(std::move(json));
return true;
}
void JSON::Finalize(std::string& json) const {
// Replace all occurrences of the "\x" marker we may have inserted during
// escaping of the JSON input string with the backslash unicode codepoint.
static std::string pattern{"[zeek\\\\u005C]"};
size_t pos = 0;
while ( (pos = json.find(pattern, pos)) != std::string::npos ) {
json.replace(pos, pattern.length(), "\\u005C");
pos += pattern.length();
}
}
Value* JSON::ParseValue(const std::string& s, const std::string& name, TypeTag type, TypeTag subtype) const {
GetThread()->Error("JSON formatter does not support parsing yet.");
return nullptr;

View file

@ -36,6 +36,7 @@ public:
private:
void BuildJSON(zeek::json::detail::NullDoubleWriter& writer, Value* val, const std::string& name = "") const;
void Finalize(std::string& json) const;
TimeFormat timestamps;
bool include_unset_fields;

View file

@ -2242,8 +2242,9 @@ void zeek_strerror_r(int zeek_errno, char* buf, size_t buflen) {
static string json_escape_byte(char c) {
char hex[2] = {'0', '0'};
bytetohex(c, hex);
string result = "\\x";
// Hack: put in place a "marker" that survives JSON-encoding,
// that we can then substitute in the resulting JSON.
string result = "[zeek\\u005C]x";
result.append(hex, 2);
return result;