nlohmann/json

Unexpected Integer Conversion of JSON Values on ARM64

Dontla opened this issue · 1 comments

Description

I encountered an issue with the nlohmann/json library where integer values parsed from a JSON object are not correctly converted when using the get(), get(), and get() methods on ARM64 architecture. This behavior results in incorrect data retrieval from a JSON object that otherwise appears to contain the correct values when outputted as raw JSON or accessed directly without type conversion. This issue may represent a bug in type handling or integer conversion specific to ARM64 environments.

Reproduction steps

  1. Parse a JSON object containing an integer value using nlohmann/json.
  2. Retrieve the integer using get(), get(), and get().
  3. Print the retrieved values to the console.

My raw json:

{
  "config": {
    "port": "/dev/ttyTHS0",
    "baudRate": 9600,
    "deviceAddress": 1,
    "deviceType": "AlarmCircuitMaster",
    "controlType": "start"
  },
  "commands": {
    "alarmType": "yellow"
  }
}

My C++ code:

` std::cout << "Received JSON for POST request: " << std::endl;

        std::cout << j.dump(4) << std::endl;

        std::cout << "Is baudRate a number? " << j["config"]["baudRate"].is_number() << std::endl;

        std::cout << "baudRate as int: " << j.at("config").at("baudRate").get<int>() << std::endl;
        std::cout << "baudRate as int: " << j["config"]["baudRate"].get<int>() << std::endl;

        std::cout << "baudRate as long: " << j["config"]["baudRate"].get<long>() << std::endl;
        std::cout << "baudRate as long: " << j.at("config").at("baudRate").get<long>() << std::endl;

        std::cout << "baudRate as unsigned int: " << j["config"]["baudRate"].get<unsigned int>() << std::endl;
        std::cout << "baudRate as unsigned int: " << j.at("config").at("baudRate").get<unsigned int>() << std::endl;

        std::cout << "Raw baudRate value: " << j["config"]["baudRate"] << std::endl;
        std::cout << "baw baudRate value: " << j.at("config").at("baudRate") << std::endl;

`

Expected vs. actual results

Expected: The integer values retrieved from the JSON object should match the values present in the JSON.
Actual: The retrieved values are consistently incorrect (e.g., expecting 9600 but receiving 2580) despite the JSON object showing correct values when printed directly.

Expected results:

Received JSON for POST request:
{
    "commands": {
        "alarmType": "yellow"
    },
    "config": {
        "baudRate": 9600,
        "controlType": "start",
        "deviceAddress": 1,
        "deviceType": "AlarmCircuitMaster",
        "port": "/dev/ttyTHS0"
    }
}
Is baudRate a number? 1
baudRate as int: 9600
baudRate as int: 9600
baudRate as long: 9600
baudRate as long: 9600
baudRate as unsigned int: 9600
baudRate as unsigned int: 9600
Raw baudRate value: 9600
baw baudRate value: 9600

Actual results:

Received JSON for POST request:
{
    "commands": {
        "alarmType": "yellow"
    },
    "config": {
        "baudRate": 9600,
        "controlType": "start",
        "deviceAddress": 1,
        "deviceType": "AlarmCircuitMaster",
        "port": "/dev/ttyTHS0"
    }
}
Is baudRate a number? 1
baudRate as int: 2580
baudRate as int: 2580
baudRate as long: 2580
baudRate as long: 2580
baudRate as unsigned int: 2580
baudRate as unsigned int: 2580
Raw baudRate value: 9600
baw baudRate value: 9600

Minimal code example

#include <iostream>
#include <nlohmann/json.hpp>

int main() {
    std::string jsonData = R"({"config": {"baudRate": 9600}})";
    auto json = nlohmann::json::parse(jsonData);
    std::cout << "Expected Baud Rate: 9600" << std::endl;
    std::cout << "Actual Baud Rate as int: " << json["config"]["baudRate"].get<int>() << std::endl;
    return 0;
}

Error messages

No compilation errors or exceptions are thrown. The output is incorrect as described in the "Actual Results".

Compiler and operating system

OS: Ubuntu 20.04 ARM64, Compiler: g++9.4.0

Library version

Version 3.11.3 of the nlohmann/json library, obtained directly from the GitHub repository.

Validation

I found the problem; it was in my C++ code. The code executed std::cout << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << static_cast<int>(tbuf[i]) << " ";, which set the global std::cout output to hexadecimal format. That's why the baud rate of 9600 was printed as 2580.