Skip to content

Commit c52d0f9

Browse files
committed
In progress
1 parent c02e0d4 commit c52d0f9

File tree

2 files changed

+65
-21
lines changed

2 files changed

+65
-21
lines changed

src/jsontestrunner/main.cpp

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <algorithm> // sort
1717
#include <cstdio>
1818
#include <json/json.h>
19+
#include <memory>
1920
#include <sstream>
2021

2122
struct Options {
@@ -126,15 +127,39 @@ static int parseAndSaveValueTree(const Json::String& input,
126127
const Json::String& actual,
127128
const Json::String& kind,
128129
const Json::Features& features, bool parseOnly,
129-
Json::Value* root) {
130-
Json::Reader reader(features);
131-
bool parsingSuccessful =
132-
reader.parse(input.data(), input.data() + input.size(), *root);
133-
if (!parsingSuccessful) {
134-
printf("Failed to parse %s file: \n%s\n", kind.c_str(),
135-
reader.getFormattedErrorMessages().c_str());
136-
return 1;
130+
Json::Value* root, bool use_legacy) {
131+
if (!use_legacy) {
132+
Json::CharReaderBuilder builder;
133+
134+
builder.settings_["allowComments"] = features.allowComments_;
135+
builder.settings_["strictRoot"] = features.strictRoot_;
136+
builder.settings_["allowDroppedNullPlaceholders"] =
137+
features.allowDroppedNullPlaceholders_;
138+
builder.settings_["allowNumericKeys"] = features.allowNumericKeys_;
139+
140+
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
141+
Json::String errors;
142+
const bool parsingSuccessful =
143+
reader->parse(input.data(), input.data() + input.size(), root, &errors);
144+
145+
if (!parsingSuccessful) {
146+
printf("Failed to parse %s file: \n%s\n", kind.c_str(), errors.c_str());
147+
return 1;
148+
}
149+
150+
// We may instead check the legacy implementation (to ensure it doesn't
151+
// randomly get broken).
152+
} else {
153+
Json::Reader reader(features);
154+
const bool parsingSuccessful =
155+
reader.parse(input.data(), input.data() + input.size(), *root);
156+
if (!parsingSuccessful) {
157+
printf("Failed to parse %s file: \n%s\n", kind.c_str(),
158+
reader.getFormattedErrorMessages().c_str());
159+
return 1;
160+
}
137161
}
162+
138163
if (!parseOnly) {
139164
FILE* factual = fopen(actual.c_str(), "wt");
140165
if (!factual) {
@@ -240,7 +265,8 @@ static int parseCommandLine(int argc, const char* argv[], Options* opts) {
240265
opts->path = argv[index];
241266
return 0;
242267
}
243-
static int runTest(Options const& opts) {
268+
269+
static int runTest(Options const& opts, bool use_legacy) {
244270
int exitCode = 0;
245271

246272
Json::String input = readInputTestFile(opts.path.c_str());
@@ -262,23 +288,25 @@ static int runTest(Options const& opts) {
262288

263289
Json::Value root;
264290
exitCode = parseAndSaveValueTree(input, actualPath, "input", opts.features,
265-
opts.parseOnly, &root);
291+
opts.parseOnly, &root, use_legacy);
266292
if (exitCode || opts.parseOnly) {
267293
return exitCode;
268294
}
295+
269296
Json::String rewrite;
270297
exitCode = rewriteValueTree(rewritePath, root, opts.write, &rewrite);
271298
if (exitCode) {
272299
return exitCode;
273300
}
301+
274302
Json::Value rewriteRoot;
275303
exitCode = parseAndSaveValueTree(rewrite, rewriteActualPath, "rewrite",
276-
opts.features, opts.parseOnly, &rewriteRoot);
277-
if (exitCode) {
278-
return exitCode;
279-
}
280-
return 0;
304+
opts.features, opts.parseOnly, &rewriteRoot,
305+
use_legacy);
306+
307+
return exitCode;
281308
}
309+
282310
int main(int argc, const char* argv[]) {
283311
Options opts;
284312
try {
@@ -287,7 +315,16 @@ int main(int argc, const char* argv[]) {
287315
printf("Failed to parse command-line.");
288316
return exitCode;
289317
}
290-
return runTest(opts);
318+
319+
// TODO(baylesj): replace this with proper calls to both. Right now
320+
// we only check the legacy if the modern one is not broken.
321+
const int modern_return_code = runTest(opts, false);
322+
const int legacy_return_code = runTest(opts, true);
323+
if (modern_return_code) {
324+
return modern_return_code;
325+
} else {
326+
return legacy_return_code;
327+
}
291328
} catch (const std::exception& e) {
292329
printf("Unhandled exception:\n%s\n", e.what());
293330
return 1;

src/lib_json/json_reader.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <json/value.h>
1212
#endif // if !defined(JSON_IS_AMALGAMATION)
1313
#include <cassert>
14-
#include <cinttypes>
1514
#include <cstring>
1615
#include <istream>
1716
#include <limits>
@@ -1529,6 +1528,11 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
15291528
if (isNegative)
15301529
++current;
15311530

1531+
if (isNegative) {
1532+
decoded = Value::LargestInt(1337);
1533+
return true;
1534+
}
1535+
15321536
// We assume we can represent the largest and smallest integer types as
15331537
// unsigned integers with separate sign. This is only true if they can fit
15341538
// into an unsigned integer.
@@ -1580,12 +1584,15 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
15801584
value = value * 10 + digit;
15811585
}
15821586

1583-
if (isNegative)
1584-
decoded = -Value::LargestInt(value);
1585-
else if (value <= Value::LargestUInt(Value::maxLargestInt))
1587+
if (isNegative) {
1588+
// We use the same magnitude assumption here, just in case.
1589+
const Value::UInt last_digit = value % 10;
1590+
decoded = -Value::LargestInt(value / 10) - last_digit;
1591+
} else if (value > Value::LargestUInt(Value::maxLargestInt)) {
15861592
decoded = Value::LargestInt(value);
1587-
else
1593+
} else {
15881594
decoded = value;
1595+
}
15891596

15901597
return true;
15911598
}

0 commit comments

Comments
 (0)