X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Ftest%2FJsonTest.cpp;h=0145fecbbcd77a6249fc3e875c625c5303fb0b06;hb=b3e7df8220f410398011fea71b280ba8be459fcc;hp=805cb3004ffa56a4855f20a38fb181658ffbe4bd;hpb=6a6ac91e1fda65d7871390f03be8d19b3591ba45;p=folly.git diff --git a/folly/test/JsonTest.cpp b/folly/test/JsonTest.cpp index 805cb300..0145fecb 100644 --- a/folly/test/JsonTest.cpp +++ b/folly/test/JsonTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -154,14 +154,14 @@ TEST(Json, BoolConversion) { } TEST(Json, JavascriptSafe) { - auto badDouble = (1ll << 63ll) + 1; + auto badDouble = int64_t((1ULL << 63ULL) + 1); dynamic badDyn = badDouble; EXPECT_EQ(folly::toJson(badDouble), folly::to(badDouble)); folly::json::serialization_opts opts; opts.javascript_safe = true; EXPECT_ANY_THROW(folly::json::serialize(badDouble, opts)); - auto okDouble = 1ll << 63ll; + auto okDouble = int64_t(1ULL << 63ULL); dynamic okDyn = okDouble; EXPECT_EQ(folly::toJson(okDouble), folly::to(okDouble)); } @@ -190,6 +190,53 @@ TEST(Json, JsonEscape) { R"("\b\f\n\r\u0001\t\\\"/\u000b\u0007")"); } +TEST(Json, EscapeCornerCases) { + // The escaping logic uses some bitwise operations to determine + // which bytes need escaping 8 bytes at a time. Test that this logic + // is correct regardless of positions by planting 2 characters that + // may need escaping at each possible position and checking the + // result, for varying string lengths. + + folly::json::serialization_opts opts; + opts.validate_utf8 = true; + + std::string s; + std::string expected; + for (bool ascii : {true, false}) { + opts.encode_non_ascii = ascii; + + for (size_t len = 2; len < 32; ++len) { + for (size_t i = 0; i < len; ++i) { + for (size_t j = 0; j < len; ++j) { + if (i == j) { + continue; + } + + s.clear(); + expected.clear(); + + expected.push_back('"'); + for (size_t pos = 0; pos < len; ++pos) { + if (pos == i) { + s.push_back('\\'); + expected.append("\\\\"); + } else if (pos == j) { + s.append("\xe2\x82\xac"); + expected.append(ascii ? "\\u20ac" : "\xe2\x82\xac"); + } else { + s.push_back('x'); + expected.push_back('x'); + } + } + expected.push_back('"'); + + EXPECT_EQ(folly::json::serialize(s, opts), expected) << ascii; + } + } + } + } +} + TEST(Json, JsonNonAsciiEncoding) { folly::json::serialization_opts opts; opts.encode_non_ascii = true; @@ -438,10 +485,17 @@ TEST(Json, ParseNumbersAsStrings) { } TEST(Json, SortKeys) { - folly::json::serialization_opts opts_on, opts_off; + folly::json::serialization_opts opts_on, opts_off, opts_custom_sort; opts_on.sort_keys = true; opts_off.sort_keys = false; + opts_custom_sort.sort_keys = false; // should not be required + opts_custom_sort.sort_keys_by = []( + folly::dynamic const& a, folly::dynamic const& b) { + // just an inverse sort + return b < a; + }; + dynamic value = dynamic::object ("foo", "bar") ("junk", 12) @@ -462,10 +516,18 @@ TEST(Json, SortKeys) { R"({"a":[{"a":"b","c":"d"},12.5,"Yo Dawg",["heh"],null],)" R"("another":32.2,"foo":"bar","junk":12})"; + std::string inverse_sorted_keys = + R"({"junk":12,"foo":"bar","another":32.2,)" + R"("a":[{"c":"d","a":"b"},12.5,"Yo Dawg",["heh"],null]})"; + EXPECT_EQ(value, parseJson(folly::json::serialize(value, opts_on))); EXPECT_EQ(value, parseJson(folly::json::serialize(value, opts_off))); + EXPECT_EQ(value, parseJson(folly::json::serialize(value, opts_custom_sort))); EXPECT_EQ(sorted_keys, folly::json::serialize(value, opts_on)); + EXPECT_NE(sorted_keys, folly::json::serialize(value, opts_off)); + EXPECT_EQ( + inverse_sorted_keys, folly::json::serialize(value, opts_custom_sort)); } TEST(Json, PrintTo) {