Fix various unsafe string handling in fkeys
Also removes the 2048 input byte limit And fixes utf8 completion chars in some cases
This commit is contained in:
parent
99a1fff590
commit
fda692d250
|
@ -1409,9 +1409,6 @@ key_action_tab_clean(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used in the followig completers */
|
|
||||||
#define COMP_BUF 2048
|
|
||||||
|
|
||||||
/* For use in sorting the user list for completion */
|
/* For use in sorting the user list for completion */
|
||||||
static int
|
static int
|
||||||
talked_recent_cmp (struct User *a, struct User *b)
|
talked_recent_cmp (struct User *a, struct User *b)
|
||||||
|
@ -1425,16 +1422,31 @@ talked_recent_cmp (struct User *a, struct User *b)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COMP_BUF 2048
|
||||||
|
|
||||||
|
static inline glong
|
||||||
|
len_to_offset (const char *str, glong len)
|
||||||
|
{
|
||||||
|
return g_utf8_pointer_to_offset (str, str + len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline glong
|
||||||
|
offset_to_len (const char *str, glong offset)
|
||||||
|
{
|
||||||
|
return g_utf8_offset_to_pointer (str, offset) - str;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2,
|
key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2,
|
||||||
struct session *sess)
|
struct session *sess)
|
||||||
{
|
{
|
||||||
int len = 0, elen = 0, i = 0, cursor_pos, ent_start = 0, comp = 0, found = 0,
|
int len = 0, elen = 0, i = 0, cursor_pos, ent_start = 0, comp = 0, found = 0,
|
||||||
prefix_len, skip_len = 0, is_nick, is_cmd = 0;
|
prefix_len, skip_len = 0, is_nick, is_cmd = 0;
|
||||||
char buf[COMP_BUF], ent[CHANLEN], *postfix = NULL, *result, *ch;
|
char ent[CHANLEN], *postfix = NULL, *result, *ch;
|
||||||
GList *list = NULL, *tmp_list = NULL;
|
GList *list = NULL, *tmp_list = NULL;
|
||||||
const char *text;
|
const char *text;
|
||||||
GCompletion *gcomp = NULL;
|
GCompletion *gcomp = NULL;
|
||||||
|
GString *buf;
|
||||||
|
|
||||||
/* force the IM Context to reset */
|
/* force the IM Context to reset */
|
||||||
SPELL_ENTRY_SET_EDITABLE (t, FALSE);
|
SPELL_ENTRY_SET_EDITABLE (t, FALSE);
|
||||||
|
@ -1448,8 +1460,6 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2,
|
||||||
|
|
||||||
cursor_pos = SPELL_ENTRY_GET_POS (t);
|
cursor_pos = SPELL_ENTRY_GET_POS (t);
|
||||||
|
|
||||||
buf[0] = 0; /* make sure we don't get garbage in the buffer */
|
|
||||||
|
|
||||||
/* handle "nick: " or "nick " or "#channel "*/
|
/* handle "nick: " or "nick " or "#channel "*/
|
||||||
ch = g_utf8_find_prev_char(text, g_utf8_offset_to_pointer(text,cursor_pos));
|
ch = g_utf8_find_prev_char(text, g_utf8_offset_to_pointer(text,cursor_pos));
|
||||||
if (ch && ch[0] == ' ')
|
if (ch && ch[0] == ' ')
|
||||||
|
@ -1609,40 +1619,42 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2,
|
||||||
/* bash style completion */
|
/* bash style completion */
|
||||||
if (g_list_next(list) != NULL)
|
if (g_list_next(list) != NULL)
|
||||||
{
|
{
|
||||||
|
buf = g_string_sized_new (MAX(COMP_BUF, len + NICKLEN));
|
||||||
if (strlen (result) > elen) /* the largest common prefix is larger than nick, change the data */
|
if (strlen (result) > elen) /* the largest common prefix is larger than nick, change the data */
|
||||||
{
|
{
|
||||||
if (prefix_len)
|
if (prefix_len)
|
||||||
g_utf8_strncpy (buf, text, prefix_len);
|
g_string_append_len (buf, text, offset_to_len (text, prefix_len));
|
||||||
strncat (buf, result, COMP_BUF - prefix_len);
|
g_string_append (buf, result);
|
||||||
cursor_pos = strlen (buf);
|
cursor_pos = buf->len;
|
||||||
g_free(result);
|
g_free(result);
|
||||||
if (postfix)
|
if (postfix)
|
||||||
{
|
{
|
||||||
strcat (buf, " ");
|
g_string_append_c (buf, ' ');
|
||||||
strncat (buf, postfix, COMP_BUF - cursor_pos -1);
|
g_string_append (buf, postfix);
|
||||||
}
|
}
|
||||||
SPELL_ENTRY_SET_TEXT (t, buf);
|
SPELL_ENTRY_SET_TEXT (t, buf->str);
|
||||||
SPELL_ENTRY_SET_POS (t, g_utf8_pointer_to_offset(buf, buf + cursor_pos));
|
SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, cursor_pos));
|
||||||
buf[0] = 0;
|
g_string_erase (buf, 0, -1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_free(result);
|
g_free(result);
|
||||||
|
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
len = strlen (buf); /* current buffer */
|
len = buf->len;
|
||||||
elen = strlen (list->data); /* next item to add */
|
elen = strlen (list->data); /* next item to add */
|
||||||
if (len + elen + 2 >= COMP_BUF) /* +2 is space + null */
|
if (len + elen + 2 >= COMP_BUF) /* +2 is space + null */
|
||||||
{
|
{
|
||||||
PrintText (sess, buf);
|
PrintText (sess, buf->str);
|
||||||
buf[0] = 0;
|
g_string_erase (buf, 0, -1);
|
||||||
len = 0;
|
|
||||||
}
|
}
|
||||||
strcpy (buf + len, (char *) list->data);
|
g_string_append (buf, (char*)list->data);
|
||||||
strcpy (buf + len + elen, " ");
|
g_string_append_c (buf, ' ');
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
PrintText (sess, buf);
|
PrintText (sess, buf->str);
|
||||||
g_completion_free(gcomp);
|
g_completion_free(gcomp);
|
||||||
|
g_string_free (buf, TRUE);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
/* Only one matching entry */
|
/* Only one matching entry */
|
||||||
|
@ -1654,17 +1666,19 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2,
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
{
|
{
|
||||||
|
buf = g_string_sized_new (len + NICKLEN);
|
||||||
if (prefix_len)
|
if (prefix_len)
|
||||||
g_utf8_strncpy(buf, text, prefix_len);
|
g_string_append_len (buf, text, offset_to_len (text, prefix_len));
|
||||||
strncat (buf, result, COMP_BUF - (prefix_len + 3)); /* make sure nicksuffix and space fits */
|
g_string_append (buf, result);
|
||||||
if(!prefix_len && is_nick)
|
if(!prefix_len && is_nick)
|
||||||
strcat (buf, &prefs.hex_completion_suffix[0]);
|
g_string_append_unichar (buf, g_utf8_get_char_validated ((const char*)&prefs.hex_completion_suffix, -1));
|
||||||
strcat (buf, " ");
|
g_string_append_c (buf, ' ');
|
||||||
cursor_pos = strlen (buf);
|
cursor_pos = buf->len;
|
||||||
if (postfix)
|
if (postfix)
|
||||||
strncat (buf, postfix, COMP_BUF - cursor_pos - 2);
|
g_string_append (buf, postfix);
|
||||||
SPELL_ENTRY_SET_TEXT (t, buf);
|
SPELL_ENTRY_SET_TEXT (t, buf->str);
|
||||||
SPELL_ENTRY_SET_POS (t, g_utf8_pointer_to_offset(buf, buf + cursor_pos));
|
SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, cursor_pos));
|
||||||
|
g_string_free (buf, TRUE);
|
||||||
}
|
}
|
||||||
if (gcomp)
|
if (gcomp)
|
||||||
g_completion_free(gcomp);
|
g_completion_free(gcomp);
|
||||||
|
@ -1796,7 +1810,7 @@ replace_handle (GtkWidget *t)
|
||||||
snprintf (word, sizeof (word), "%s", pop->cmd);
|
snprintf (word, sizeof (word), "%s", pop->cmd);
|
||||||
else
|
else
|
||||||
snprintf (word, sizeof (word), "%s%s", pop->cmd, postfix);
|
snprintf (word, sizeof (word), "%s%s", pop->cmd, postfix);
|
||||||
strcat (outbuf, word);
|
g_strlcat (outbuf, word, sizeof(outbuf));
|
||||||
SPELL_ENTRY_SET_TEXT (t, outbuf);
|
SPELL_ENTRY_SET_TEXT (t, outbuf);
|
||||||
SPELL_ENTRY_SET_POS (t, -1);
|
SPELL_ENTRY_SET_POS (t, -1);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue