From e8ce6767b14704acf54b3f567b301bfbe46b3dc8 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 4 Jul 2016 14:59:50 +0200 Subject: [PATCH] fix double precision loss in VelocyPack parser --- 3rdParty/velocypack/src/Parser.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/3rdParty/velocypack/src/Parser.cpp b/3rdParty/velocypack/src/Parser.cpp index 9574b92490..1b11060341 100644 --- a/3rdParty/velocypack/src/Parser.cpp +++ b/3rdParty/velocypack/src/Parser.cpp @@ -28,6 +28,8 @@ #include "velocypack/Parser.h" #include "asm-functions.h" +#include + using namespace arangodb::velocypack; // The following function does the actual parse. It gets bytes @@ -121,6 +123,7 @@ int Parser::skipWhiteSpace(char const* err) { // parses a number value void Parser::parseNumber() { + size_t startPos = _pos; ParsedNumber numberValue; bool negative = false; int i = consume(); @@ -191,7 +194,10 @@ void Parser::parseNumber() { } if (i != 'e' && i != 'E') { unconsume(); - _b->addDouble(fractionalPart); + // use conventional atof() conversion here, to avoid precision loss + // when interpreting and multiplying the single digits of the input stream + // _b->addDouble(fractionalPart); + _b->addDouble(atof(reinterpret_cast(_start) + startPos)); return; } i = getOneOrThrow("Incomplete number"); @@ -214,7 +220,10 @@ void Parser::parseNumber() { if (std::isnan(fractionalPart) || !std::isfinite(fractionalPart)) { throw Exception(Exception::NumberOutOfRange); } - _b->addDouble(fractionalPart); + // use conventional atof() conversion here, to avoid precision loss + // when interpreting and multiplying the single digits of the input stream + // _b->addDouble(fractionalPart); + _b->addDouble(atof(reinterpret_cast(_start) + startPos)); } void Parser::parseString() {