Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in dump() with int64_t minimum value #1708

Closed
maddy-longo opened this issue Aug 14, 2019 · 1 comment · Fixed by #1722
Closed

Error in dump() with int64_t minimum value #1708

maddy-longo opened this issue Aug 14, 2019 · 1 comment · Fixed by #1722
Assignees
Labels
kind: bug release item: 🐛 bug fix solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Milestone

Comments

@maddy-longo
Copy link

What is the issue you have?

There is a segfault when calling dump() on an nlohmann::json node containing an int64_t value set to std::numeric_limits<int64_t>::min(). Any other int64_t value (for example, the minimum value + 1, or the maximum value) seems to work fine. Other int or double values (uint64_t, for example) also seem to have no issues.

Please describe the steps to reproduce the issue. Can you provide a small but working code example?

For this example, the the entire nlohmann JSON repo is included in the folder json.
main.cpp:

#include <stdio.h>
#include <string>
#include <limits>

#include "json/single_include/nlohmann/json.hpp"

int main(int argc, char *argv[])
{
    nlohmann::json node_integer_limits = {{"int64_min", std::numeric_limits<int64_t>::min()}};

    std::string test_comp1 = std::to_string(std::numeric_limits<int64_t>::min());
    std::string test_comp2 = node_integer_limits["int64_min"].dump();
    printf("String difference: %d\n", test_comp1.compare(test_comp2));
    std::string test_node = node_integer_limits.dump();

    printf("Finished!\n");
}

Makefile:

OBJECTS = main.o

CPPFLAGS := -std=gnu++14 -O2 -g

$(OBJECTS): CPPFLAGS := $(CPPFLAGS)

tests: $(OBJECTS)
    g++ $(CPPFLAGS) -o tests $(OBJECTS)

main.o: main.cpp json/single_include/nlohmann/json.hpp
    g++ $(CPPFLAGS) -c main.cpp

.PHONY: clean
clean:
    rm -rf tests $(OBJECTS)

What is the expected behavior?

Calling dump() returns a string version of the value.

And what is the actual behavior instead?

See above. The error code is:

Segmentation fault (core dumped)

In gdb:

(gdb) run
Starting program: /<full path removed>/tests

Program received signal SIGSEGV, Segmentation fault.
nlohmann::detail::serializer<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::dump_integer<unsigned long, 0> (
    x=<optimized out>, this=<optimized out>) at json/single_include/nlohmann/json.hpp:14306
14306           o->write_characters(number_buffer.data(), n_chars);
(gdb) bt
#0  nlohmann::detail::serializer<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::dump_integer<unsigned long, 0> (
    x=<optimized out>, this=<optimized out>) at json/single_include/nlohmann/json.hpp:14306
#1  nlohmann::detail::serializer<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::dump (
    this=this@entry=0x7fffffffde40, val=..., pretty_print=pretty_print@entry=false, ensure_ascii=<optimized out>, indent_step=indent_step@entry=0, current_indent=<optimized out>) at json/single_include/nlohmann/json.hpp:13894
#2  0x0000000000407c14 in nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer>::dump (this=0x61fd20,
    indent=indent@entry=-1, indent_char=indent_char@entry=32 ' ', ensure_ascii=ensure_ascii@entry=false, error_handler=error_handler@entry=nlohmann::detail::error_handler_t::strict) at json/single_include/nlohmann/json.hpp:16390
#3  0x000000000040188f in main (argc=<optimized out>, argv=<optimized out>) at main.cpp:12

The expected output is:

String difference: 0
Finished!

Which compiler and operating system are you using? Is it a supported compiler?

All of this is on the same Ubuntu 16.04 machine. The issue occurs when compiling g++-5 ((Ubuntu 5.5.0-12ubuntu1~16.04) 5.5.0 20171010) for C++11, C++14, or C++17. The issue only occurs when compiling with -O2 or higher. Both g++-6 ((Ubuntu 6.5.0-2ubuntu1~16.04) 6.5.0 20181026) and g++-7 ((Ubuntu 7.4.0-1ubuntu1~16.04~ppa1) 7.4.0) compile and run with no issues across all optimization levels.

Did you use a released version of the library or the version from the develop branch?

Tried with the develop branch as well as versions 3.6.1 and 3.7.0. The behavior was the same in all cases.

If you experience a compilation error: can you compile and run the unit tests?

There were no compilation errors. All tests passed.

Notes

The issue might be caused by line 14267 of json.hpp on the develop branch (https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp#L14267).

@nlohmann
Copy link
Owner

Oh dear...

I'll have a look.

@nlohmann nlohmann added release item: 🐛 bug fix solution: proposed fix a fix for the issue has been proposed and waits for confirmation labels Sep 10, 2019
@nlohmann nlohmann added this to the Release 3.7.1 milestone Sep 10, 2019
@nlohmann nlohmann self-assigned this Sep 10, 2019
dnsmichi pushed a commit to Icinga/icinga2 that referenced this issue Dec 13, 2019
This includes the following fixes:

nlohmann/json#1436

> For a deeply-nested JSON object, the recursive implementation of json_value::destroy function causes stack overflow.

nlohmann/json#1708
nlohmann/json#1722

Stack size

nlohmann/json#1693 (comment)

Integer Overflow

nlohmann/json#1447

UTF8, json dump out of bounds

nlohmann/json#1445

Possibly influences #7532
Al2Klimov pushed a commit to Icinga/icinga2 that referenced this issue Dec 16, 2019
This includes the following fixes:

nlohmann/json#1436

> For a deeply-nested JSON object, the recursive implementation of json_value::destroy function causes stack overflow.

nlohmann/json#1708
nlohmann/json#1722

Stack size

nlohmann/json#1693 (comment)

Integer Overflow

nlohmann/json#1447

UTF8, json dump out of bounds

nlohmann/json#1445

Possibly influences #7532
N-o-X pushed a commit to Icinga/icinga2 that referenced this issue May 8, 2020
This includes the following fixes:

nlohmann/json#1436

> For a deeply-nested JSON object, the recursive implementation of json_value::destroy function causes stack overflow.

nlohmann/json#1708
nlohmann/json#1722

Stack size

nlohmann/json#1693 (comment)

Integer Overflow

nlohmann/json#1447

UTF8, json dump out of bounds

nlohmann/json#1445

Possibly influences #7532
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug release item: 🐛 bug fix solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants