Skip to content

Embedded nulls dropped from JSON strings #559

@DRMacIver

Description

@DRMacIver

When parsing JSON strings with embedded null characters, reflect-cpp's JSON parser seems to drop the string from the null onwards. Here's an example extracted from a version of running into this in the wild:

#include <iostream>
#include <string>
#include <optional>
#include <rfl.hpp>
#include <rfl/json.hpp>

struct Response {
    std::optional<std::string> result;
};

int main() {
    // JSON with a string containing an escaped null byte: "00\u0000"
    // This should parse to a 3-character string: '0', '0', '\0'
    std::string json = R"({"result": "00\u0000"})";
    
    std::cout << "Input JSON: " << json << "\n";
    std::cout << "Expected result length: 3 (two '0' chars + null byte)\n\n";
    
    auto parse_result = rfl::json::read<Response>(json);
    
    if (!parse_result) {
        std::cerr << "Parse error: " << parse_result.error().what() << "\n";
        return 1;
    }
    
    const Response& response = parse_result.value();
    
    if (!response.result) {
        std::cerr << "Result is nullopt\n";
        return 1;
    }
    
    const std::string& value = *response.result;
    
    std::cout << "Parsed string length: " << value.size() << "\n";
    std::cout << "Parsed string bytes: ";
    for (unsigned char c : value) {
        std::cout << static_cast<int>(c) << " ";
    }
    std::cout << "\n\n";
    
    if (value.size() == 3) {
        std::cout << "PASS: String length is correct\n";
        return 0;
    } else {
        std::cout << "FAIL: String was truncated at null byte!\n";
        std::cout << "      Expected 3 bytes, got " << value.size() << "\n";
        return 1;
    }
}

When compiled with g++ against reflect-cpp 0.22.0, I get the following output:

Input JSON: {"result": "00\u0000"}
Expected result length: 3 (two '0' chars + null byte)

Parsed string length: 2
Parsed string bytes: 48 48 

FAIL: String was truncated at null byte!
      Expected 3 bytes, got 2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions