namespace {
+const int kJsonDepthLimit = 50;
+const int kKeyLengthLimit = 128;
+const int kValueLengthLimit = 1024;
+
std::string GetFileKeyRootPath(const char* pkgid) {
pkgmgrinfo_pkginfo_h handle;
int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
return path;
}
+bool CheckElementsTypeEqual(const Json::Value& node) {
+ if (!node.isArray())
+ return false;
+
+ Json::ValueType array_element_type = Json::ValueType::nullValue;
+ bool is_numeric_array = false;
+
+ for (auto it = node.begin(); it != node.end(); ++it) {
+ if (it->type() != Json::ValueType::nullValue) {
+ array_element_type = it->type();
+ is_numeric_array = it->isNumeric();
+ break;
+ }
+ }
+
+ for (auto it = node.begin(); it != node.end(); ++it) {
+ if (it->type() == Json::ValueType::nullValue)
+ continue;
+
+ if (it->type() != array_element_type &&
+ !(it->isNumeric() && is_numeric_array))
+ return false;
+ }
+
+ return true;
+}
+
} // namespace
namespace ttm {
namespace plugin {
bool ThemeParser::ExtractArray(const Json::Value& node,
- std::string parent_key, ThemeInfoBuilder* builder) {
+ std::string parent_key, ThemeInfoBuilder* builder, int depth) {
if (node.empty()) {
LOG(ERROR) << "Empty array is not allowed";
return false;
}
+ if (depth > kJsonDepthLimit) {
+ LOG(ERROR) << "Json value's depth is exceed maximum depth";
+ return false;
+ }
+
+ if (!CheckElementsTypeEqual(node)) {
+ LOG(ERROR) << "Json array element's type should be same";
+ return false;
+ }
+
Json::ValueType element_type = node.begin()->type();
std::vector<std::string> array_values;
int ind = 0;
for (auto it = node.begin(); it != node.end(); ++it) {
std::string key = parent_key + "/" + std::to_string(ind++);
- if (it->type() != element_type) {
- LOG(ERROR) << "Json array element's type should be same";
- return false;
- }
-
if (it->isObject()) {
- if (!ExtractJson(*it, key, builder))
+ if (!ExtractJson(*it, key, builder, depth + 1))
return false;
} else if (it->isArray()) {
- if (!ExtractArray(*it, key, builder))
+ if (!ExtractArray(*it, key, builder, depth + 1))
return false;
} else {
+ if (it->asString().length() >= kValueLengthLimit) {
+ LOG(ERROR) << "Json value's length is exceeded";
+ return false;
+ }
array_values.emplace_back(it->asString());
}
}
bool ThemeParser::ExtractElement(const Json::Value &node,
const std::string parent_key, ThemeInfoBuilder* builder) {
+ if (node.asString().length() >= kValueLengthLimit) {
+ LOG(ERROR) << "Json value's length is exceeded";
+ return false;
+ }
+
builder->PutString(parent_key, node.asString());
return true;
}
bool ThemeParser::ExtractJson(const Json::Value& node,
- std::string parent_key, ThemeInfoBuilder* builder) {
+ std::string parent_key, ThemeInfoBuilder* builder, int depth) {
+ if (depth > kJsonDepthLimit) {
+ LOG(ERROR) << "Json value's depth is exceeded";
+ return false;
+ }
+
bool ret = true;
for (auto it = node.begin(); it != node.end(); ++it) {
+ if (it.name().length() >= kKeyLengthLimit) {
+ LOG(ERROR) << "Json key's length is exceeded";
+ return false;
+ }
+
std::string key = parent_key + "/" + it.name();
if (it->isObject())
- ret &= ExtractJson(*it, key, builder);
+ ret &= ExtractJson(*it, key, builder, depth + 1);
else if (it->isArray())
- ret &= ExtractArray(*it, key, builder);
+ ret &= ExtractArray(*it, key, builder, depth + 1);
else
ret &= ExtractElement(*it, key, builder);
}
PutString("uid", std::to_string(uid)).
PutString("is_default", is_default ? "true" : "false");
- if (!ExtractJson(root, "", &builder)) {
+ if (!ExtractJson(root, "", &builder, 1)) {
LOG(ERROR) << "Fail to extract json value";
return {};
}
private:
bool ExtractArray(const Json::Value& node,
- std::string parent_key, ThemeInfoBuilder* builder);
+ std::string parent_key, ThemeInfoBuilder* builder, int depth);
bool ExtractElement(const Json::Value &node,
const std::string parent_key, ThemeInfoBuilder* builder);
bool ExtractJson(const Json::Value& node,
- std::string parent_key, ThemeInfoBuilder* builder);
+ std::string parent_key, ThemeInfoBuilder* builder, int depth);
std::string path_;
bool auto_file_key_gen_;
--- /dev/null
+{
+ "50D_array" :
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ "invalid"
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+}
\ No newline at end of file
--- /dev/null
+{
+ "50D_array" :
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ [
+ "valid"
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+}
\ No newline at end of file
--- /dev/null
+{
+ "1st" : {
+ "2st" : {
+ "3st" : {
+ "4st" : {
+ "5st" : {
+ "6st" : {
+ "7st" : {
+ "8st" : {
+ "9st" : {
+ "10st" : {
+ "11st" : {
+ "12st" : {
+ "13st" : {
+ "14st" : {
+ "15st" : {
+ "16st" : {
+ "17st" : {
+ "18st" : {
+ "19st" : {
+ "20st" : {
+ "21st" : {
+ "22st" : {
+ "23st" : {
+ "24st" : {
+ "25st" : {
+ "26st" : {
+ "27st" : {
+ "28st" : {
+ "29st" : {
+ "30st" : {
+ "31st" : {
+ "32st" : {
+ "33st" : {
+ "34st" : {
+ "35st" : {
+ "36st" : {
+ "37st" : {
+ "38st" : {
+ "39st" : {
+ "40st" : {
+ "41st" : {
+ "42st" : {
+ "43st" : {
+ "44st" : {
+ "45st" : {
+ "46st" : {
+ "47st" : {
+ "48st" : {
+ "49st" : {
+ "50st" : {
+ "51st" : "invalid"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+{
+ "1st" : {
+ "2st" : {
+ "3st" : {
+ "4st" : {
+ "5st" : {
+ "6st" : {
+ "7st" : {
+ "8st" : {
+ "9st" : {
+ "10st" : {
+ "11st" : {
+ "12st" : {
+ "13st" : {
+ "14st" : {
+ "15st" : {
+ "16st" : {
+ "17st" : {
+ "18st" : {
+ "19st" : {
+ "20st" : {
+ "21st" : {
+ "22st" : {
+ "23st" : {
+ "24st" : {
+ "25st" : {
+ "26st" : {
+ "27st" : {
+ "28st" : {
+ "29st" : {
+ "30st" : {
+ "31st" : {
+ "32st" : {
+ "33st" : {
+ "34st" : {
+ "35st" : {
+ "36st" : {
+ "37st" : {
+ "38st" : {
+ "39st" : {
+ "40st" : {
+ "41st" : {
+ "42st" : {
+ "43st" : {
+ "44st" : {
+ "45st" : {
+ "46st" : {
+ "47st" : {
+ "48st" : {
+ "49st" : {
+ "50st" : "valid"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
{
"array" : [
+ null,
"a",
1
]
--- /dev/null
+{
+ "128_length_key__________________________________________________________________________________________________________________" : "invalid"
+}
--- /dev/null
+{
+ "127_length_key_________________________________________________________________________________________________________________" : "valid"
+}
--- /dev/null
+{
+ "valid_length_value" : "................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................"
+}
--- /dev/null
+{
+ "valid_length_value" : [
+ "................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................"
+ ]
+}
--- /dev/null
+{
+ "valid_length_value" : "..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................."
+}
"keyboard": {
"keypad_bg_color": "#050a28"
}
- }
+ },
+ "object_array" : [
+ {
+ "key_A" : "A",
+ "key_B" : "B"
+ },
+ {
+ "key_A" : "AA",
+ "key_B" : "BB"
+ },
+ null
+ ]
}
std::vector<std::string>({"GOGO_Preview.png"}));
EXPECT_EQ(info.GetString("/theme/files/theme_resources"),
"shared/res/theme_resources");
+ EXPECT_EQ(info.GetString("/object_array/0/key_A"), "A");
+ EXPECT_EQ(info.GetString("/object_array/0/key_B"), "B");
+ EXPECT_EQ(info.GetString("/object_array/1/key_A"), "AA");
+ EXPECT_EQ(info.GetString("/object_array/1/key_B"), "BB");
}
TEST_F(ThemeParserTest, MultidimensionalArray) {
auto info = parser.Inflate("testid", "testpkgid", 5001, false);
EXPECT_FALSE(info.IsValid());
}
+
+TEST_F(ThemeParserTest, DeepDepthKey_P) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_deep_depth_key_P.json", false);
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_TRUE(info.IsValid());
+}
+
+TEST_F(ThemeParserTest, DeepDepthKey_N) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_deep_depth_key_N.json", false);
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_FALSE(info.IsValid());
+}
+
+TEST_F(ThemeParserTest, DeepDepthArray_P) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_deep_depth_array_P.json", false);
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_TRUE(info.IsValid());
+}
+
+TEST_F(ThemeParserTest, DeepDepthArray_N) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_deep_depth_array_N.json", false);
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_FALSE(info.IsValid());
+}
+
+TEST_F(ThemeParserTest, LongLengthKey_P) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_long_length_key_P.json", false);
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_TRUE(info.IsValid());
+}
+
+TEST_F(ThemeParserTest, LongLengthKey_N) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_long_length_key_N.json", false);
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_FALSE(info.IsValid());
+}
+
+TEST_F(ThemeParserTest, LongLengthValue_P) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_long_length_value_P.json", false);
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_TRUE(info.IsValid());
+}
+
+TEST_F(ThemeParserTest, LongLengthValue_N) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_long_length_value_N.json", false);
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_FALSE(info.IsValid());
+}
+
+TEST_F(ThemeParserTest, LongLengthValue_N2) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_long_length_value_N2.json", false);
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_FALSE(info.IsValid());
+}