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
					
				
					 1 changed files with 44 additions and 30 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		
		Reference in a new issue