1 // Copyright 2021 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16
17 #include "tink/jwt/internal/json_util.h"
18
19 #include <string>
20
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "tink/util/test_matchers.h"
24 #include "tink/util/test_util.h"
25
26 using ::crypto::tink::test::IsOk;
27 using ::crypto::tink::test::IsOkAndHolds;
28 using ::google::protobuf::ListValue;
29 using ::google::protobuf::Struct;
30
31 namespace crypto {
32 namespace tink {
33 namespace jwt_internal {
34
TEST(JsonUtil,ParseThenSerializeStructWtihStringListOk)35 TEST(JsonUtil, ParseThenSerializeStructWtihStringListOk) {
36 util::StatusOr<Struct> proto =
37 JsonStringToProtoStruct(R"({"some_key":["hello","world","!"]})");
38 ASSERT_THAT(proto, IsOk());
39
40 ASSERT_THAT(ProtoStructToJsonString(*proto),
41 IsOkAndHolds(R"({"some_key":["hello","world","!"]})"));
42 }
43
TEST(JsonUtil,ParseThenSerializeStructWtihNumberOk)44 TEST(JsonUtil, ParseThenSerializeStructWtihNumberOk) {
45 util::StatusOr<Struct> proto =
46 JsonStringToProtoStruct(R"({"some_key":-12345})");
47 ASSERT_THAT(proto, IsOk());
48
49 ASSERT_THAT(ProtoStructToJsonString(*proto),
50 IsOkAndHolds(R"({"some_key":-12345})"));
51 }
52
TEST(JsonUtil,ParseThenSerializeStructWtihBoolOk)53 TEST(JsonUtil, ParseThenSerializeStructWtihBoolOk) {
54 util::StatusOr<Struct> proto =
55 JsonStringToProtoStruct(R"({"some_key":false})");
56 ASSERT_THAT(proto, IsOk());
57
58 ASSERT_THAT(ProtoStructToJsonString(*proto),
59 IsOkAndHolds(R"({"some_key":false})"));
60 }
61
TEST(JsonUtil,ParseThenSerializeListOk)62 TEST(JsonUtil, ParseThenSerializeListOk) {
63 util::StatusOr<ListValue> proto =
64 JsonStringToProtoList(R"(["hello", "world", 42, true])");
65 ASSERT_THAT(proto, IsOk());
66
67 ASSERT_THAT(ProtoListToJsonString(*proto),
68 IsOkAndHolds(R"(["hello","world",42,true])"));
69 }
70
TEST(JsonUtil,ParseInvalidStructTokenNotOk)71 TEST(JsonUtil, ParseInvalidStructTokenNotOk) {
72 util::StatusOr<Struct> proto =
73 JsonStringToProtoStruct(R"({"some_key":false)");
74 ASSERT_FALSE(proto.ok());
75 }
76
TEST(JsonUtil,ParseInvalidListTokenNotOk)77 TEST(JsonUtil, ParseInvalidListTokenNotOk) {
78 util::StatusOr<Struct> proto = JsonStringToProtoStruct(R"(["one", )");
79 ASSERT_FALSE(proto.ok());
80 }
81
TEST(JsonUtil,parseRecursiveJsonStringFails)82 TEST(JsonUtil, parseRecursiveJsonStringFails) {
83 std::string recursive_json;
84 for (int i = 0; i < 10000; i++) {
85 recursive_json.append("{\"a\":");
86 }
87 recursive_json.append("1");
88 for (int i = 0; i < 10000; i++) {
89 recursive_json.append("}");
90 }
91 util::StatusOr<Struct> proto = JsonStringToProtoStruct(recursive_json);
92 EXPECT_FALSE(proto.ok());
93 }
94
TEST(JsonUtil,ParseStructWithoutQuotesOk)95 TEST(JsonUtil, ParseStructWithoutQuotesOk) {
96 // TODO(b/360366279) Make parsing stricter that this is not allowed.
97 util::StatusOr<Struct> proto = JsonStringToProtoStruct(R"({some_key:false})");
98 ASSERT_THAT(proto, IsOk());
99 ASSERT_THAT(ProtoStructToJsonString(*proto),
100 IsOkAndHolds(R"({"some_key":false})"));
101 }
102
TEST(JsonUtil,ParseListWithoutQuotesNotOk)103 TEST(JsonUtil, ParseListWithoutQuotesNotOk) {
104 util::StatusOr<ListValue> proto = JsonStringToProtoList(R"([one,two])");
105 EXPECT_FALSE(proto.ok());
106 }
107
TEST(JsonUtil,ParseStructWithCommentNotOk)108 TEST(JsonUtil, ParseStructWithCommentNotOk) {
109 util::StatusOr<Struct> proto =
110 JsonStringToProtoStruct(R"({"some_key":false /* comment */})");
111 EXPECT_FALSE(proto.ok());
112 }
113
TEST(JsonUtil,ParseListWithCommentNotOk)114 TEST(JsonUtil, ParseListWithCommentNotOk) {
115 util::StatusOr<ListValue> proto =
116 JsonStringToProtoList(R"(["hello", "world" /* comment */])");
117 EXPECT_FALSE(proto.ok());
118 }
119
120 } // namespace jwt_internal
121 } // namespace tink
122 } // namespace crypto
123