1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
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 #ifndef OMIT_JSON
17 #include <algorithm>
18 #include <gtest/gtest.h>
19 #include "db_errno.h"
20 #include "distributeddb_tools_unit_test.h"
21 #include "json_object.h"
22 
23 using namespace std;
24 using namespace testing::ext;
25 using namespace DistributedDB;
26 
27 namespace {
28     const int MAX_DEPTH_FOR_TEST = 10;
29     const int STRING1_DEPTH = 12;
30     const int STRING3_DEPTH = 6;
31 
32     // nest depth = 12 and valid.
33     const string JSON_STRING1 = "{\"#14\":[[{\"#11\":{\"#8\":[{\"#5\":[[{\"#2\":[{\"#0\":\"value_\"},\"value_\"],"
34         "\"#3\":\"value_\"},\"value_\"],\"value_\"],\"#6\":\"value_\"},\"value_\"],\"#9\":\"value_\"},"
35         "\"#12\":\"value_\"},\"value_\"],\"value_\"],\"#15\":{\"#18\":{\"#16\":\"value_\"},\"#19\":\"value_\"}}";
36 
37     // nest depth = 12 and invalid happens in nest depth = 2.
38     const string JSON_STRING2 = "{\"#17\":[\"just for mistake pls.[{\"#14\":[[{\"#11\":{\"#8\":{\"#5\":[{\"#2\":"
39         "{\"#0\":\"value_\"},\"#3\":\"value_\"},\"value_\"],\"#6\":\"value_\"},\"#9\":\"value_\"},"
40         "\"#12\":\"value_\"},\"value_\"],\"value_\"],\"#15\":\"value_\"},\"value_\"],\"value_\"],"
41         "\"#18\":{\"#21\":{\"#19\":\"value_\"},\"#22\":\"value_\"}}";
42 
43     // nest depth = 6 and valid.
44     const string JSON_STRING3 = "{\"#5\":[{\"#2\":[[{\"#0\":\"value_\"},\"value_\"],\"value_\"],\"#3\":\"value_\"},"
45         "\"value_\"],\"#6\":{\"#7\":\"value_\",\"#8\":\"value_\"}}";
46 
47     // nest depth = 6 and invalid happens in nest depth = 3.
48     const string JSON_STRING4 = "{\"#6\":[{\"#3\":\"just for mistake pls.[{\"#0\":[\"value_\"],\"#1\":\"value_\"},"
49         "\"value_\"],\"#4\":\"value_\"},\"value_\"],\"#7\":{\"#8\":\"value_\",\"#9\":\"value_\"}}";
50 
51     // nest depth = 15 and invalid happens in nest depth = 11.
52     const string JSON_STRING5 = "{\"#35\":[{\"#29\":{\"#23\":{\"#17\":{\"#11\":{\"#8\":[{\"#5\":[{\"#2\":"
53         "\"just for mistake pls.[[[{\"#0\":\"value_\"},\"value_\"],\"value_\"],\"value_\"],\"#3\":\"value_\"},"
54         "\"value_\"],\"#6\":\"value_\"},\"value_\"],\"#9\":\"value_\"},\"#12\":{\"#13\":\"value_\","
55         "\"#14\":\"value_\"}},\"#18\":{\"#19\":\"value_\",\"#20\":\"value_\"}},\"#24\":{\"#25\":\"value_\","
56         "\"#26\":\"value_\"}},\"#30\":{\"#31\":\"value_\",\"#32\":\"value_\"}},\"value_\"],\"#36\":"
57         "{\"#37\":[\"value_\"],\"#38\":\"value_\"}}";
58 
59     uint32_t g_oriMaxNestDepth = 0;
60 }
61 
62 class DistributedDBJsonPrecheckUnitTest : public testing::Test {
63 public:
64     static void SetUpTestCase(void);
65     static void TearDownTestCase(void);
66     void SetUp();
TearDown()67     void TearDown() {};
68 };
69 
SetUpTestCase(void)70 void DistributedDBJsonPrecheckUnitTest::SetUpTestCase(void)
71 {
72     /**
73      * @tc.setup: Specifies a maximum nesting depth of 10.
74      */
75     g_oriMaxNestDepth = JsonObject::SetMaxNestDepth(MAX_DEPTH_FOR_TEST);
76 }
77 
TearDownTestCase(void)78 void DistributedDBJsonPrecheckUnitTest::TearDownTestCase(void)
79 {
80     /**
81      * @tc.teardown: Reset nesting depth to origin value.
82      */
83     JsonObject::SetMaxNestDepth(g_oriMaxNestDepth);
84 }
85 
SetUp()86 void DistributedDBJsonPrecheckUnitTest::SetUp()
87 {
88     DistributedDBUnitTest::DistributedDBToolsUnitTest::PrintTestCaseInfo();
89 }
90 
91 /**
92  * @tc.name: Precheck Valid String 001
93  * @tc.desc: json string is legal
94  * @tc.type: FUNC
95  * @tc.require: AR000DR9K3
96  * @tc.author: yiguang
97  */
98 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseValidString001, TestSize.Level1)
99 {
100     /**
101      * @tc.steps: step1. Check legal json string with nesting depth of 12.
102      * @tc.expected: step1. return value = 12.
103      */
104     int errCode = E_OK;
105     int stepOne = static_cast<int>(JsonObject::CalculateNestDepth(JSON_STRING1, errCode));
106     EXPECT_TRUE(errCode == E_OK);
107     EXPECT_TRUE(stepOne == STRING1_DEPTH);
108 
109     /**
110      * @tc.steps: step2. Parsing of legal json string with nesting depth greater than 10 failed.
111      * @tc.expected: step2. Parsing result failed.
112      */
113     JsonObject tempObj;
114     int stepTwo = tempObj.Parse(JSON_STRING1);
115     EXPECT_TRUE(stepTwo != E_OK);
116 }
117 
118 /**
119  * @tc.name: Precheck Valid String 002
120  * @tc.desc: json string is legal
121  * @tc.type: FUNC
122  * @tc.require: AR000DR9K3
123  * @tc.author: yiguang
124  */
125 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseValidString002, TestSize.Level1)
126 {
127     /**
128      * @tc.steps: step1. Check legal json string with nesting depth of 6.
129      * @tc.expected: step1. return value = 6.
130      */
131     int errCode = E_OK;
132     int stepOne = static_cast<int>(JsonObject::CalculateNestDepth(JSON_STRING3, errCode));
133     EXPECT_TRUE(errCode == E_OK);
134     EXPECT_TRUE(stepOne == STRING3_DEPTH);
135 
136     /**
137      * @tc.steps: step2. Parsing of legal json string with nesting depth less than 10 success.
138      * @tc.expected: step2. Parsing result success.
139      */
140     JsonObject tempObj;
141     int stepTwo = tempObj.Parse(JSON_STRING3);
142     EXPECT_TRUE(stepTwo == E_OK);
143 }
144 
145 /**
146  * @tc.name: Precheck invalid String 001
147  * @tc.desc: The json string has been detected illegal before exceeding the specified nesting depth.
148  * @tc.type: FUNC
149  * @tc.require: AR000DR9K3
150  * @tc.author: yiguang
151  */
152 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseInvalidString001, TestSize.Level1)
153 {
154     /**
155      * @tc.steps: step1. Parsing of illegal json string with nesting depth greater than 10 success.
156      * @tc.expected: step1. Parsing result failed.
157      */
158     JsonObject tempObj;
159     int stepOne = tempObj.Parse(JSON_STRING2);
160     EXPECT_TRUE(stepOne != E_OK);
161 }
162 
163 /**
164  * @tc.name: Precheck invalid String 002
165  * @tc.desc: The json string has been detected illegal before exceeding the specified nesting depth.
166  * @tc.type: FUNC
167  * @tc.require: AR000DR9K3
168  * @tc.author: yiguang
169  */
170 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseInvalidString002, TestSize.Level1)
171 {
172     /**
173      * @tc.steps: step1. Parsing of illegal json string with nesting depth less than 10 success.
174      * @tc.expected: step1. Parsing result failed.
175      */
176     JsonObject tempObj;
177     int stepOne = tempObj.Parse(JSON_STRING4);
178     EXPECT_TRUE(stepOne != E_OK);
179 }
180 
181 /**
182  * @tc.name: Precheck invalid String 003
183  * @tc.desc: The json string has been detected illegal before exceeding the specified nesting depth.
184  * @tc.type: FUNC
185  * @tc.require: AR000DR9K3
186  * @tc.author: yiguang
187  */
188 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseInvalidString003, TestSize.Level1)
189 {
190     /**
191      * @tc.steps: step1. Detect illegal json string with nesting depth greater than 10.
192      * @tc.expected: step1. return value > 10.
193      */
194     int errCode = E_OK;
195     int stepOne = static_cast<int>(JsonObject::CalculateNestDepth(JSON_STRING5, errCode));
196     EXPECT_TRUE(errCode == E_OK);
197     EXPECT_TRUE(stepOne > MAX_DEPTH_FOR_TEST);
198 
199     /**
200      * @tc.steps: step2. Parsing of illegal json string with nesting depth greater than 10 success.
201      * @tc.expected: step2. Parsing result failed.
202      */
203     JsonObject tempObj;
204     int stepTwo = tempObj.Parse(JSON_STRING5);
205     EXPECT_TRUE(stepTwo != E_OK);
206 }
207 #endif