Escape newlines in pluginpref

This commit is contained in:
TingPing 2014-08-26 19:11:23 -04:00
parent 9fc9d3a4ab
commit 24573c0171
3 changed files with 128 additions and 8 deletions

View File

@ -170,6 +170,116 @@ list_delentry (GSList ** list, char *name)
return 0;
}
/*
* Unescapes \\r and \\n as \r and \n.
* Returns newly allocated string.
*
* Modified version of gkeyfile's unescaping.
*/
char *
unescape_newlines (const gchar *value)
{
gchar *string_value, *p, *q0, *q;
string_value = g_new (gchar, strlen (value) + 1);
p = (gchar *) value;
q0 = q = string_value;
while (*p)
{
if (*p == '\\')
{
p++;
switch (*p)
{
case 'n':
*q = '\n';
break;
case 'r':
*q = '\r';
break;
case '\\':
*q = '\\';
break;
case '\0':
g_warning ("Escaped character at end of string.");
break;
default:
*q++ = '\\';
*q = *p;
g_warning ("Invalid escape sequence.");
break;
}
}
else
{
*q = *p;
}
if (*p == '\0')
break;
q++;
p++;
}
*q = '\0';
return string_value;
}
/*
* Escapes \r and \n as \\r and \\n.
* Returns newly allocated string.
*
* Modified version of gkeyfile's escaping.
*/
char *
escape_newlines (const char *str)
{
gchar *value, *p, *q;
gsize len;
len = strlen (str) + 1;
value = g_new (gchar, 2 * len);
p = (gchar*)str;
q = value;
while (p < (str + len - 1))
{
gchar escaped_character[3] = { '\\', 0, 0 };
switch (*p)
{
case '\n':
escaped_character[1] = 'n';
strcpy (q, escaped_character);
q += 2;
break;
case '\r':
escaped_character[1] = 'r';
strcpy (q, escaped_character);
q += 2;
break;
case '\\':
escaped_character[1] = '\\';
strcpy (q, escaped_character);
q += 2;
break;
default:
*q = *p;
q++;
break;
}
p++;
}
*q = '\0';
return value;
}
char *
cfg_get_str (char *cfg, const char *var, char *dest, int dest_len)
{

View File

@ -54,6 +54,9 @@ FILE *hexchat_fopen_file (const char *file, const char *mode, int xof_flags);
GFile *hexchat_open_gfile (const char *filename);
gsize stream_writef (GOutputStream *ostream, const char *fmt, ...) G_GNUC_PRINTF (2, 3);
char *unescape_newlines (const gchar *value);
char *escape_newlines (const gchar *value);
#define XOF_DOMODE 1
#define XOF_FULLPATH 2

View File

@ -1752,9 +1752,7 @@ hexchat_pluginpref_set_str_real (hexchat_plugin *pl, const char *var, const char
GDataInputStream *istream;
GFileIOStream *tmpstream;
gboolean ret;
char *confname;
char *line;
char *canon;
char *confname, *line, *canon, *escaped_value;
canon = g_strdup (pl->name);
canonalize_key (canon);
@ -1780,8 +1778,10 @@ hexchat_pluginpref_set_str_real (hexchat_plugin *pl, const char *var, const char
g_object_unref (file);
return 0;
}
cfg_put_str (ostream, var, value);
escaped_value = escape_newlines (value);
cfg_put_str (ostream, var, escaped_value);
g_free (escaped_value);
return 1;
}
@ -1810,7 +1810,9 @@ hexchat_pluginpref_set_str_real (hexchat_plugin *pl, const char *var, const char
if (mode == 1)
{
/* Add new setting */
cfg_put_str (ostream, var, value);
escaped_value = escape_newlines (value);
cfg_put_str (ostream, var, escaped_value);
g_free (escaped_value);
}
while ((line = g_data_input_stream_read_line_utf8 (istream, NULL, NULL, NULL)))
@ -1843,7 +1845,8 @@ static int
hexchat_pluginpref_get_str_real (hexchat_plugin *pl, const char *var, char *dest, int dest_len)
{
GFile *file;
char *confname, *canon, *cfg;
char *confname, *canon, *cfg, *unescaped_value;
char buf[512], *bufp = buf;
canon = g_strdup (pl->name);
canonalize_key (canon);
@ -1860,11 +1863,15 @@ hexchat_pluginpref_get_str_real (hexchat_plugin *pl, const char *var, char *dest
}
g_object_unref (file);
if (!cfg_get_str (cfg, var, dest, dest_len))
if (!cfg_get_str (cfg, var, buf, sizeof(buf)))
{
g_free (cfg);
return 0;
}
unescaped_value = unescape_newlines (bufp);
g_strlcpy (dest, unescaped_value, dest_len);
g_free (unescaped_value);
g_free (cfg);
return 1;