remove useless test case
This commit is contained in:
@@ -891,8 +891,8 @@ expr_runtime_stream_open(struct expr_runtime *expr_rt, int thread_id)
|
||||
expr_rt_stream->ref_expr_rt = expr_rt;
|
||||
expr_rt_stream->handle = expr_matcher_stream_open(expr_rt->matcher, thread_id);
|
||||
if (NULL == expr_rt_stream->handle) {
|
||||
FREE(expr_rt_stream);
|
||||
return NULL;
|
||||
log_info(expr_rt->logger, MODULE_EXPR,
|
||||
"[%s:%d] expr_matcher_stream_open failed, expr_rt->matcher is %p", __FUNCTION__, __LINE__, expr_rt->matcher);
|
||||
}
|
||||
|
||||
return expr_rt_stream;
|
||||
|
||||
@@ -68,7 +68,7 @@ struct table_condition {
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
struct table_object {
|
||||
struct negate_attribute_object {
|
||||
char attribute_name[MAX_ATTR_NAME_LEN];
|
||||
UT_array *object_uuids;
|
||||
UT_hash_handle hh;
|
||||
@@ -147,7 +147,7 @@ struct rule_compile_state {
|
||||
UT_array *indirect_hit_objects;
|
||||
UT_array *last_hit_objects;
|
||||
UT_array *hit_rule_table_ids;
|
||||
struct table_object *hit_not_tbl_objects;
|
||||
struct negate_attribute_object *hit_negate_attribute_objects;
|
||||
};
|
||||
|
||||
UT_icd ut_condition_id_icd = {sizeof(long long), NULL, NULL, NULL};
|
||||
@@ -890,29 +890,29 @@ struct rule_compile_state *rule_compile_state_new(void)
|
||||
utarray_new(rule_compile_state->indirect_hit_objects, &ut_maat_hit_object_icd);
|
||||
utarray_new(rule_compile_state->last_hit_objects, &ut_maat_hit_object_icd);
|
||||
utarray_new(rule_compile_state->hit_rule_table_ids, &ut_hit_rule_table_id_icd);
|
||||
rule_compile_state->hit_not_tbl_objects = NULL;
|
||||
rule_compile_state->hit_negate_attribute_objects = NULL;
|
||||
|
||||
return rule_compile_state;
|
||||
}
|
||||
|
||||
static long long
|
||||
rule_compile_state_hit_not_tbl_objects_free(struct rule_compile_state *rule_compile_state)
|
||||
rule_compile_state_hit_not_condition_objects_free(struct rule_compile_state *rule_compile_state)
|
||||
{
|
||||
if (NULL == rule_compile_state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long long free_bytes = 0;
|
||||
struct table_object *tbl_object = NULL, *tmp_tbl_object = NULL;
|
||||
HASH_ITER(hh, rule_compile_state->hit_not_tbl_objects, tbl_object, tmp_tbl_object) {
|
||||
struct negate_attribute_object *negate_attr_obj = NULL, *tmp_negate_attr_obj = NULL;
|
||||
HASH_ITER(hh, rule_compile_state->hit_negate_attribute_objects, negate_attr_obj, tmp_negate_attr_obj) {
|
||||
free_bytes +=
|
||||
(sizeof(tbl_object) + utarray_len(tbl_object->object_uuids) * sizeof(uuid_t));
|
||||
HASH_DEL(rule_compile_state->hit_not_tbl_objects, tbl_object);
|
||||
if (tbl_object->object_uuids != NULL) {
|
||||
utarray_free(tbl_object->object_uuids);
|
||||
tbl_object->object_uuids = NULL;
|
||||
(sizeof(negate_attr_obj) + utarray_len(negate_attr_obj->object_uuids) * sizeof(uuid_t));
|
||||
HASH_DEL(rule_compile_state->hit_negate_attribute_objects, negate_attr_obj);
|
||||
if (negate_attr_obj->object_uuids != NULL) {
|
||||
utarray_free(negate_attr_obj->object_uuids);
|
||||
negate_attr_obj->object_uuids = NULL;
|
||||
}
|
||||
FREE(tbl_object);
|
||||
FREE(negate_attr_obj);
|
||||
}
|
||||
|
||||
return free_bytes;
|
||||
@@ -938,9 +938,9 @@ void rule_compile_state_reset(struct rule_compile_state *rule_compile_state)
|
||||
utarray_clear(rule_compile_state->last_hit_objects);
|
||||
utarray_clear(rule_compile_state->hit_rule_table_ids);
|
||||
|
||||
struct table_object *tbl_object = NULL, *tmp_tbl_object = NULL;
|
||||
HASH_ITER(hh, rule_compile_state->hit_not_tbl_objects, tbl_object, tmp_tbl_object) {
|
||||
utarray_clear(tbl_object->object_uuids);
|
||||
struct negate_attribute_object *negate_attr_obj = NULL, *tmp_negate_attr_obj = NULL;
|
||||
HASH_ITER(hh, rule_compile_state->hit_negate_attribute_objects, negate_attr_obj, tmp_negate_attr_obj) {
|
||||
utarray_clear(negate_attr_obj->object_uuids);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1015,7 +1015,7 @@ void rule_compile_state_free(struct rule_compile_state *rule_compile_state,
|
||||
rule_compile_state->hit_rule_table_ids = NULL;
|
||||
}
|
||||
|
||||
free_bytes += rule_compile_state_hit_not_tbl_objects_free(rule_compile_state);
|
||||
free_bytes += rule_compile_state_hit_not_condition_objects_free(rule_compile_state);
|
||||
|
||||
FREE(rule_compile_state);
|
||||
|
||||
@@ -1386,18 +1386,18 @@ rule_compile_state_cache_hit_not_objects(struct rule_compile_state *rule_compile
|
||||
qsort(hit_object_uuids, n_hit_object_uuid, sizeof(uuid_t), compare_object_uuid);
|
||||
}
|
||||
|
||||
struct table_object *tbl_object = NULL;
|
||||
HASH_FIND_STR(rule_compile_state->hit_not_tbl_objects, attribute_name, tbl_object);
|
||||
if (tbl_object != NULL) {
|
||||
struct negate_attribute_object *negate_attr_obj = NULL;
|
||||
HASH_FIND_STR(rule_compile_state->hit_negate_attribute_objects, attribute_name, negate_attr_obj);
|
||||
if (negate_attr_obj != NULL) {
|
||||
for (size_t i = 0; i < n_hit_object_uuid; i++) {
|
||||
uuid_t *object_uuid = (uuid_t *)utarray_find(tbl_object->object_uuids,
|
||||
uuid_t *object_uuid = (uuid_t *)utarray_find(negate_attr_obj->object_uuids,
|
||||
&hit_object_uuids[i],
|
||||
compare_object_uuid);
|
||||
if (NULL == object_uuid) {
|
||||
continue;
|
||||
}
|
||||
size_t remove_idx = utarray_eltidx(tbl_object->object_uuids, object_uuid);
|
||||
utarray_erase(tbl_object->object_uuids, remove_idx, 1);
|
||||
size_t remove_idx = utarray_eltidx(negate_attr_obj->object_uuids, object_uuid);
|
||||
utarray_erase(negate_attr_obj->object_uuids, remove_idx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1414,21 +1414,21 @@ rule_compile_state_cache_hit_not_objects(struct rule_compile_state *rule_compile
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NULL == tbl_object) {
|
||||
tbl_object = ALLOC(struct table_object, 1);
|
||||
snprintf(tbl_object->attribute_name, sizeof(tbl_object->attribute_name), "%s", attribute_name);
|
||||
utarray_new(tbl_object->object_uuids, &ut_rule_object_uuid_icd);
|
||||
HASH_ADD_STR(rule_compile_state->hit_not_tbl_objects, attribute_name, tbl_object);
|
||||
if (NULL == negate_attr_obj) {
|
||||
negate_attr_obj = ALLOC(struct negate_attribute_object, 1);
|
||||
snprintf(negate_attr_obj->attribute_name, sizeof(negate_attr_obj->attribute_name), "%s", attribute_name);
|
||||
utarray_new(negate_attr_obj->object_uuids, &ut_rule_object_uuid_icd);
|
||||
HASH_ADD_STR(rule_compile_state->hit_negate_attribute_objects, attribute_name, negate_attr_obj);
|
||||
}
|
||||
|
||||
if (!utarray_find(tbl_object->object_uuids, &(condition_id_kv->key.object_uuid),
|
||||
if (!utarray_find(negate_attr_obj->object_uuids, &(condition_id_kv->key.object_uuid),
|
||||
compare_object_uuid)) {
|
||||
utarray_push_back(tbl_object->object_uuids, &(condition_id_kv->key.object_uuid));
|
||||
utarray_push_back(negate_attr_obj->object_uuids, &(condition_id_kv->key.object_uuid));
|
||||
}
|
||||
}
|
||||
|
||||
if (tbl_object != NULL) {
|
||||
utarray_sort(tbl_object->object_uuids, compare_object_uuid);
|
||||
if (negate_attr_obj != NULL) {
|
||||
utarray_sort(negate_attr_obj->object_uuids, compare_object_uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1842,17 +1842,17 @@ void rule_compile_state_not_logic_update(struct rule_compile_state *rule_compile
|
||||
rule_compile_state->Nth_scan = Nth_scan;
|
||||
utarray_clear(rule_compile_state->this_scan_hit_not_conditions);
|
||||
|
||||
struct table_object *tbl_object = NULL;
|
||||
HASH_FIND_STR(rule_compile_state->hit_not_tbl_objects, attribute_name, tbl_object);
|
||||
if (NULL == tbl_object) {
|
||||
struct negate_attribute_object *negate_attr_obj = NULL;
|
||||
HASH_FIND_STR(rule_compile_state->hit_negate_attribute_objects, attribute_name, negate_attr_obj);
|
||||
if (NULL == negate_attr_obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct condition_id_kv *condition_id_kv = NULL;
|
||||
for (size_t i = 0; i < utarray_len(tbl_object->object_uuids); i++) {
|
||||
for (size_t i = 0; i < utarray_len(negate_attr_obj->object_uuids); i++) {
|
||||
struct condition_query_key key;
|
||||
|
||||
uuid_t *object_uuid = utarray_eltptr(tbl_object->object_uuids, i);
|
||||
uuid_t *object_uuid = utarray_eltptr(negate_attr_obj->object_uuids, i);
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
snprintf(key.attribute_name, sizeof(key.attribute_name), "%s", attribute_name);
|
||||
|
||||
@@ -1156,6 +1156,42 @@ TEST_F(HsStringScan, StreamScanUTF8) {
|
||||
state = NULL;
|
||||
}
|
||||
|
||||
TEST_F(HsStringScan, InvisibleCharactor) {
|
||||
const char *hex_data = "00A12B3CEEFF";
|
||||
const char *table_name = "KEYWORDS_TABLE";
|
||||
const char *attribute_name = "KEYWORDS_TABLE";
|
||||
struct maat *maat_inst = HsStringScan::_shared_maat_inst;
|
||||
int thread_id = 0;
|
||||
|
||||
uuid_t results[ARRAY_SIZE];
|
||||
size_t n_hit_result = 0;
|
||||
struct maat_state *state = maat_state_new(maat_inst, thread_id);
|
||||
|
||||
size_t binary_data_length = strlen(hex_data) / 2;
|
||||
unsigned char binary_data[binary_data_length];
|
||||
|
||||
// 将十六进制字符串转换为二进制数据
|
||||
for (size_t i = 0; i < binary_data_length; i++) {
|
||||
sscanf(&hex_data[2 * i], "%2hhx", &binary_data[i]);
|
||||
}
|
||||
|
||||
memset(results, 0, sizeof(results));
|
||||
int ret = maat_scan_string(maat_inst, table_name, attribute_name, (char*)binary_data, binary_data_length,
|
||||
results, ARRAY_SIZE, &n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_HIT);
|
||||
EXPECT_EQ(n_hit_result, 1);
|
||||
char uuid_str[UUID_STR_LEN] = {0};
|
||||
uuid_unparse(results[0], uuid_str);
|
||||
EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000238");
|
||||
|
||||
ret = maat_scan_not_logic(maat_inst, table_name, attribute_name, results, ARRAY_SIZE,
|
||||
&n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_OK);
|
||||
|
||||
maat_state_free(state);
|
||||
state = NULL;
|
||||
}
|
||||
|
||||
TEST_F(HsStringScan, StreamInput) {
|
||||
uuid_t results[ARRAY_SIZE];
|
||||
size_t n_hit_result = 0;
|
||||
@@ -9985,139 +10021,6 @@ TEST_F(MaatCmd, SameSuperObjectRefByMultiRule) {
|
||||
state = NULL;
|
||||
}
|
||||
|
||||
TEST_F(MaatCmd, SameScanStatusWhenConditionUpdate_TSG6419) {//TODO: rule will update with all conditions
|
||||
const char* rule_table_name = "RULE_DEFAULT";
|
||||
const char* ip_table_name = "IP_PLUS_CONFIG";
|
||||
const char *ip_attribute_name = "IP_PLUS_CONFIG";
|
||||
const char *app_id_table_name = "APP_ID";
|
||||
const char *app_id_attribute_name = "APP_ID";
|
||||
int thread_id = 0, ret = 0;
|
||||
struct maat *maat_inst = MaatCmd::_shared_maat_inst;
|
||||
struct maat_state *state = maat_state_new(maat_inst, thread_id);
|
||||
|
||||
/* item11 -> object11 -> condition1 -> rule1
|
||||
/
|
||||
item21 -> object21 -> condition2 _/
|
||||
*/
|
||||
long long object11_id = maat_cmd_incrby(maat_inst, "SEQUENCE_OBJECT", 1);
|
||||
char object11_uuid_str[UUID_STR_LEN] = {0};
|
||||
snprintf(object11_uuid_str, UUID_STR_LEN, "00000000-0000-0000-0000-%012lld", object11_id);
|
||||
|
||||
long long item11_id = maat_cmd_incrby(maat_inst, "SEQUENCE_REGION", 1);
|
||||
char item11_uuid_str[UUID_STR_LEN] = {0};
|
||||
snprintf(item11_uuid_str, UUID_STR_LEN, "00000000-0000-0000-0000-%012lld", item11_id);
|
||||
ret = ip_table_set_line(maat_inst, ip_table_name, MAAT_OP_ADD, item11_uuid_str,
|
||||
object11_uuid_str, "192.168.2.1-192.168.2.4", NULL, 0);
|
||||
EXPECT_EQ(ret, 1);
|
||||
|
||||
long long object21_id = maat_cmd_incrby(maat_inst, "SEQUENCE_OBJECT", 1);
|
||||
char object21_uuid_str[UUID_STR_LEN] = {0};
|
||||
snprintf(object21_uuid_str, UUID_STR_LEN, "00000000-0000-0000-0000-%012lld", object21_id);
|
||||
|
||||
long long item21_id = maat_cmd_incrby(maat_inst, "SEQUENCE_REGION", 1);
|
||||
char item21_uuid_str[UUID_STR_LEN] = {0};
|
||||
snprintf(item21_uuid_str, UUID_STR_LEN, "00000000-0000-0000-0000-%012lld", item21_id);
|
||||
ret = interval_table_set_line(maat_inst, app_id_table_name, MAAT_OP_ADD,
|
||||
item21_uuid_str, object21_uuid_str, "31", 0);
|
||||
EXPECT_EQ(ret, 1);
|
||||
|
||||
long long rule1_id = maat_cmd_incrby(maat_inst, "TEST_SEQ", 1);
|
||||
char rule1_uuid_str[UUID_STR_LEN] = {0};
|
||||
snprintf(rule1_uuid_str, UUID_STR_LEN, "00000000-0000-0000-0000-%012lld", rule1_id);
|
||||
struct maat_cmd_and_condition and_conditions[3];
|
||||
and_conditions[0].negate_option = 0;
|
||||
and_conditions[0].or_condition_num = 1;
|
||||
and_conditions[0].or_conditions[0].attribute_name = ip_attribute_name;
|
||||
and_conditions[0].or_conditions[0].object_num = 1;
|
||||
and_conditions[0].or_conditions[0].object_uuids_str[0] = object11_uuid_str;
|
||||
and_conditions[1].negate_option = 0;
|
||||
and_conditions[1].or_condition_num = 1;
|
||||
and_conditions[1].or_conditions[0].attribute_name = app_id_attribute_name;
|
||||
and_conditions[1].or_conditions[0].object_num = 1;
|
||||
and_conditions[1].or_conditions[0].object_uuids_str[0] = object21_uuid_str;
|
||||
ret = rule_table_set_line(maat_inst, rule_table_name, MAAT_OP_ADD,
|
||||
rule1_uuid_str, and_conditions, 2, NULL, 0);
|
||||
EXPECT_EQ(ret, 1);
|
||||
|
||||
sleep(WAIT_FOR_EFFECTIVE_S * 2);
|
||||
|
||||
uuid_t results[ARRAY_SIZE];
|
||||
size_t n_hit_result = 0;
|
||||
uint32_t ip_addr;
|
||||
inet_pton(AF_INET, "192.168.2.2", &ip_addr);
|
||||
|
||||
ret = maat_scan_ipv4(maat_inst, ip_table_name, ip_attribute_name, ip_addr, results,
|
||||
ARRAY_SIZE, &n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT);
|
||||
|
||||
ret = maat_scan_not_logic(maat_inst, ip_table_name, ip_attribute_name, results, ARRAY_SIZE,
|
||||
&n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_OK);
|
||||
|
||||
int scan_app_id = 32;
|
||||
ret = maat_scan_integer(maat_inst, app_id_table_name, app_id_attribute_name, scan_app_id, results,
|
||||
ARRAY_SIZE, &n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_OK);
|
||||
|
||||
ret = maat_scan_not_logic(maat_inst, app_id_table_name, app_id_attribute_name, results, ARRAY_SIZE,
|
||||
&n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_OK);
|
||||
|
||||
/* item11 -> object11 -> condition1 -> rule1
|
||||
/
|
||||
item21 -> object21 -> condition2 _/
|
||||
item22 -> object22 -> condition3 _/
|
||||
*/
|
||||
long long object22_id = maat_cmd_incrby(maat_inst, "SEQUENCE_OBJECT", 1);
|
||||
char object22_uuid_str[UUID_STR_LEN] = {0};
|
||||
snprintf(object22_uuid_str, UUID_STR_LEN, "00000000-0000-0000-0000-%012lld", object22_id);
|
||||
|
||||
long long item22_id = maat_cmd_incrby(maat_inst, "SEQUENCE_REGION", 1);
|
||||
char item22_uuid_str[UUID_STR_LEN] = {0};
|
||||
snprintf(item22_uuid_str, UUID_STR_LEN, "00000000-0000-0000-0000-%012lld", item22_id);
|
||||
ret = interval_table_set_line(maat_inst, app_id_table_name, MAAT_OP_ADD,
|
||||
item22_uuid_str, object22_uuid_str, "32", 0);
|
||||
EXPECT_EQ(ret, 1);
|
||||
|
||||
ret = rule_table_set_line(maat_inst, rule_table_name, MAAT_OP_DEL,
|
||||
rule1_uuid_str, and_conditions, 2, NULL, 0);
|
||||
EXPECT_EQ(ret, 1);
|
||||
|
||||
and_conditions[2].negate_option = 0;
|
||||
and_conditions[2].or_condition_num = 1;
|
||||
and_conditions[2].or_conditions[0].attribute_name = app_id_attribute_name;
|
||||
and_conditions[2].or_conditions[0].object_num = 1;
|
||||
and_conditions[2].or_conditions[0].object_uuids_str[0] = object22_uuid_str;
|
||||
ret = rule_table_set_line(maat_inst, rule_table_name, MAAT_OP_ADD,
|
||||
rule1_uuid_str, and_conditions, 3, NULL, 0);
|
||||
EXPECT_EQ(ret, 1);
|
||||
|
||||
sleep(WAIT_FOR_EFFECTIVE_S * 2);
|
||||
|
||||
ret = maat_scan_integer(maat_inst, app_id_table_name, app_id_attribute_name, 31, results, ARRAY_SIZE,
|
||||
&n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT);
|
||||
|
||||
ret = maat_scan_not_logic(maat_inst, app_id_table_name, app_id_attribute_name, results, ARRAY_SIZE,
|
||||
&n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_OK);
|
||||
|
||||
ret = maat_scan_integer(maat_inst, app_id_table_name, app_id_attribute_name, scan_app_id, results,
|
||||
ARRAY_SIZE, &n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_HIT);
|
||||
EXPECT_EQ(n_hit_result, 1);
|
||||
char uuid_str[UUID_STR_LEN] = {0};
|
||||
uuid_unparse(results[0], uuid_str);
|
||||
EXPECT_STREQ(uuid_str, rule1_uuid_str);
|
||||
|
||||
ret = maat_scan_not_logic(maat_inst, app_id_table_name, app_id_attribute_name, results, ARRAY_SIZE,
|
||||
&n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_OK);
|
||||
|
||||
maat_state_free(state);
|
||||
state = NULL;
|
||||
}
|
||||
|
||||
TEST_F(MaatCmd, ObjectEdit) {
|
||||
const char *rule_table_name = "RULE_DEFAULT";
|
||||
const char *ip_table_name = "IP_PLUS_CONFIG";
|
||||
@@ -10480,7 +10383,7 @@ TEST_F(MaatCmd, StreamScanWhenExprTableIncUpdate) {
|
||||
uuid_t results[ARRAY_SIZE];
|
||||
size_t n_hit_result = 0;
|
||||
|
||||
struct maat_stream *stream = maat_stream_new(maat_inst, scan_table_name, scan_attribute_name, state);//TODO: create stream failed when expr_matcher is NULL
|
||||
struct maat_stream *stream = maat_stream_new(maat_inst, scan_table_name, scan_attribute_name, state);
|
||||
ret = maat_stream_scan(stream, scan_data, strlen(scan_data), results,
|
||||
ARRAY_SIZE, &n_hit_result, state);
|
||||
EXPECT_EQ(ret, MAAT_SCAN_OK);
|
||||
|
||||
@@ -2304,7 +2304,6 @@
|
||||
},
|
||||
{
|
||||
"attribute_name": "IP_PLUS_CONFIG",
|
||||
"negate_option": true,
|
||||
"object_uuids": [
|
||||
"00000000-0000-0000-0000-000000000014"
|
||||
]
|
||||
@@ -4202,6 +4201,36 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"uuid": "00000000-0000-0000-0000-000000000238",
|
||||
"service": 0,
|
||||
"action": 0,
|
||||
"do_blacklist": 0,
|
||||
"do_log": 0,
|
||||
"action_parameter": "null",
|
||||
"is_valid": "yes",
|
||||
"and_conditions": [
|
||||
{
|
||||
"attribute_name": "KEYWORDS_TABLE",
|
||||
"objects": [
|
||||
{
|
||||
"object_name": "238_keywords_object",
|
||||
"uuid": "00000000-0000-0000-0000-000000000264",
|
||||
"items": [
|
||||
{
|
||||
"table_type": "expr",
|
||||
"table_name": "KEYWORDS_TABLE",
|
||||
"table_content": {
|
||||
"expression": "(offset=0,depth=20)|00A12B3CEEFF|",
|
||||
"expr_type": "and"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"plugin_table": [
|
||||
|
||||
Reference in New Issue
Block a user