mirror of
https://github.com/mdbtools/mdbtools.git
synced 2026-01-02 12:27:09 +08:00
Improve bounds checking
No particular crashes, but replace strcpy / strncpy with snprintf and GLib functions wherever possible.
This commit is contained in:
@@ -60,7 +60,7 @@ int main(int argc, char **argv)
|
|||||||
fseek(in,(pg*pg_size),SEEK_SET);
|
fseek(in,(pg*pg_size),SEEK_SET);
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((length = fread(data,1,16,in))) {
|
while ((length = fread(data,1,16,in))) {
|
||||||
sprintf(addr, "%06lx", i);
|
snprintf(addr, sizeof(addr), "%06lx", i);
|
||||||
//if (!strcmp(&addr[3],"000") || (!jet4 && !strcmp(&addr[3],"800")) &&
|
//if (!strcmp(&addr[3],"000") || (!jet4 && !strcmp(&addr[3],"800")) &&
|
||||||
//pg) break;
|
//pg) break;
|
||||||
if (!strcmp(&addr[3],"000") || (!jet4 && !strcmp(&addr[3],"800"))) {
|
if (!strcmp(&addr[3],"000") || (!jet4 && !strcmp(&addr[3],"800"))) {
|
||||||
|
|||||||
@@ -493,23 +493,18 @@ mdb_get_index_name(int backend, MdbTableDef *table, MdbIndex *idx)
|
|||||||
switch(backend){
|
switch(backend){
|
||||||
case MDB_BACKEND_MYSQL:
|
case MDB_BACKEND_MYSQL:
|
||||||
// appending table name to index often makes it too long for mysql
|
// appending table name to index often makes it too long for mysql
|
||||||
index_name = malloc(strlen(idx->name)+5+1);
|
|
||||||
if (idx->index_type==1)
|
if (idx->index_type==1)
|
||||||
// for mysql name of primary key is not used
|
// for mysql name of primary key is not used
|
||||||
strcpy(index_name, "_pkey");
|
index_name = g_strdup("_pkey");
|
||||||
else {
|
else {
|
||||||
strcpy(index_name, idx->name);
|
index_name = g_strdup(idx->name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
index_name = malloc(strlen(table->name)+strlen(idx->name)+5+1);
|
|
||||||
strcpy(index_name, table->name);
|
|
||||||
if (idx->index_type==1)
|
if (idx->index_type==1)
|
||||||
strcat(index_name, "_pkey");
|
index_name = g_strconcat(table->name, "_pkey", NULL);
|
||||||
else {
|
else {
|
||||||
strcat(index_name, "_");
|
index_name = g_strconcat(table->name, "_", idx->name, "_idx", NULL);
|
||||||
strcat(index_name, idx->name);
|
|
||||||
strcat(index_name, "_idx");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
|
|||||||
msysobj.mdb = mdb;
|
msysobj.mdb = mdb;
|
||||||
msysobj.object_type = MDB_TABLE;
|
msysobj.object_type = MDB_TABLE;
|
||||||
msysobj.table_pg = 2;
|
msysobj.table_pg = 2;
|
||||||
strcpy(msysobj.object_name, "MSysObjects");
|
snprintf(msysobj.object_name, sizeof(msysobj.object_name), "%s", "MSysObjects");
|
||||||
|
|
||||||
/* mdb_table_dump(&msysobj); */
|
/* mdb_table_dump(&msysobj); */
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
|
|||||||
// (atol(obj_id) & 0x00FFFFFF), type, type, obj_name);
|
// (atol(obj_id) & 0x00FFFFFF), type, type, obj_name);
|
||||||
entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry));
|
entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry));
|
||||||
entry->mdb = mdb;
|
entry->mdb = mdb;
|
||||||
strcpy(entry->object_name, obj_name);
|
snprintf(entry->object_name, sizeof(entry->object_name), "%s", obj_name);
|
||||||
entry->object_type = (type & 0x7F);
|
entry->object_type = (type & 0x7F);
|
||||||
entry->table_pg = atol(obj_id) & 0x00FFFFFF;
|
entry->table_pg = atol(obj_id) & 0x00FFFFFF;
|
||||||
entry->flags = atol(obj_flags);
|
entry->flags = atol(obj_flags);
|
||||||
|
|||||||
@@ -188,8 +188,9 @@ mdb_ascii2unicode(MdbHandle *mdb, const char *src, size_t slen, char *dest, size
|
|||||||
dlen -= len_out;
|
dlen -= len_out;
|
||||||
#else
|
#else
|
||||||
if (IS_JET3(mdb)) {
|
if (IS_JET3(mdb)) {
|
||||||
dlen = MIN(len_in, len_out);
|
int count;
|
||||||
strncpy(out_ptr, in_ptr, dlen);
|
snprintf(out_ptr, len_out, "%*s%n", (int)len_in, in_ptr, &count);
|
||||||
|
dlen = count;
|
||||||
} else {
|
} else {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
slen = MIN(len_in, len_out/2);
|
slen = MIN(len_in, len_out/2);
|
||||||
|
|||||||
@@ -123,9 +123,7 @@ mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len)
|
|||||||
dsize = mdb_get_int16(kkd, pos + 6);
|
dsize = mdb_get_int16(kkd, pos + 6);
|
||||||
if (dsize < 0 || pos + 8 + dsize > len)
|
if (dsize < 0 || pos + 8 + dsize > len)
|
||||||
break;
|
break;
|
||||||
value = g_malloc(dsize + 1);
|
value = g_strdup_printf("%*s", dsize, &kkd[pos+8]);
|
||||||
strncpy(value, &kkd[pos + 8], dsize);
|
|
||||||
value[dsize] = '\0';
|
|
||||||
name = g_ptr_array_index(names,elem);
|
name = g_ptr_array_index(names,elem);
|
||||||
if (mdb_get_option(MDB_DEBUG_PROPS)) {
|
if (mdb_get_option(MDB_DEBUG_PROPS)) {
|
||||||
fprintf(stderr, "%02d ",i++);
|
fprintf(stderr, "%02d ",i++);
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ int mdb_test_int(MdbSargNode *node, gint32 i)
|
|||||||
static double poor_mans_trunc(double x)
|
static double poor_mans_trunc(double x)
|
||||||
{
|
{
|
||||||
char buf[16];
|
char buf[16];
|
||||||
sprintf(buf, "%.6f", x);
|
snprintf(buf, sizeof(buf), "%.6f", x);
|
||||||
sscanf(buf, "%lf", &x);
|
sscanf(buf, "%lf", &x);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry)
|
|||||||
|
|
||||||
table = (MdbTableDef *) g_malloc0(sizeof(MdbTableDef));
|
table = (MdbTableDef *) g_malloc0(sizeof(MdbTableDef));
|
||||||
table->entry=entry;
|
table->entry=entry;
|
||||||
strcpy(table->name, entry->object_name);
|
snprintf(table->name, sizeof(table->name), "%s", entry->object_name);
|
||||||
|
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ void
|
|||||||
mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed)
|
mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed)
|
||||||
{
|
{
|
||||||
memset(tcol,0,sizeof(MdbColumn));
|
memset(tcol,0,sizeof(MdbColumn));
|
||||||
strcpy(tcol->name, col_name);
|
snprintf(tcol->name, sizeof(tcol->name), "%s", col_name);
|
||||||
tcol->col_type = col_type;
|
tcol->col_type = col_type;
|
||||||
if ((col_type == MDB_TEXT) || (col_type == MDB_MEMO)) {
|
if ((col_type == MDB_TEXT) || (col_type == MDB_MEMO)) {
|
||||||
tcol->col_size = col_size;
|
tcol->col_size = col_size;
|
||||||
@@ -57,7 +57,7 @@ mdb_create_temp_table(MdbHandle *mdb, char *name)
|
|||||||
entry->mdb = mdb;
|
entry->mdb = mdb;
|
||||||
entry->object_type = MDB_TABLE;
|
entry->object_type = MDB_TABLE;
|
||||||
entry->table_pg = 0;
|
entry->table_pg = 0;
|
||||||
strcpy(entry->object_name, name);
|
snprintf(entry->object_name, sizeof(entry->object_name), "%s", name);
|
||||||
|
|
||||||
table = mdb_alloc_tabledef(entry);
|
table = mdb_alloc_tabledef(entry);
|
||||||
table->columns = g_ptr_array_new();
|
table->columns = g_ptr_array_new();
|
||||||
|
|||||||
@@ -1228,8 +1228,7 @@ SQLRETURN SQL_API SQLPrepare(
|
|||||||
|
|
||||||
TRACE("SQLPrepare");
|
TRACE("SQLPrepare");
|
||||||
|
|
||||||
strncpy(stmt->query, (char*)szSqlStr, sqllen);
|
snprintf(stmt->query, sizeof(stmt->query), "%*s", sqllen, (char*)szSqlStr);
|
||||||
stmt->query[sqllen]='\0';
|
|
||||||
|
|
||||||
return SQL_SUCCESS;
|
return SQL_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -1349,9 +1348,9 @@ SQLRETURN SQL_API SQLColumns(
|
|||||||
for (j=0; j<table->num_cols; j++) {
|
for (j=0; j<table->num_cols; j++) {
|
||||||
col = g_ptr_array_index(table->columns, j);
|
col = g_ptr_array_index(table->columns, j);
|
||||||
|
|
||||||
ts2 = mdb_ascii2unicode(mdb, table->name, 0, (char*)t2, MDB_BIND_SIZE);
|
ts2 = mdb_ascii2unicode(mdb, table->name, 0, (char*)t2, sizeof(t2));
|
||||||
ts3 = mdb_ascii2unicode(mdb, col->name, 0, (char*)t3, MDB_BIND_SIZE);
|
ts3 = mdb_ascii2unicode(mdb, col->name, 0, (char*)t3, sizeof(t3));
|
||||||
ts5 = mdb_ascii2unicode(mdb, _odbc_get_client_type_name(col), 0, (char*)t5, MDB_BIND_SIZE);
|
ts5 = mdb_ascii2unicode(mdb, _odbc_get_client_type_name(col), 0, (char*)t5, sizeof(t5));
|
||||||
|
|
||||||
nullable = SQL_NO_NULLS;
|
nullable = SQL_NO_NULLS;
|
||||||
datatype = _odbc_get_client_type(col);
|
datatype = _odbc_get_client_type(col);
|
||||||
@@ -1938,15 +1937,15 @@ SQLRETURN SQL_API SQLGetInfo(
|
|||||||
break;
|
break;
|
||||||
case SQL_DBMS_NAME:
|
case SQL_DBMS_NAME:
|
||||||
if (rgbInfoValue)
|
if (rgbInfoValue)
|
||||||
strncpy(rgbInfoValue, "MDBTOOLS", cbInfoValueMax);
|
snprintf(rgbInfoValue, cbInfoValueMax, "%s", "MDBTOOLS");
|
||||||
if (pcbInfoValue)
|
if (pcbInfoValue)
|
||||||
*pcbInfoValue = 9;
|
*pcbInfoValue = sizeof("MDBTOOLS");
|
||||||
break;
|
break;
|
||||||
case SQL_DBMS_VER:
|
case SQL_DBMS_VER:
|
||||||
if (rgbInfoValue)
|
if (rgbInfoValue)
|
||||||
strncpy(rgbInfoValue, VERSION, cbInfoValueMax);
|
snprintf(rgbInfoValue, cbInfoValueMax, "%s", VERSION);
|
||||||
if (pcbInfoValue)
|
if (pcbInfoValue)
|
||||||
*pcbInfoValue = sizeof(VERSION)+1;
|
*pcbInfoValue = sizeof(VERSION);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (pcbInfoValue)
|
if (pcbInfoValue)
|
||||||
@@ -2039,11 +2038,11 @@ SQLRETURN SQL_API SQLGetTypeInfo(
|
|||||||
if (fSqlType && (fSqlType != type_info[i].data_type))
|
if (fSqlType && (fSqlType != type_info[i].data_type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ts0 = mdb_ascii2unicode(mdb, (char*)type_info[i].type_name, 0, (char*)t0, MDB_BIND_SIZE);
|
ts0 = mdb_ascii2unicode(mdb, (char*)type_info[i].type_name, 0, (char*)t0, sizeof(t0));
|
||||||
ts3 = mdb_ascii2unicode(mdb, (char*)type_info[i].literal_prefix, 0, (char*)t3, MDB_BIND_SIZE);
|
ts3 = mdb_ascii2unicode(mdb, (char*)type_info[i].literal_prefix, 0, (char*)t3, sizeof(t3));
|
||||||
ts4 = mdb_ascii2unicode(mdb, (char*)type_info[i].literal_suffix, 0, (char*)t4, MDB_BIND_SIZE);
|
ts4 = mdb_ascii2unicode(mdb, (char*)type_info[i].literal_suffix, 0, (char*)t4, sizeof(t4));
|
||||||
ts5 = mdb_ascii2unicode(mdb, (char*)type_info[i].create_params, 0, (char*)t5, MDB_BIND_SIZE);
|
ts5 = mdb_ascii2unicode(mdb, (char*)type_info[i].create_params, 0, (char*)t5, sizeof(t5));
|
||||||
ts12 = mdb_ascii2unicode(mdb, (char*)type_info[i].local_type_name, 0, (char*)t12, MDB_BIND_SIZE);
|
ts12 = mdb_ascii2unicode(mdb, (char*)type_info[i].local_type_name, 0, (char*)t12, sizeof(t12));
|
||||||
|
|
||||||
FILL_FIELD(&fields[0], t0, ts0);
|
FILL_FIELD(&fields[0], t0, ts0);
|
||||||
FILL_FIELD(&fields[1],&type_info[i].data_type, 0);
|
FILL_FIELD(&fields[1],&type_info[i].data_type, 0);
|
||||||
@@ -2195,8 +2194,8 @@ SQLRETURN SQL_API SQLTables( //sz* not used, so Unicode API not required.
|
|||||||
FILL_FIELD(&fields[j], NULL, 0);
|
FILL_FIELD(&fields[j], NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ts2 = mdb_ascii2unicode(mdb, entry->object_name, 0, (char*)t2, MDB_BIND_SIZE);
|
ts2 = mdb_ascii2unicode(mdb, entry->object_name, 0, (char*)t2, sizeof(t2));
|
||||||
ts3 = mdb_ascii2unicode(mdb, table_types[ttype], 0, (char*)t3, MDB_BIND_SIZE);
|
ts3 = mdb_ascii2unicode(mdb, table_types[ttype], 0, (char*)t3, sizeof(t3));
|
||||||
|
|
||||||
FILL_FIELD(&fields[2], t2, ts2);
|
FILL_FIELD(&fields[2], t2, ts2);
|
||||||
FILL_FIELD(&fields[3], t3, ts3);
|
FILL_FIELD(&fields[3], t3, ts3);
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ mdb_sql_strptime(MdbSQL *sql, char *data, char *format)
|
|||||||
if (date < 2 && date > 1) date--;
|
if (date < 2 && date > 1) date--;
|
||||||
if ((pszDate=malloc(16))) {
|
if ((pszDate=malloc(16))) {
|
||||||
char cLocale=localeconv()->decimal_point[0], *p;
|
char cLocale=localeconv()->decimal_point[0], *p;
|
||||||
sprintf(pszDate, "%lf", date);
|
snprintf(pszDate, 16, "%lf", date);
|
||||||
if (cLocale!='.') for (p=pszDate; *p; p++) if (*p==cLocale) *p='.';
|
if (cLocale!='.') for (p=pszDate; *p; p++) if (*p==cLocale) *p='.';
|
||||||
}
|
}
|
||||||
return pszDate;
|
return pszDate;
|
||||||
@@ -467,7 +467,6 @@ mdb_sql_eval_expr(MdbSQL *sql, char *const1, int op, char *const2)
|
|||||||
int
|
int
|
||||||
mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
|
mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
|
||||||
{
|
{
|
||||||
int lastchar;
|
|
||||||
char *p;
|
char *p;
|
||||||
MdbSargNode *node;
|
MdbSargNode *node;
|
||||||
|
|
||||||
@@ -485,9 +484,7 @@ mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
|
|||||||
** column definition can be checked for validity
|
** column definition can be checked for validity
|
||||||
*/
|
*/
|
||||||
if (constant[0]=='\'') {
|
if (constant[0]=='\'') {
|
||||||
lastchar = strlen(constant) > 256 ? 256 : strlen(constant);
|
snprintf(node->value.s, sizeof(node->value.s), "%*s", (int)strlen(constant) - 2, &constant[1]);
|
||||||
strncpy(node->value.s, &constant[1], lastchar - 2);;
|
|
||||||
node->value.s[lastchar - 1]='\0';
|
|
||||||
node->val_type = MDB_TEXT;
|
node->val_type = MDB_TEXT;
|
||||||
} else if ((p=strchr(constant, '.'))) {
|
} else if ((p=strchr(constant, '.'))) {
|
||||||
*p=localeconv()->decimal_point[0];
|
*p=localeconv()->decimal_point[0];
|
||||||
@@ -652,7 +649,7 @@ void mdb_sql_listtables(MdbSQL *sql)
|
|||||||
entry = g_ptr_array_index (mdb->catalog, i);
|
entry = g_ptr_array_index (mdb->catalog, i);
|
||||||
if (mdb_is_user_table(entry)) {
|
if (mdb_is_user_table(entry)) {
|
||||||
//col = g_ptr_array_index(table->columns,0);
|
//col = g_ptr_array_index(table->columns,0);
|
||||||
tmpsiz = mdb_ascii2unicode(mdb, entry->object_name, 0, tmpstr, 100);
|
tmpsiz = mdb_ascii2unicode(mdb, entry->object_name, 0, tmpstr, sizeof(tmpstr));
|
||||||
mdb_fill_temp_field(&fields[0],tmpstr, tmpsiz, 0,0,0,0);
|
mdb_fill_temp_field(&fields[0],tmpstr, tmpsiz, 0,0,0,0);
|
||||||
row_size = mdb_pack_row(ttable, row_buffer, 1, fields);
|
row_size = mdb_pack_row(ttable, row_buffer, 1, fields);
|
||||||
mdb_add_row_to_pg(ttable,row_buffer, row_size);
|
mdb_add_row_to_pg(ttable,row_buffer, row_size);
|
||||||
@@ -716,15 +713,15 @@ void mdb_sql_describe_table(MdbSQL *sql)
|
|||||||
for (i=0;i<table->num_cols;i++) {
|
for (i=0;i<table->num_cols;i++) {
|
||||||
|
|
||||||
col = g_ptr_array_index(table->columns,i);
|
col = g_ptr_array_index(table->columns,i);
|
||||||
tmpsiz = mdb_ascii2unicode(mdb, col->name, 0, col_name, 100);
|
tmpsiz = mdb_ascii2unicode(mdb, col->name, 0, col_name, sizeof(col_name));
|
||||||
mdb_fill_temp_field(&fields[0],col_name, tmpsiz, 0,0,0,0);
|
mdb_fill_temp_field(&fields[0],col_name, tmpsiz, 0,0,0,0);
|
||||||
|
|
||||||
strcpy(tmpstr, mdb_get_colbacktype_string(col));
|
snprintf(tmpstr, sizeof(tmpstr), "%s", mdb_get_colbacktype_string(col));
|
||||||
tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, col_type, 100);
|
tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, col_type, sizeof(col_type));
|
||||||
mdb_fill_temp_field(&fields[1],col_type, tmpsiz, 0,0,0,1);
|
mdb_fill_temp_field(&fields[1],col_type, tmpsiz, 0,0,0,1);
|
||||||
|
|
||||||
sprintf(tmpstr,"%d",col->col_size);
|
snprintf(tmpstr, sizeof(tmpstr), "%d", col->col_size);
|
||||||
tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, col_size, 100);
|
tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, col_size, sizeof(col_size));
|
||||||
mdb_fill_temp_field(&fields[2],col_size, tmpsiz, 0,0,0,2);
|
mdb_fill_temp_field(&fields[2],col_size, tmpsiz, 0,0,0,2);
|
||||||
|
|
||||||
row_size = mdb_pack_row(ttable, row_buffer, 3, fields);
|
row_size = mdb_pack_row(ttable, row_buffer, 3, fields);
|
||||||
@@ -814,8 +811,8 @@ int found = 0;
|
|||||||
int row_size, tmpsiz;
|
int row_size, tmpsiz;
|
||||||
|
|
||||||
mdb_sql_add_temp_col(sql, ttable, 0, "count", MDB_TEXT, 30, 0);
|
mdb_sql_add_temp_col(sql, ttable, 0, "count", MDB_TEXT, 30, 0);
|
||||||
sprintf(tmpstr,"%d",table->num_rows);
|
snprintf(tmpstr, sizeof(tmpstr), "%d", table->num_rows);
|
||||||
tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, row_cnt, 32);
|
tmpsiz = mdb_ascii2unicode(mdb, tmpstr, 0, row_cnt, sizeof(row_cnt));
|
||||||
mdb_fill_temp_field(&fields[0],row_cnt, tmpsiz, 0,0,0,0);
|
mdb_fill_temp_field(&fields[0],row_cnt, tmpsiz, 0,0,0,0);
|
||||||
row_size = mdb_pack_row(ttable, row_buffer, 1, fields);
|
row_size = mdb_pack_row(ttable, row_buffer, 1, fields);
|
||||||
mdb_add_row_to_pg(ttable,row_buffer, row_size);
|
mdb_add_row_to_pg(ttable,row_buffer, row_size);
|
||||||
|
|||||||
@@ -78,10 +78,8 @@ int i = 0;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf = (char *) malloc(strlen(line)+1);
|
|
||||||
strcpy(buf,line);
|
|
||||||
|
|
||||||
return buf;
|
return g_strdup(line);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -425,7 +423,7 @@ main(int argc, char **argv)
|
|||||||
} else if (s[strlen(s)-1]=='\n')
|
} else if (s[strlen(s)-1]=='\n')
|
||||||
s[strlen(s)-1]=0;
|
s[strlen(s)-1]=0;
|
||||||
} else {
|
} else {
|
||||||
sprintf(prompt, "%d => ", line);
|
snprintf(prompt, sizeof(prompt), "%d => ", line);
|
||||||
s=readline(prompt);
|
s=readline(prompt);
|
||||||
if (!s)
|
if (!s)
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user