state: escape invalid key file characters

This commit is contained in:
Julian Bouzas 2021-06-29 10:13:47 -04:00
parent 8505078a80
commit ee190411f4
2 changed files with 167 additions and 2 deletions

View file

@ -16,6 +16,100 @@
#include "log.h"
#include "state.h"
#define ESCAPED_CHARACTER '\\'
static char *
escape_string (const gchar *str)
{
char *res = NULL;
size_t str_size, i, j;
g_return_val_if_fail (str, NULL);
str_size = strlen (str);
g_return_val_if_fail (str_size > 0, NULL);
res = g_malloc_n ((str_size * 2) + 1, sizeof(gchar));
j = 0;
for (i = 0; i < str_size; i++) {
switch (str[i]) {
case ESCAPED_CHARACTER:
res[j++] = ESCAPED_CHARACTER;
res[j++] = ESCAPED_CHARACTER;
break;
case ' ':
res[j++] = ESCAPED_CHARACTER;
res[j++] = 's';
break;
case '=':
res[j++] = ESCAPED_CHARACTER;
res[j++] = 'e';
break;
case '[':
res[j++] = ESCAPED_CHARACTER;
res[j++] = 'o';
break;
case ']':
res[j++] = ESCAPED_CHARACTER;
res[j++] = 'c';
break;
default:
res[j++] = str[i];
break;
}
}
res[j++] = '\0';
return res;
}
static char *
compress_string (const gchar *str)
{
char *res = NULL;
size_t str_size, i, j;
g_return_val_if_fail (str, NULL);
str_size = strlen (str);
g_return_val_if_fail (str_size > 0, NULL);
res = g_malloc_n (str_size + 1, sizeof(gchar));
j = 0;
for (i = 0; i < str_size - 1; i++) {
if (str[i] == ESCAPED_CHARACTER) {
switch (str[i + 1]) {
case ESCAPED_CHARACTER:
res[j++] = ESCAPED_CHARACTER;
break;
case 's':
res[j++] = ' ';
break;
case 'e':
res[j++] = '=';
break;
case 'o':
res[j++] = '[';
break;
case 'c':
res[j++] = ']';
break;
default:
res[j++] = str[i];
break;
}
i++;
} else {
res[j++] = str[i];
}
}
if (i < str_size)
res[j++] = str[i];
res[j++] = '\0';
return res;
}
/*! \defgroup wpstate WpState */
/*!
* \struct WpState
@ -219,7 +313,9 @@ wp_state_save (WpState *self, WpProperties *props, GError ** error)
g_value_unset (&item)) {
const gchar *key = wp_properties_iterator_item_get_key (&item);
const gchar *val = wp_properties_iterator_item_get_value (&item);
g_key_file_set_string (keyfile, self->name, key, val);
g_autofree gchar *escaped_key = escape_string (key);
if (escaped_key)
g_key_file_set_string (keyfile, self->name, escaped_key, val);
}
if (!g_key_file_save_to_file (keyfile, self->location, &err)) {
@ -262,12 +358,15 @@ wp_state_load (WpState *self)
return g_steal_pointer (&props);
for (guint i = 0; keys[i]; i++) {
g_autofree gchar *compressed_key = NULL;
const gchar *key = keys[i];
g_autofree gchar *val = NULL;
val = g_key_file_get_string (keyfile, self->name, key, NULL);
if (!val)
continue;
wp_properties_set (props, key, val);
compressed_key = compress_string (key);
if (compressed_key)
wp_properties_set (props, compressed_key, val);
}
g_strfreev (keys);

View file

@ -135,6 +135,71 @@ test_state_spaces (void)
wp_state_clear (state);
}
static void
test_state_escaped (void)
{
g_autoptr (GError) error = NULL;
g_autoptr (WpState) state = wp_state_new ("escaped");
g_assert_nonnull (state);
/* Save */
{
g_autoptr (WpProperties) props = wp_properties_new_empty ();
wp_properties_set (props, "[]", "v0");
wp_properties_set (props, "[ ]", "v1");
wp_properties_set (props, "[=]", "v2");
wp_properties_set (props, " [=]", "v3");
wp_properties_set (props, "[=] ", "v4");
wp_properties_set (props, " [=] ", "v5");
wp_properties_set (props, " [ =] ", "v6");
wp_properties_set (props, " [= ] ", "v7");
wp_properties_set (props, " [ = ] ", "v8");
wp_properties_set (props, " [", "v9");
wp_properties_set (props, "[ ", "v10");
wp_properties_set (props, " [ ", "v11");
wp_properties_set (props, " ]", "v12");
wp_properties_set (props, "] ", "v13");
wp_properties_set (props, " ] ", "v14");
wp_properties_set (props, " ", "v15");
wp_properties_set (props, "=", "v16");
wp_properties_set (props, "\\", "v17");
wp_properties_set (props, "\\[", "v18");
wp_properties_set (props, "\\a", "v19");
wp_properties_set (props, "\\\\", "v20");
wp_properties_set (props, "[][", "][]");
g_assert_true (wp_state_save (state, props, &error));
g_assert_no_error (error);
}
/* Load */
{
g_autoptr (WpProperties) props = wp_state_load (state);
g_assert_nonnull (props);
g_assert_cmpstr (wp_properties_get (props, "[]"), ==, "v0");
g_assert_cmpstr (wp_properties_get (props, "[ ]"), ==, "v1");
g_assert_cmpstr (wp_properties_get (props, "[=]"), ==, "v2");
g_assert_cmpstr (wp_properties_get (props, " [=]"), ==, "v3");
g_assert_cmpstr (wp_properties_get (props, "[=] "), ==, "v4");
g_assert_cmpstr (wp_properties_get (props, " [=] "), ==, "v5");
g_assert_cmpstr (wp_properties_get (props, " [ =] "), ==, "v6");
g_assert_cmpstr (wp_properties_get (props, " [= ] "), ==, "v7");
g_assert_cmpstr (wp_properties_get (props, " [ = ] "), ==, "v8");
g_assert_cmpstr (wp_properties_get (props, " ["), ==, "v9");
g_assert_cmpstr (wp_properties_get (props, "[ "), ==, "v10");
g_assert_cmpstr (wp_properties_get (props, " [ "), ==, "v11");
g_assert_cmpstr (wp_properties_get (props, " ]"), ==, "v12");
g_assert_cmpstr (wp_properties_get (props, "] "), ==, "v13");
g_assert_cmpstr (wp_properties_get (props, " ] "), ==, "v14");
g_assert_cmpstr (wp_properties_get (props, " "), ==, "v15");
g_assert_cmpstr (wp_properties_get (props, "="), ==, "v16");
g_assert_cmpstr (wp_properties_get (props, "\\"), ==, "v17");
g_assert_cmpstr (wp_properties_get (props, "\\["), ==, "v18");
g_assert_cmpstr (wp_properties_get (props, "\\a"), ==, "v19");
g_assert_cmpstr (wp_properties_get (props, "\\\\"), ==, "v20");
g_assert_cmpstr (wp_properties_get (props, "[]["), ==, "][]");
}
}
int
main (int argc, char *argv[])
{
@ -144,6 +209,7 @@ main (int argc, char *argv[])
g_test_add_func ("/wp/state/basic", test_state_basic);
g_test_add_func ("/wp/state/empty", test_state_empty);
g_test_add_func ("/wp/state/spaces", test_state_spaces);
g_test_add_func ("/wp/state/escaped", test_state_escaped);
return g_test_run ();
}