tweaks: replace a function call or a macro with a hard number
Verify at startup that the number is not too small.
Этот коммит содержится в:
родитель
754aa8ba79
Коммит
aedc3ddd49
43
src/chars.c
43
src/chars.c
@ -77,7 +77,7 @@ bool is_alpha_mbchar(const char *c)
|
|||||||
if (use_utf8) {
|
if (use_utf8) {
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
|
|
||||||
if (mbtowc(&wc, c, MB_CUR_MAX) < 0) {
|
if (mbtowc(&wc, c, MAXCHARLEN) < 0) {
|
||||||
mbtowc_reset();
|
mbtowc_reset();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ bool is_alnum_mbchar(const char *c)
|
|||||||
if (use_utf8) {
|
if (use_utf8) {
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
|
|
||||||
if (mbtowc(&wc, c, MB_CUR_MAX) < 0) {
|
if (mbtowc(&wc, c, MAXCHARLEN) < 0) {
|
||||||
mbtowc_reset();
|
mbtowc_reset();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ bool is_blank_mbchar(const char *c)
|
|||||||
if (use_utf8) {
|
if (use_utf8) {
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
|
|
||||||
if (mbtowc(&wc, c, MB_CUR_MAX) < 0) {
|
if (mbtowc(&wc, c, MAXCHARLEN) < 0) {
|
||||||
mbtowc_reset();
|
mbtowc_reset();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ bool is_punct_mbchar(const char *c)
|
|||||||
if (use_utf8) {
|
if (use_utf8) {
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
|
|
||||||
if (mbtowc(&wc, c, MB_CUR_MAX) < 0) {
|
if (mbtowc(&wc, c, MAXCHARLEN) < 0) {
|
||||||
mbtowc_reset();
|
mbtowc_reset();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -188,7 +188,7 @@ bool is_word_mbchar(const char *c, bool allow_punct)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (word_chars != NULL && *word_chars != '\0') {
|
if (word_chars != NULL && *word_chars != '\0') {
|
||||||
char symbol[mb_cur_max() + 1];
|
char symbol[MAXCHARLEN + 1];
|
||||||
int symlen = parse_mbchar(c, symbol, NULL);
|
int symlen = parse_mbchar(c, symbol, NULL);
|
||||||
|
|
||||||
symbol[symlen] = '\0';
|
symbol[symlen] = '\0';
|
||||||
@ -240,7 +240,7 @@ int length_of_char(const char *c, int *width)
|
|||||||
#ifdef ENABLE_UTF8
|
#ifdef ENABLE_UTF8
|
||||||
if (use_utf8) {
|
if (use_utf8) {
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
int charlen = mbtowc(&wc, c, MB_CUR_MAX);
|
int charlen = mbtowc(&wc, c, MAXCHARLEN);
|
||||||
|
|
||||||
/* If the sequence is invalid... */
|
/* If the sequence is invalid... */
|
||||||
if (charlen < 0) {
|
if (charlen < 0) {
|
||||||
@ -273,7 +273,7 @@ int mbwidth(const char *c)
|
|||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
int width;
|
int width;
|
||||||
|
|
||||||
if (mbtowc(&wc, c, MB_CUR_MAX) < 0) {
|
if (mbtowc(&wc, c, MAXCHARLEN) < 0) {
|
||||||
mbtowc_reset();
|
mbtowc_reset();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -289,17 +289,6 @@ int mbwidth(const char *c)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the maximum length (in bytes) of a character. */
|
|
||||||
int mb_cur_max(void)
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_UTF8
|
|
||||||
if (use_utf8)
|
|
||||||
return MB_CUR_MAX;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert the Unicode value in chr to a multibyte character, if possible.
|
/* Convert the Unicode value in chr to a multibyte character, if possible.
|
||||||
* If the conversion succeeds, return the (dynamically allocated) multibyte
|
* If the conversion succeeds, return the (dynamically allocated) multibyte
|
||||||
* character and its length. Otherwise, return an undefined (dynamically
|
* character and its length. Otherwise, return an undefined (dynamically
|
||||||
@ -310,7 +299,7 @@ char *make_mbchar(long chr, int *chr_mb_len)
|
|||||||
|
|
||||||
#ifdef ENABLE_UTF8
|
#ifdef ENABLE_UTF8
|
||||||
if (use_utf8) {
|
if (use_utf8) {
|
||||||
chr_mb = charalloc(MB_CUR_MAX);
|
chr_mb = charalloc(MAXCHARLEN);
|
||||||
*chr_mb_len = wctomb(chr_mb, (wchar_t)chr);
|
*chr_mb_len = wctomb(chr_mb, (wchar_t)chr);
|
||||||
|
|
||||||
/* Reject invalid Unicode characters. */
|
/* Reject invalid Unicode characters. */
|
||||||
@ -340,7 +329,7 @@ int parse_mbchar(const char *buf, char *chr, size_t *col)
|
|||||||
#ifdef ENABLE_UTF8
|
#ifdef ENABLE_UTF8
|
||||||
if (use_utf8) {
|
if (use_utf8) {
|
||||||
/* Get the number of bytes in the multibyte character. */
|
/* Get the number of bytes in the multibyte character. */
|
||||||
length = mblen(buf, MB_CUR_MAX);
|
length = mblen(buf, MAXCHARLEN);
|
||||||
|
|
||||||
/* When the multibyte sequence is invalid, only take the first byte. */
|
/* When the multibyte sequence is invalid, only take the first byte. */
|
||||||
if (length <= 0) {
|
if (length <= 0) {
|
||||||
@ -410,10 +399,10 @@ size_t move_mbleft(const char *buf, size_t pos)
|
|||||||
/* There is no library function to move backward one multibyte
|
/* There is no library function to move backward one multibyte
|
||||||
* character. So we just start groping for one at the farthest
|
* character. So we just start groping for one at the farthest
|
||||||
* possible point. */
|
* possible point. */
|
||||||
if (mb_cur_max() > pos)
|
if (pos < MAXCHARLEN)
|
||||||
before = 0;
|
before = 0;
|
||||||
else
|
else
|
||||||
before = pos - mb_cur_max();
|
before = pos - MAXCHARLEN;
|
||||||
|
|
||||||
while (before < pos) {
|
while (before < pos) {
|
||||||
char_len = parse_mbchar(buf + before, NULL, NULL);
|
char_len = parse_mbchar(buf + before, NULL, NULL);
|
||||||
@ -446,12 +435,12 @@ int mbstrncasecmp(const char *s1, const char *s2, size_t n)
|
|||||||
while (*s1 != '\0' && *s2 != '\0' && n > 0) {
|
while (*s1 != '\0' && *s2 != '\0' && n > 0) {
|
||||||
bool bad1 = FALSE, bad2 = FALSE;
|
bool bad1 = FALSE, bad2 = FALSE;
|
||||||
|
|
||||||
if (mbtowc(&wc1, s1, MB_CUR_MAX) < 0) {
|
if (mbtowc(&wc1, s1, MAXCHARLEN) < 0) {
|
||||||
mbtowc_reset();
|
mbtowc_reset();
|
||||||
bad1 = TRUE;
|
bad1 = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mbtowc(&wc2, s2, MB_CUR_MAX) < 0) {
|
if (mbtowc(&wc2, s2, MAXCHARLEN) < 0) {
|
||||||
mbtowc_reset();
|
mbtowc_reset();
|
||||||
bad2 = TRUE;
|
bad2 = TRUE;
|
||||||
}
|
}
|
||||||
@ -625,11 +614,11 @@ char *mbstrchr(const char *s, const char *c)
|
|||||||
#ifdef ENABLE_UTF8
|
#ifdef ENABLE_UTF8
|
||||||
if (use_utf8) {
|
if (use_utf8) {
|
||||||
bool bad_s_mb = FALSE, bad_c_mb = FALSE;
|
bool bad_s_mb = FALSE, bad_c_mb = FALSE;
|
||||||
char symbol[MB_CUR_MAX];
|
char symbol[MAXCHARLEN];
|
||||||
const char *q = s;
|
const char *q = s;
|
||||||
wchar_t ws, wc;
|
wchar_t ws, wc;
|
||||||
|
|
||||||
if (mbtowc(&wc, c, MB_CUR_MAX) < 0) {
|
if (mbtowc(&wc, c, MAXCHARLEN) < 0) {
|
||||||
mbtowc_reset();
|
mbtowc_reset();
|
||||||
wc = (unsigned char)*c;
|
wc = (unsigned char)*c;
|
||||||
bad_c_mb = TRUE;
|
bad_c_mb = TRUE;
|
||||||
@ -749,7 +738,7 @@ bool has_blank_mbchars(const char *s)
|
|||||||
{
|
{
|
||||||
#ifdef ENABLE_UTF8
|
#ifdef ENABLE_UTF8
|
||||||
if (use_utf8) {
|
if (use_utf8) {
|
||||||
char symbol[MB_CUR_MAX];
|
char symbol[MAXCHARLEN];
|
||||||
|
|
||||||
for (; *s != '\0'; s += move_mbright(s, 0)) {
|
for (; *s != '\0'; s += move_mbright(s, 0)) {
|
||||||
parse_mbchar(s, symbol, NULL);
|
parse_mbchar(s, symbol, NULL);
|
||||||
|
@ -2633,7 +2633,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
|
|||||||
char *mzero, *glued;
|
char *mzero, *glued;
|
||||||
const char *lastslash = revstrstr(buf, "/", buf + *place);
|
const char *lastslash = revstrstr(buf, "/", buf + *place);
|
||||||
size_t lastslash_len = (lastslash == NULL) ? 0 : lastslash - buf + 1;
|
size_t lastslash_len = (lastslash == NULL) ? 0 : lastslash - buf + 1;
|
||||||
char char1[mb_cur_max()], char2[mb_cur_max()];
|
char char1[MAXCHARLEN], char2[MAXCHARLEN];
|
||||||
int len1, len2;
|
int len1, len2;
|
||||||
|
|
||||||
/* Get the number of characters that all matches have in common. */
|
/* Get the number of characters that all matches have in common. */
|
||||||
|
@ -370,7 +370,7 @@ void help_init(void)
|
|||||||
* plus one or two \n's. */
|
* plus one or two \n's. */
|
||||||
for (f = allfuncs; f != NULL; f = f->next)
|
for (f = allfuncs; f != NULL; f = f->next)
|
||||||
if (f->menus & currmenu)
|
if (f->menus & currmenu)
|
||||||
allocsize += (16 * mb_cur_max()) + strlen(f->help) + 2;
|
allocsize += (16 * MAXCHARLEN) + strlen(f->help) + 2;
|
||||||
|
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
/* If we're on the main list, we also count the toggle help text.
|
/* If we're on the main list, we also count the toggle help text.
|
||||||
|
@ -1812,7 +1812,7 @@ int do_mouse(void)
|
|||||||
* TRUE. */
|
* TRUE. */
|
||||||
void do_output(char *output, size_t output_len, bool allow_cntrls)
|
void do_output(char *output, size_t output_len, bool allow_cntrls)
|
||||||
{
|
{
|
||||||
char onechar[mb_cur_max()];
|
char onechar[MAXCHARLEN];
|
||||||
int char_len;
|
int char_len;
|
||||||
size_t current_len = strlen(openfile->current->data);
|
size_t current_len = strlen(openfile->current->data);
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@ -2016,6 +2016,10 @@ int main(int argc, char **argv)
|
|||||||
textdomain(PACKAGE);
|
textdomain(PACKAGE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (MB_CUR_MAX > MAXCHARLEN)
|
||||||
|
fprintf(stderr, "Unexpected large character size: %i bytes"
|
||||||
|
" -- please report a bug\n", MB_CUR_MAX);
|
||||||
|
|
||||||
#if defined(DISABLE_NANORC) && defined(DISABLE_ROOTWRAPPING)
|
#if defined(DISABLE_NANORC) && defined(DISABLE_ROOTWRAPPING)
|
||||||
/* If we don't have rcfile support, --disable-wrapping-as-root is
|
/* If we don't have rcfile support, --disable-wrapping-as-root is
|
||||||
* used, and we're root, turn wrapping off. */
|
* used, and we're root, turn wrapping off. */
|
||||||
|
@ -68,6 +68,13 @@
|
|||||||
#define charmove(dest, src, n) memmove(dest, src, (n) * sizeof(char))
|
#define charmove(dest, src, n) memmove(dest, src, (n) * sizeof(char))
|
||||||
#define charset(dest, src, n) memset(dest, src, (n) * sizeof(char))
|
#define charset(dest, src, n) memset(dest, src, (n) * sizeof(char))
|
||||||
|
|
||||||
|
/* In UTF-8 a character is at most six bytes long. */
|
||||||
|
#ifdef ENABLE_UTF8
|
||||||
|
#define MAXCHARLEN 6
|
||||||
|
#else
|
||||||
|
#define MAXCHARLEN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set a default value for PATH_MAX if there isn't one. */
|
/* Set a default value for PATH_MAX if there isn't one. */
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
#define PATH_MAX 4096
|
#define PATH_MAX 4096
|
||||||
|
@ -197,7 +197,7 @@ void do_statusbar_output(int *the_input, size_t input_len,
|
|||||||
bool filtering)
|
bool filtering)
|
||||||
{
|
{
|
||||||
char *output = charalloc(input_len + 1);
|
char *output = charalloc(input_len + 1);
|
||||||
char onechar[mb_cur_max()];
|
char onechar[MAXCHARLEN];
|
||||||
int i, char_len;
|
int i, char_len;
|
||||||
|
|
||||||
/* Copy the typed stuff so it can be treated. */
|
/* Copy the typed stuff so it can be treated. */
|
||||||
@ -631,9 +631,9 @@ int do_prompt(bool allow_tabs, bool allow_files,
|
|||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
redo_theprompt:
|
redo_theprompt:
|
||||||
#endif
|
#endif
|
||||||
prompt = charalloc((COLS * mb_cur_max()) + 1);
|
prompt = charalloc((COLS * MAXCHARLEN) + 1);
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
vsnprintf(prompt, COLS * mb_cur_max(), msg, ap);
|
vsnprintf(prompt, COLS * MAXCHARLEN, msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
/* Reserve five columns for colon plus angles plus answer, ":<aa>". */
|
/* Reserve five columns for colon plus angles plus answer, ":<aa>". */
|
||||||
prompt[actual_x(prompt, (COLS < 5) ? 0 : COLS - 5)] = '\0';
|
prompt[actual_x(prompt, (COLS < 5) ? 0 : COLS - 5)] = '\0';
|
||||||
|
@ -199,7 +199,6 @@ char control_rep(const signed char c);
|
|||||||
char control_mbrep(const char *c, bool isdata);
|
char control_mbrep(const char *c, bool isdata);
|
||||||
int length_of_char(const char *c, int *width);
|
int length_of_char(const char *c, int *width);
|
||||||
int mbwidth(const char *c);
|
int mbwidth(const char *c);
|
||||||
int mb_cur_max(void);
|
|
||||||
char *make_mbchar(long chr, int *chr_mb_len);
|
char *make_mbchar(long chr, int *chr_mb_len);
|
||||||
int parse_mbchar(const char *buf, char *chr, size_t *col);
|
int parse_mbchar(const char *buf, char *chr, size_t *col);
|
||||||
size_t move_mbleft(const char *buf, size_t pos);
|
size_t move_mbleft(const char *buf, size_t pos);
|
||||||
|
@ -1057,12 +1057,12 @@ void do_find_bracket(void)
|
|||||||
wanted_ch_len = parse_mbchar(wanted_ch, NULL, NULL);
|
wanted_ch_len = parse_mbchar(wanted_ch, NULL, NULL);
|
||||||
|
|
||||||
/* Fill bracket_set in with the values of ch and wanted_ch. */
|
/* Fill bracket_set in with the values of ch and wanted_ch. */
|
||||||
bracket_set = charalloc((mb_cur_max() * 2) + 1);
|
bracket_set = charalloc((MAXCHARLEN * 2) + 1);
|
||||||
strncpy(bracket_set, ch, ch_len);
|
strncpy(bracket_set, ch, ch_len);
|
||||||
strncpy(bracket_set + ch_len, wanted_ch, wanted_ch_len);
|
strncpy(bracket_set + ch_len, wanted_ch, wanted_ch_len);
|
||||||
bracket_set[ch_len + wanted_ch_len] = '\0';
|
bracket_set[ch_len + wanted_ch_len] = '\0';
|
||||||
|
|
||||||
found_ch = charalloc(mb_cur_max() + 1);
|
found_ch = charalloc(MAXCHARLEN + 1);
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
if (find_bracket_match(reverse, bracket_set)) {
|
if (find_bracket_match(reverse, bracket_set)) {
|
||||||
|
@ -1221,7 +1221,7 @@ void add_undo(undo_type action)
|
|||||||
u->xflags = WAS_FINAL_BACKSPACE;
|
u->xflags = WAS_FINAL_BACKSPACE;
|
||||||
case DEL:
|
case DEL:
|
||||||
if (openfile->current->data[openfile->current_x] != '\0') {
|
if (openfile->current->data[openfile->current_x] != '\0') {
|
||||||
char *char_buf = charalloc(mb_cur_max() + 1);
|
char *char_buf = charalloc(MAXCHARLEN + 1);
|
||||||
int char_len = parse_mbchar(&openfile->current->data[u->begin],
|
int char_len = parse_mbchar(&openfile->current->data[u->begin],
|
||||||
char_buf, NULL);
|
char_buf, NULL);
|
||||||
char_buf[char_len] = '\0';
|
char_buf[char_len] = '\0';
|
||||||
@ -1354,7 +1354,7 @@ fprintf(stderr, " >> Updating... action = %d, openfile->last_action = %d, openf
|
|||||||
fprintf(stderr, " >> openfile->current->data = \"%s\", current_x = %lu, u->begin = %lu\n",
|
fprintf(stderr, " >> openfile->current->data = \"%s\", current_x = %lu, u->begin = %lu\n",
|
||||||
openfile->current->data, (unsigned long)openfile->current_x, (unsigned long)u->begin);
|
openfile->current->data, (unsigned long)openfile->current_x, (unsigned long)u->begin);
|
||||||
#endif
|
#endif
|
||||||
char *char_buf = charalloc(mb_cur_max());
|
char *char_buf = charalloc(MAXCHARLEN);
|
||||||
int char_len = parse_mbchar(&openfile->current->data[u->mark_begin_x], char_buf, NULL);
|
int char_len = parse_mbchar(&openfile->current->data[u->mark_begin_x], char_buf, NULL);
|
||||||
u->strdata = addstrings(u->strdata, u->strdata ? strlen(u->strdata) : 0, char_buf, char_len);
|
u->strdata = addstrings(u->strdata, u->strdata ? strlen(u->strdata) : 0, char_buf, char_len);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -1366,7 +1366,7 @@ fprintf(stderr, " >> Updating... action = %d, openfile->last_action = %d, openf
|
|||||||
}
|
}
|
||||||
case BACK:
|
case BACK:
|
||||||
case DEL: {
|
case DEL: {
|
||||||
char *char_buf = charalloc(mb_cur_max());
|
char *char_buf = charalloc(MAXCHARLEN);
|
||||||
int char_len = parse_mbchar(&openfile->current->data[openfile->current_x], char_buf, NULL);
|
int char_len = parse_mbchar(&openfile->current->data[openfile->current_x], char_buf, NULL);
|
||||||
if (openfile->current_x == u->begin) {
|
if (openfile->current_x == u->begin) {
|
||||||
/* They deleted more: add removed character after earlier stuff. */
|
/* They deleted more: add removed character after earlier stuff. */
|
||||||
@ -1682,7 +1682,7 @@ ssize_t break_line(const char *line, ssize_t goal, bool snap_at_nl)
|
|||||||
size_t indent_length(const char *line)
|
size_t indent_length(const char *line)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
char onechar[mb_cur_max()];
|
char onechar[MAXCHARLEN];
|
||||||
int charlen;
|
int charlen;
|
||||||
|
|
||||||
while (*line != '\0') {
|
while (*line != '\0') {
|
||||||
|
@ -215,7 +215,7 @@ const char *fixbounds(const char *r)
|
|||||||
* a separate word? That is: is it not part of a longer word?*/
|
* a separate word? That is: is it not part of a longer word?*/
|
||||||
bool is_separate_word(size_t position, size_t length, const char *buf)
|
bool is_separate_word(size_t position, size_t length, const char *buf)
|
||||||
{
|
{
|
||||||
char before[mb_cur_max()], after[mb_cur_max()];
|
char before[MAXCHARLEN], after[MAXCHARLEN];
|
||||||
size_t word_end = position + length;
|
size_t word_end = position + length;
|
||||||
|
|
||||||
/* Get the characters before and after the word, if any. */
|
/* Get the characters before and after the word, if any. */
|
||||||
|
@ -1822,7 +1822,7 @@ char *display_string(const char *buf, size_t start_col, size_t span,
|
|||||||
buf += start_index;
|
buf += start_index;
|
||||||
|
|
||||||
/* Allocate enough space for converting the relevant part of the line. */
|
/* Allocate enough space for converting the relevant part of the line. */
|
||||||
converted = charalloc(strlen(buf) * (mb_cur_max() + tabsize) + 1);
|
converted = charalloc(strlen(buf) * (MAXCHARLEN + tabsize) + 1);
|
||||||
|
|
||||||
/* If the first character starts before the left edge, or would be
|
/* If the first character starts before the left edge, or would be
|
||||||
* overwritten by a "$" token, then show placeholders instead. */
|
* overwritten by a "$" token, then show placeholders instead. */
|
||||||
@ -2136,8 +2136,8 @@ void statusline(message_type importance, const char *msg, ...)
|
|||||||
blank_statusbar();
|
blank_statusbar();
|
||||||
|
|
||||||
/* Construct the message out of all the arguments. */
|
/* Construct the message out of all the arguments. */
|
||||||
compound = charalloc(mb_cur_max() * (COLS + 1));
|
compound = charalloc(MAXCHARLEN * (COLS + 1));
|
||||||
vsnprintf(compound, mb_cur_max() * (COLS + 1), msg, ap);
|
vsnprintf(compound, MAXCHARLEN * (COLS + 1), msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
message = display_string(compound, 0, COLS, FALSE);
|
message = display_string(compound, 0, COLS, FALSE);
|
||||||
free(compound);
|
free(compound);
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user