[epiphany] passwords-sync: Fix crash caused by serializing NULL usernames
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany] passwords-sync: Fix crash caused by serializing NULL usernames
- Date: Tue, 8 Aug 2017 00:36:58 +0000 (UTC)
commit e9dbd958a9e870038d2143fcd0d4911923405d20
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date: Tue Aug 8 02:58:47 2017 +0300
passwords-sync: Fix crash caused by serializing NULL usernames
https://bugzilla.gnome.org/show_bug.cgi?id=785947
lib/sync/ephy-password-manager.c | 35 ++++++++++++++++++++++-----------
lib/sync/ephy-password-record.c | 39 ++++++++++++++++++++++++++++++++++++-
2 files changed, 60 insertions(+), 14 deletions(-)
---
diff --git a/lib/sync/ephy-password-manager.c b/lib/sync/ephy-password-manager.c
index 46f482e..19e46c7 100644
--- a/lib/sync/ephy-password-manager.c
+++ b/lib/sync/ephy-password-manager.c
@@ -244,8 +244,9 @@ ephy_password_manager_cache_remove (EphyPasswordManager *self,
g_assert (EPHY_IS_PASSWORD_MANAGER (self));
g_assert (self->cache);
- g_assert (hostname);
- g_assert (username);
+
+ if (!hostname || !username)
+ return;
usernames = g_hash_table_lookup (self->cache, hostname);
if (usernames) {
@@ -267,8 +268,9 @@ ephy_password_manager_cache_add (EphyPasswordManager *self,
g_assert (EPHY_IS_PASSWORD_MANAGER (self));
g_assert (self->cache);
- g_assert (hostname);
- g_assert (username);
+
+ if (!hostname || !username)
+ return;
usernames = g_hash_table_lookup (self->cache, hostname);
for (GSList *l = usernames; l && l->data; l = l->next) {
@@ -290,8 +292,7 @@ populate_cache_cb (GSList *records,
const char *hostname = ephy_password_record_get_hostname (record);
const char *username = ephy_password_record_get_username (record);
- if (username)
- ephy_password_manager_cache_add (self, hostname, username);
+ ephy_password_manager_cache_add (self, hostname, username);
}
g_slist_free_full (records, g_object_unref);
@@ -433,8 +434,7 @@ ephy_password_manger_store_record (EphyPasswordManager *self,
ephy_synchronizable_get_server_time_modified (EPHY_SYNCHRONIZABLE
(record)));
store_internal (ephy_password_record_get_password (record), attributes, NULL, NULL);
- if (username)
- ephy_password_manager_cache_add (self, hostname, username);
+ ephy_password_manager_cache_add (self, hostname, username);
g_hash_table_unref (attributes);
}
@@ -809,10 +809,21 @@ replace_existing_cb (GSList *records,
{
ReplaceRecordAsyncData *data = (ReplaceRecordAsyncData *)user_data;
- /* We only expect one matching record here. */
- g_assert (g_slist_length (records) == 1);
-
- ephy_password_manager_forget_record (data->manager, records->data, data->record);
+ for (GSList *l = records; l && l->data; l = l->next) {
+ /* NULL fields can cause the query to match other records too,
+ * so we need to make sure we have the record we've been looking for. */
+ if (!g_strcmp0 (ephy_password_record_get_hostname (records->data),
+ ephy_password_record_get_hostname (data->record)) &&
+ !g_strcmp0 (ephy_password_record_get_username (records->data),
+ ephy_password_record_get_username (data->record)) &&
+ !g_strcmp0 (ephy_password_record_get_username_field (records->data),
+ ephy_password_record_get_username_field (data->record)) &&
+ !g_strcmp0 (ephy_password_record_get_password_field (records->data),
+ ephy_password_record_get_password_field (data->record))) {
+ ephy_password_manager_forget_record (data->manager, records->data, data->record);
+ break;
+ }
+ }
replace_record_async_data_free (data);
}
diff --git a/lib/sync/ephy-password-record.c b/lib/sync/ephy-password-record.c
index 99060fd..9e08c9e 100644
--- a/lib/sync/ephy-password-record.c
+++ b/lib/sync/ephy-password-record.c
@@ -334,11 +334,46 @@ ephy_password_record_get_time_password_changed (EphyPasswordRecord *self)
return self->time_password_changed;
}
+static JsonNode *
+serializable_serialize_property (JsonSerializable *serializable,
+ const char *name,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ /* Firefox expects null usernames as empty strings. */
+ if (!g_strcmp0 (name, "username") || !g_strcmp0 (name, "usernameField")) {
+ if (g_value_get_string (value) == NULL) {
+ JsonNode *node = json_node_new (JSON_NODE_VALUE);
+ json_node_set_string (node, "");
+ return node;
+ }
+ }
+
+ return json_serializable_default_serialize_property (serializable, name, value, pspec);
+}
+
+static gboolean
+serializable_deserialize_property (JsonSerializable *serializable,
+ const char *name,
+ GValue *value,
+ GParamSpec *pspec,
+ JsonNode *node)
+{
+ if (!g_strcmp0 (name, "username") || !g_strcmp0 (name, "usernameField")) {
+ if (!g_strcmp0 (json_node_get_string (node), "")) {
+ g_value_set_string (value, NULL);
+ return TRUE;
+ }
+ }
+
+ return json_serializable_default_deserialize_property (serializable, name, value, pspec, node);
+}
+
static void
json_serializable_iface_init (JsonSerializableIface *iface)
{
- iface->serialize_property = json_serializable_default_serialize_property;
- iface->deserialize_property = json_serializable_default_deserialize_property;
+ iface->serialize_property = serializable_serialize_property;
+ iface->deserialize_property = serializable_deserialize_property;
}
static const char *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]