chadaustin / sajson

Lightweight, extremely high-performance JSON parser for C++11
MIT License
562 stars 42 forks source link

Signed integer overflow in parse_number() #37

Closed grievejia closed 6 years ago

grievejia commented 6 years ago

Here's the input that will trigger the issue: int_overflow.txt Feed it into master(cbd7a20) parse() function built with UndefinedBehaviorSanitizer will crash the parser:

> ./parse int_overflow.txt
sajson.h:2105:30: runtime error: signed integer overflow: 10 * 999999006 cannot be represented in type 'int'
    #0 0x520ccb in sajson::parser<sajson::dynamic_allocation::allocator>::parse_number(char*) /home/grieve/scratch/sajson/./sajson.h:2105:30
    #1 0x518953 in sajson::parser<sajson::dynamic_allocation::allocator>::parse() /home/grieve/scratch/sajson/./sajson.h:1806:39
    #2 0x5156a6 in sajson::parser<sajson::dynamic_allocation::allocator>::get_document() /home/grieve/scratch/sajson/./sajson.h:1529:17
    #3 0x513ae5 in sajson::document sajson::parse<sajson::dynamic_allocation, sajson::mutable_string_view>(sajson::dynamic_allocation const&, sajson::mutable_string_view const&) /home/grieve/scratch/sajson/./sajson.h:2467:11
    #4 0x5130d9 in main /home/grieve/scratch/sajson/parse.cpp:24:23
    #5 0x7fcc1b4b44c9 in __libc_start_main (/usr/lib/libc.so.6+0x204c9)
    #6 0x419d59 in _start (/home/grieve/scratch/sajson/parse+0x419d59)

Here is the full source list of parse.cpp I used in the aforementioned testing:

#include "sajson.h"
#include <cstring>
#include <utility>
#include <fstream>
#include <istream>

using namespace sajson;

std::pair<char*, std::size_t> readBytes(const char* filename) {
  std::ifstream ifs(filename, std::ios::binary|std::ios::ate);
  auto pos = ifs.tellg();
  std::size_t len = pos;

  char* buf = new char[len];
  ifs.seekg(0, std::ios::beg);
  ifs.read(buf, len);
  ifs.close();
  return std::make_pair(buf, len);
}

int main(int argc, char** argv) {
  if (argc > 1) {
    auto res = readBytes(argv[1]);
    auto const& doc = parse(dynamic_allocation(), mutable_string_view(res.second, res.first));
    delete[] res.first;
  }
}
chadaustin commented 6 years ago

Thank you! Good find. I've been pretty busy but I'll try to fix it soon.

chadaustin commented 6 years ago

Sorry for this taking a while. Fixed in 8e8932148a2e4dcd1209a0438ec84acedf165077