--- a/libpurple/protocols/gg/message-prpl.c Mon Sep 21 20:15:51 2020 -0500
+++ b/libpurple/protocols/gg/message-prpl.c Mon Sep 21 20:23:22 2020 -0500
@@ -309,13 +309,14 @@
-gchar * ggp_message_format_to_gg(PurpleConversation *conv, const gchar *text)
+ggp_message_format_to_gg(PurpleConversation *conv, const gchar *text) - GList *rt = NULL; /* reformatted text */
+ GString *reformatted_text = NULL; - GList *pending_objects = NULL;
+ GString *pending_objects = NULL; GList *font_stack = NULL;
static int html_sizes_pt[7] = { 7, 8, 9, 10, 12, 14, 16 };
@@ -346,6 +347,8 @@
text_new = g_strdup_printf("%s<eom></eom>", text_new);
+ reformatted_text = g_string_new(NULL); + pending_objects = g_string_new(NULL); g_regex_match(global_data.re_html_tag, text_new, 0, &match);
while (g_match_info_matches(match)) {
int m_start, m_end, m_pos;
@@ -370,76 +373,80 @@
"uknown tag %s\n", tag_str);
- /* closing *all* formatting-related tags (GG11 weirness)
+ /* closing *all* formatting-related tags (GG11 weirdness) * and adding pending objects */
- if ((text_before && (font_changed || pending_objects)) ||
- (tag == GGP_HTML_TAG_EOM && tag_close))
+ if ((text_before && (font_changed || pending_objects->len > 0)) || + (tag == GGP_HTML_TAG_EOM && tag_close)) { - if (font_current->s && !GGP_GG11_FORCE_COMPAT)
- rt = g_list_prepend(rt,
- rt = g_list_prepend(rt,
- rt = g_list_prepend(rt,
- rt = g_list_prepend(rt,
- rt = g_list_prepend(rt, g_strdup("</span>"));
+ if (font_current->s && !GGP_GG11_FORCE_COMPAT) { + g_string_append(reformatted_text, "</s>"); + g_string_append(reformatted_text, "</u>"); + g_string_append(reformatted_text, "</i>"); + g_string_append(reformatted_text, "</b>"); + g_string_append(reformatted_text, "</span>");
- rt = g_list_concat(pending_objects, rt);
- pending_objects = NULL;
+ if (pending_objects->len > 0) { + g_string_append(reformatted_text, pending_objects->str); + g_string_truncate(pending_objects, 0); /* opening formatting-related tags again */
if (text_before && !in_any_tag) {
gboolean has_size = (font_new->size > 0 &&
font_new->size <= 7 && font_new->size != 3);
+ has_size || font_new->face || + (font_new->bgcolor >= 0 && !GGP_GG11_FORCE_COMPAT) ||
- styles = g_list_append(styles, g_strdup_printf(
- html_sizes_pt[font_new->size - 1]));
- styles = g_list_append(styles, g_strdup_printf(
- "font-family:%s;", font_new->face));
- if (font_new->bgcolor >= 0 && !GGP_GG11_FORCE_COMPAT)
- styles = g_list_append(styles, g_strdup_printf(
- "background-color:#%06x;",
- if (font_new->color >= 0)
- styles = g_list_append(styles, g_strdup_printf(
- "color:#%06x;", font_new->color));
+ g_string_append(reformatted_text, "<span style=\"");
- gchar *combined = ggp_strjoin_list(" ", styles);
- g_list_free_full(styles, g_free);
- style = g_strdup_printf(" style=\"%s\"",
- rt = g_list_prepend(rt, g_strdup_printf("<span%s>",
+ g_string_append_printf(reformatted_text, "font-size:%dpt;", + html_sizes_pt[font_new->size - 1]); + g_string_append_printf(reformatted_text, "font-family:%s;", + if (font_new->bgcolor >= 0 && !GGP_GG11_FORCE_COMPAT) { + g_string_append_printf(reformatted_text, + "background-color:#%06x;", + if (font_new->color >= 0) { + g_string_append_printf(reformatted_text, "color:#%06x;",
- rt = g_list_prepend(rt, g_strdup("<b>"));
- rt = g_list_prepend(rt, g_strdup("<i>"));
- rt = g_list_prepend(rt, g_strdup("<u>"));
- if (font_new->s && !GGP_GG11_FORCE_COMPAT)
- rt = g_list_prepend(rt, g_strdup("<s>"));
+ g_string_append(reformatted_text, "\">"); + g_string_append(reformatted_text, "<span>"); + g_string_append(reformatted_text, "<b>"); + g_string_append(reformatted_text, "<i>"); + g_string_append(reformatted_text, "<u>"); + if (font_new->s && !GGP_GG11_FORCE_COMPAT) { + g_string_append(reformatted_text, "<s>"); ggp_font_free(font_current);
@@ -448,8 +455,8 @@
- rt = g_list_prepend(rt,
- g_strndup(text_new + pos, m_start - pos));
+ g_string_append_len(reformatted_text, text_new + pos, /* set formatting of a following text */
@@ -480,10 +487,9 @@
res = ggp_image_prepare(conv, image, &id);
if (res == GGP_IMAGE_PREPARE_OK) {
- pending_objects = g_list_prepend(
- pending_objects, g_strdup_printf(
- "<img name=\"" GGP_IMAGE_ID_FORMAT
+ g_string_append_printf(pending_objects, + "<img name=\"" GGP_IMAGE_ID_FORMAT "\">", } else if (res == GGP_IMAGE_PREPARE_TOO_BIG) {
purple_conversation_write_system_message(conv,
_("Image is too large, please try "
@@ -541,9 +547,9 @@
font_stack = g_list_prepend(font_stack,
ggp_font_clone(font_new));
- if (tag == GGP_HTML_TAG_DIV)
- pending_objects = g_list_prepend(
- pending_objects, g_strdup("<br>"));
+ if (tag == GGP_HTML_TAG_DIV) { + g_string_append(pending_objects, "<br>"); style = g_hash_table_lookup(attribs, "style");
@@ -583,11 +589,9 @@
font_new = ggp_font_clone(font_base);
} else if (tag == GGP_HTML_TAG_BR) {
- pending_objects = g_list_prepend(pending_objects,
+ g_string_append(pending_objects, "<br>"); } else if (tag == GGP_HTML_TAG_HR) {
- pending_objects = g_list_prepend(pending_objects,
- g_strdup("<br><span>---</span><br>"));
+ g_string_append(pending_objects, "<br><span>---</span><br>"); } else if (tag == GGP_HTML_TAG_A || tag == GGP_HTML_TAG_EOM) {
} else if (tag == GGP_HTML_TAG_UNKNOWN) {
@@ -616,10 +620,9 @@
g_list_free_full(font_stack, ggp_font_free);
/* combining reformatted text info one string */
- rt = g_list_reverse(rt);
- text_new = ggp_strjoin_list("", rt);
- g_list_free_full(rt, g_free);
+ g_string_free(pending_objects, TRUE); + text_new = g_string_free(reformatted_text, FALSE); if (purple_debug_is_verbose())
purple_debug_info("gg", "reformatted text: [%s]", text_new);
--- a/libpurple/protocols/gg/servconn.c Mon Sep 21 20:15:51 2020 -0500
+++ b/libpurple/protocols/gg/servconn.c Mon Sep 21 20:23:22 2020 -0500
@@ -44,14 +44,18 @@
void ggp_servconn_setup(PurpleAccountOption *server_option)
- purple_prefs_add_string(GGP_SERVCONN_HISTORY_PREF, "");
+ purple_prefs_add_string_list(GGP_SERVCONN_HISTORY_PREF, NULL); global_data.server_option = server_option;
- global_data.server_history = ggp_strsplit_list(purple_prefs_get_string(
- GGP_SERVCONN_HISTORY_PREF), ";", GGP_SERVCONN_HISTORY_MAXLEN + 1);
- global_data.server_history = ggp_list_truncate(
- global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN,
+ global_data.server_history = + purple_prefs_get_string_list(GGP_SERVCONN_HISTORY_PREF); + extra = g_list_nth(global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN); + /* Truncate the list to the maximum. */ + extra->prev->next = NULL; + g_list_free_full(extra, g_free); purple_account_option_string_set_hints(global_data.server_option,
ggp_servconn_get_servers());
@@ -65,7 +69,6 @@
void ggp_servconn_add_server(const gchar *server)
old_entry = g_list_find_custom(global_data.server_history, server,
(GCompareFunc)g_strcmp0);
@@ -77,21 +80,32 @@
global_data.server_history = g_list_prepend(global_data.server_history,
- global_data.server_history = ggp_list_truncate(
- global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN,
+ g_list_nth(global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN); + if (old_entry != NULL) { + /* Truncate the list to the maximum. */ + old_entry->prev->next = NULL; + g_list_free_full(old_entry, g_free); - joined = ggp_strjoin_list(";", global_data.server_history);
- purple_prefs_set_string(GGP_SERVCONN_HISTORY_PREF, joined);
+ purple_prefs_set_string_list(GGP_SERVCONN_HISTORY_PREF, + global_data.server_history); purple_account_option_string_set_hints(global_data.server_option,
ggp_servconn_get_servers());
-GSList * ggp_servconn_get_servers(void)
+ggp_servconn_get_servers(void) - return ggp_list_copy_to_slist_deep(global_data.server_history,
- (GCopyFunc)g_strdup, NULL);
+ GSList *new_list = NULL; + it = g_list_first(global_data.server_history); + new_list = g_slist_append(new_list, g_strdup(it->data)); --- a/libpurple/protocols/gg/utils.c Mon Sep 21 20:15:51 2020 -0500
+++ b/libpurple/protocols/gg/utils.c Mon Sep 21 20:23:22 2020 -0500
@@ -102,15 +102,6 @@
return ggp_convert(src, "CP1250", "UTF-8");
-gboolean ggp_password_validate(const gchar *password)
- const int len = strlen(password);
- if (len < 6 || len > 15)
- return g_regex_match_simple("^[ a-zA-Z0-9~`!@#$%^&*()_+=[\\]{};':\",./?"
- "<>\\\\|-]+$", password, 0, 0);
gchar * ggp_utf8_strndup(const gchar *str, gsize n)
@@ -134,60 +125,6 @@
return g_strndup(str, raw_len);
-GSList * ggp_list_copy_to_slist_deep(GList *list, GCopyFunc func,
- GSList *new_list = NULL;
- it = g_list_first(list);
- new_list = g_slist_append(new_list, func(it->data, user_data));
-GList * ggp_strsplit_list(const gchar *string, const gchar *delimiter,
- gchar **splitted, **it;
- it = splitted = g_strsplit(string, delimiter, max_tokens);
- list = g_list_append(list, *it);
-gchar * ggp_strjoin_list(const gchar *separator, GList *list)
- list_len = g_list_length(list);
- str_array = g_new(gchar*, list_len + 1);
- it = g_list_first(list);
- str_array[i++] = it->data;
- joined = g_strjoinv(separator, str_array);
const gchar * ggp_ipv4_to_str(uint32_t raw_ip)
static gchar buff[INET_ADDRSTRLEN];
@@ -202,16 +139,6 @@
-GList * ggp_list_truncate(GList *list, guint length, GDestroyNotify free_func)
- while (g_list_length(list) > length) {
- GList *last = g_list_last(list);
- list = g_list_delete_link(list, last);
gchar * ggp_free_if_equal(gchar *str, const gchar *pattern)
if (g_strcmp0(str, pattern) == 0) {
@@ -228,18 +155,6 @@
-gint ggp_int64_compare(gconstpointer _a, gconstpointer _b)
- const int64_t *ap = _a, *bp = _b;
- const int64_t a = *ap, b = *bp;
JsonParser * ggp_json_parse(const gchar *data)
--- a/libpurple/protocols/gg/utils.h Mon Sep 21 20:15:51 2020 -0500
+++ b/libpurple/protocols/gg/utils.h Mon Sep 21 20:23:22 2020 -0500
@@ -81,28 +81,14 @@
gchar * ggp_convert_from_cp1250(const gchar *src);
-gboolean ggp_password_validate(const gchar *password);
gchar * ggp_utf8_strndup(const gchar *str, gsize n);
-GSList * ggp_list_copy_to_slist_deep(GList *list, GCopyFunc func,
-GList * ggp_strsplit_list(const gchar *string, const gchar *delimiter,
-gchar * ggp_strjoin_list(const gchar *separator, GList *list);
const gchar * ggp_ipv4_to_str(uint32_t raw_ip);
-GList * ggp_list_truncate(GList *list, guint length, GDestroyNotify free_func);
gchar * ggp_free_if_equal(gchar *str, const gchar *pattern);
uint64_t * ggp_uint64dup(uint64_t val);
-gint ggp_int64_compare(gconstpointer a, gconstpointer b);
JsonParser * ggp_json_parse(const gchar *data);
#endif /* PURPLE_GG_UTILS_H */
--- a/libpurple/protocols/gg/validator.c Mon Sep 21 20:15:51 2020 -0500
+++ b/libpurple/protocols/gg/validator.c Mon Sep 21 20:23:22 2020 -0500
@@ -44,8 +44,16 @@
value = purple_request_field_string_get_value(field);
- if (value != NULL && ggp_password_validate(value))
+ size_t len = strlen(value); + if (6 <= len && len <= 15) { + if (g_regex_match_simple( + "^[ a-zA-Z0-9~`!@#$%^&*()_+=[\\]{};':\",./?<>\\\\|-]+$", *errmsg = g_strdup(_("Password can contain 6-15 alphanumeric characters"));