mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-02 16:48:00 +02:00
state: escape invalid key file characters
This commit is contained in:
parent
8505078a80
commit
ee190411f4
2 changed files with 167 additions and 2 deletions
103
lib/wp/state.c
103
lib/wp/state.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue