From 93df5697a04e406929d7a3fa1f17904d2859e36d Mon Sep 17 00:00:00 2001
From: Wouter van Oortmerssen <wvo@google.com>
Date: Thu, 10 Jul 2014 13:40:55 -0700
Subject: [PATCH] Parser now correctly reads floats in scientific notation.

Change-Id: I7abb14a4b6c596674d6aff2b9de6e63603c0d2dc
Tested: on Windows and Linux.
---
 src/idl_parser.cpp |  7 +++++++
 tests/test.cpp     | 16 ++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index 47e44c8b..4a372b8e 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -200,6 +200,13 @@ void Parser::Next() {
           if (*cursor_ == '.') {
             cursor_++;
             while (isdigit(static_cast<unsigned char>(*cursor_))) cursor_++;
+            // See if this float has a scientific notation suffix. Both JSON
+            // and C++ (through strtod() we use) have the same format:
+            if (*cursor_ == 'e' || *cursor_ == 'E') {
+              cursor_++;
+              if (*cursor_ == '+' || *cursor_ == '-') cursor_++;
+              while (isdigit(static_cast<unsigned char>(*cursor_))) cursor_++;
+            }
             token_ = kTokenFloatConstant;
           } else {
             token_ = kTokenIntegerConstant;
diff --git a/tests/test.cpp b/tests/test.cpp
index 5aa8157d..9ca42348 100644
--- a/tests/test.cpp
+++ b/tests/test.cpp
@@ -481,6 +481,21 @@ void ErrorTest() {
   TestError("union Z { X } struct X { Y:int; }", "only tables");
 }
 
+// Additional parser testing not covered elsewhere.
+void TokenTest() {
+  flatbuffers::Parser parser;
+
+  // Simple schema.
+  TEST_EQ(parser.Parse("table X { Y:float; } root_type X;"), true);
+
+  // Test scientific notation numbers.
+  TEST_EQ(parser.Parse("{ Y:0.0314159e+2 }"), true);
+  auto root = flatbuffers::GetRoot<float>(parser.builder_.GetBufferPointer());
+  // root will point to the table, which is a 32bit vtable offset followed
+  // by a float:
+  TEST_EQ(fabs(root[1] - 3.14159) < 0.001, true);
+}
+
 int main(int /*argc*/, const char * /*argv*/[]) {
   // Run our various test suites:
 
@@ -495,6 +510,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
   FuzzTest2();
 
   ErrorTest();
+  TokenTest();
 
   if (!testing_fails) {
     TEST_OUTPUT_LINE("ALL TESTS PASSED");
-- 
GitLab