[epiphany/wip/sync: 1/11] sync: Simplify goto statements
- From: Gabriel Ivașcu <gabrielivascu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/sync: 1/11] sync: Simplify goto statements
- Date: Wed, 19 Apr 2017 17:46:50 +0000 (UTC)
commit 5f820e66a80224a0b7d5454d155ae008061f79f9
Author: Gabriel Ivascu <ivascu gabriel59 gmail com>
Date: Fri Apr 14 13:33:51 2017 +0300
sync: Simplify goto statements
src/prefs-dialog.c | 152 ++++++-------
src/sync/ephy-sync-crypto.c | 41 ++--
src/sync/ephy-sync-service.c | 462 +++++++++++++++++----------------------
src/sync/ephy-synchronizable.c | 54 ++---
4 files changed, 313 insertions(+), 396 deletions(-)
---
diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c
index d04da26..b4a5c76 100644
--- a/src/prefs-dialog.c
+++ b/src/prefs-dialog.c
@@ -282,12 +282,12 @@ sync_fxa_server_message_cb (WebKitUserContentManager *manager,
WebKitJavascriptResult *result,
PrefsDialog *dialog)
{
- JsonNode *node;
- JsonObject *json;
- JsonObject *detail;
- JsonObject *data;
+ JsonNode *node = NULL;
+ JsonObject *json = NULL;
+ JsonObject *detail = NULL;
+ JsonObject *data = NULL;
GError *error = NULL;
- char *json_string;
+ char *json_string = NULL;
const char *type;
const char *command;
const char *email;
@@ -295,111 +295,97 @@ sync_fxa_server_message_cb (WebKitUserContentManager *manager,
const char *sessionToken;
const char *keyFetchToken;
const char *unwrapBKey;
- gboolean verified;
- gboolean is_internal_error = TRUE;
json_string = ephy_embed_utils_get_js_result_as_string (result);
if (!json_string) {
g_warning ("Failed to get JavaScript result as string");
- goto out;
+ goto out_error;
}
node = json_from_string (json_string, &error);
if (error) {
g_warning ("Response is not a valid JSON: %s", error->message);
- g_error_free (error);
- goto free_string;
- }
- if (!JSON_NODE_HOLDS_OBJECT (node)) {
- g_warning ("JSON node does not hold a JSON object");
- goto free_node;
+ goto out_error;
}
json = json_node_get_object (node);
- if (!json_object_has_member (json, "type") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "type"))) {
- g_warning ("JSON object has invalid 'type' member");
- goto free_node;
+ if (!json) {
+ g_warning ("JSON node does not hold a JSON object");
+ goto out_error;
}
type = json_object_get_string_member (json, "type");
+ if (!type) {
+ g_warning ("JSON object has missing or invalid 'type' member");
+ goto out_error;
+ }
/* The only message type expected is FirefoxAccountsCommand. */
if (g_strcmp0 (type, "FirefoxAccountsCommand")) {
g_warning ("Unknown command type: %s", type);
- goto free_node;
- }
- if (!json_object_has_member (json, "detail") ||
- !JSON_NODE_HOLDS_OBJECT (json_object_get_member (json, "detail"))) {
- g_warning ("JSON object has invalid 'detail' member");
- goto free_node;
+ goto out_error;
}
detail = json_object_get_object_member (json, "detail");
- if (!json_object_has_member (detail, "command") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (detail, "command"))) {
- g_warning ("JSON object has invalid 'command' member");
- goto free_node;
+ if (!detail) {
+ g_warning ("JSON object has missing or invalid 'detail' member");
+ goto out_error;
}
-
command = json_object_get_string_member (detail, "command");
+ if (!command) {
+ g_warning ("JSON object has missing or invalid 'command' member");
+ goto out_error;
+ }
+
if (!g_strcmp0 (command, "loaded")) {
LOG ("Firefox Accounts iframe loaded");
- is_internal_error = FALSE;
- } else if (!g_strcmp0 (command, "can_link_account")) {
+ goto out_no_error;
+ }
+ if (!g_strcmp0 (command, "can_link_account")) {
/* We need to confirm a relink. */
sync_send_data_to_fxa_server (dialog, "message", "can_link_account", "{'ok': true}");
- is_internal_error = FALSE;
- } else if (!g_strcmp0 (command, "login")) {
- if (!json_object_has_member (detail, "data") ||
- !JSON_NODE_HOLDS_OBJECT (json_object_get_member (detail, "data"))) {
- g_warning ("JSON object has invalid 'data' member");
- goto free_node;
- }
-
- gtk_widget_set_visible (dialog->sync_firefox_iframe_label, FALSE);
- sync_send_data_to_fxa_server (dialog, "message", "login", NULL);
-
- data = json_object_get_object_member (detail, "data");
- if (!json_object_has_member (data, "uid") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (data, "uid")) ||
- !json_object_has_member (data, "email") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (data, "email")) ||
- !json_object_has_member (data, "sessionToken") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (data, "sessionToken")) ||
- !json_object_has_member (data, "keyFetchToken") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (data, "keyFetchToken")) ||
- !json_object_has_member (data, "unwrapBKey") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (data, "unwrapBKey")) ||
- !json_object_has_member (data, "verified") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (data, "verified"))) {
- g_warning ("JSON object has missing or invalid members");
- goto free_node;
- }
-
- email = json_object_get_string_member (data, "email");
- uid = json_object_get_string_member (data, "uid");
- sessionToken = json_object_get_string_member (data, "sessionToken");
- keyFetchToken = json_object_get_string_member (data, "keyFetchToken");
- unwrapBKey = json_object_get_string_member (data, "unwrapBKey");
- verified = json_object_get_boolean_member (data, "verified");
+ goto out_no_error;
+ }
+ if (g_strcmp0 (command, "login")) {
+ g_warning ("Unexepected command: %s", command);
+ goto out_error;
+ }
- if (!verified) {
- sync_sign_in_details_show (dialog, _("Please don’t leave this page until "
- "you have completed the verification."));
- }
+ /* Login command. */
+ gtk_widget_set_visible (dialog->sync_firefox_iframe_label, FALSE);
+ sync_send_data_to_fxa_server (dialog, "message", "login", NULL);
- ephy_sync_service_do_sign_in (dialog->sync_service, email, uid,
- sessionToken, keyFetchToken, unwrapBKey);
- is_internal_error = FALSE;
- } else {
- g_warning ("Unexepected command: %s", command);
+ data = json_object_get_object_member (detail, "data");
+ if (!data) {
+ g_warning ("JSON object has invalid 'data' member");
+ goto out_error;
+ }
+ email = json_object_get_string_member (data, "email");
+ uid = json_object_get_string_member (data, "uid");
+ sessionToken = json_object_get_string_member (data, "sessionToken");
+ keyFetchToken = json_object_get_string_member (data, "keyFetchToken");
+ unwrapBKey = json_object_get_string_member (data, "unwrapBKey");
+ if (!email || !uid || !sessionToken || !keyFetchToken || !unwrapBKey) {
+ g_warning ("JSON object has missing or invalid members");
+ goto out_error;
+ }
+ if (!json_object_has_member (data, "verified") ||
+ !JSON_NODE_HOLDS_VALUE (json_object_get_member (data, "verified"))) {
+ g_warning ("JSON object has missing or invalid 'verified' member");
+ goto out_error;
}
-free_node:
- json_node_unref (node);
-free_string:
+ if (!json_object_get_boolean_member (data, "verified"))
+ sync_sign_in_details_show (dialog, _("Please don’t leave this page until "
+ "you have completed the verification."));
+ ephy_sync_service_do_sign_in (dialog->sync_service, email, uid,
+ sessionToken, keyFetchToken, unwrapBKey);
+ goto out_no_error;
+
+out_error:
+ sync_sign_in_details_show (dialog, _("Something went wrong, please try again."));
+ webkit_web_view_load_uri (dialog->fxa_web_view, FXA_IFRAME_URL);
+out_no_error:
+ if (node)
+ json_node_unref (node);
+ if (error)
+ g_error_free (error);
g_free (json_string);
-out:
- if (is_internal_error) {
- sync_sign_in_details_show (dialog, _("Something went wrong, please try again."));
- webkit_web_view_load_uri (dialog->fxa_web_view, FXA_IFRAME_URL);
- }
}
static void
diff --git a/src/sync/ephy-sync-crypto.c b/src/sync/ephy-sync-crypto.c
index 7133bef..24d818c 100644
--- a/src/sync/ephy-sync-crypto.c
+++ b/src/sync/ephy-sync-crypto.c
@@ -970,13 +970,13 @@ char *
ephy_sync_crypto_decrypt_record (const char *payload,
SyncCryptoKeyBundle *bundle)
{
- JsonNode *node;
- JsonObject *json;
+ JsonNode *node = NULL;
+ JsonObject *json = NULL;
GError *error = NULL;
- guint8 *aes_key;
- guint8 *hmac_key;
- guint8 *ciphertext;
- guint8 *iv;
+ guint8 *aes_key = NULL;
+ guint8 *hmac_key = NULL;
+ guint8 *ciphertext = NULL;
+ guint8 *iv = NULL;
char *cleartext = NULL;
const char *ciphertext_b64;
const char *iv_b64;
@@ -991,23 +991,20 @@ ephy_sync_crypto_decrypt_record (const char *payload,
node = json_from_string (payload, &error);
if (error) {
g_warning ("Payload is not a valid JSON: %s", error->message);
- g_error_free (error);
goto out;
}
- if (!JSON_NODE_HOLDS_OBJECT (node)) {
- g_warning ("JSON node does not hold a JSON object");
- goto free_node;
- }
json = json_node_get_object (node);
- if (!json_object_has_member (json, "ciphertext") ||
- !json_object_has_member (json, "IV") ||
- !json_object_has_member (json, "hmac")) {
- g_warning ("JSON object has missing members");
- goto free_node;
+ if (!json) {
+ g_warning ("JSON node does not hold a JSON object");
+ goto out;
}
ciphertext_b64 = json_object_get_string_member (json, "ciphertext");
iv_b64 = json_object_get_string_member (json, "IV");
hmac = json_object_get_string_member (json, "hmac");
+ if (!ciphertext_b64 || !iv_b64 || !hmac) {
+ g_warning ("JSON object has missing or invalid members");
+ goto out;
+ }
/* Get the encryption key and the HMAC key. */
aes_key = ephy_sync_crypto_decode_hex (bundle->aes_key_hex);
@@ -1017,7 +1014,7 @@ ephy_sync_crypto_decrypt_record (const char *payload,
* if the HMAC verification fails. */
if (!ephy_sync_crypto_hmac_is_valid (ciphertext_b64, hmac_key, hmac)) {
g_warning ("Incorrect HMAC value");
- goto free_keys;
+ goto out;
}
/* Finally, decrypt the record. */
@@ -1025,14 +1022,16 @@ ephy_sync_crypto_decrypt_record (const char *payload,
iv = g_base64_decode (iv_b64, &iv_len);
cleartext = ephy_sync_crypto_aes_256_decrypt (ciphertext, ciphertext_len, aes_key, iv);
+out:
g_free (ciphertext);
g_free (iv);
-free_keys:
g_free (aes_key);
g_free (hmac_key);
-free_node:
- json_node_unref (node);
-out:
+ if (node)
+ json_node_unref (node);
+ if (error)
+ g_error_free (error);
+
return cleartext;
}
diff --git a/src/sync/ephy-sync-service.c b/src/sync/ephy-sync-service.c
index 3cfc543..8cc65ff 100644
--- a/src/sync/ephy-sync-service.c
+++ b/src/sync/ephy-sync-service.c
@@ -440,16 +440,16 @@ ephy_sync_service_certificate_is_valid (EphySyncService *self,
char **pieces;
char *header;
char *payload;
- char *expected;
+ char *expected = NULL;
const char *alg;
const char *email;
gsize len;
gboolean retval = FALSE;
g_assert (EPHY_IS_SYNC_SERVICE (self));
+ g_assert (ephy_sync_service_get_secret (self, secrets[UID]));
g_assert (certificate);
- uri = soup_uri_new (MOZILLA_FXA_SERVER_URL);
pieces = g_strsplit (certificate, ".", 0);
header = (char *)ephy_sync_crypto_base64_urlsafe_decode (pieces[0], &len, TRUE);
payload = (char *)ephy_sync_crypto_base64_urlsafe_decode (pieces[1], &len, TRUE);
@@ -458,20 +458,18 @@ ephy_sync_service_certificate_is_valid (EphySyncService *self,
json_parser_load_from_data (parser, header, -1, &error);
if (error) {
g_warning ("Header is not a valid JSON: %s", error->message);
- g_error_free (error);
goto out;
}
- if (!JSON_NODE_HOLDS_OBJECT (json_parser_get_root (parser))) {
+ json = json_node_get_object (json_parser_get_root (parser));
+ if (!json) {
g_warning ("JSON node does not hold a JSON object");
goto out;
}
- json = json_node_get_object (json_parser_get_root (parser));
- if (!json_object_has_member (json, "alg") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "alg"))) {
+ alg = json_object_get_string_member (json, "alg");
+ if (!alg) {
g_warning ("JSON object has missing or invalid 'alg' member");
goto out;
}
- alg = json_object_get_string_member (json, "alg");
if (g_strcmp0 (alg, "RS256")) {
g_warning ("Expected algorithm RS256, found %s", alg);
goto out;
@@ -479,44 +477,39 @@ ephy_sync_service_certificate_is_valid (EphySyncService *self,
json_parser_load_from_data (parser, payload, -1, &error);
if (error) {
g_warning ("Payload is not a valid JSON: %s", error->message);
- g_error_free (error);
goto out;
}
- if (!JSON_NODE_HOLDS_OBJECT (json_parser_get_root (parser))) {
+ json = json_node_get_object (json_parser_get_root (parser));
+ if (!json) {
g_warning ("JSON node does not hold a JSON object");
goto out;
}
- json = json_node_get_object (json_parser_get_root (parser));
- if (!json_object_has_member (json, "principal") ||
- !JSON_NODE_HOLDS_OBJECT (json_object_get_member (json, "principal"))) {
+ principal = json_object_get_object_member (json, "principal");
+ if (!principal) {
g_warning ("JSON object has missing or invalid 'principal' member");
goto out;
}
- principal = json_object_get_object_member (json, "principal");
- if (!json_object_has_member (principal, "email") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (principal, "email"))) {
- g_warning ("JSON object has misisng or invalid 'email' member");
+ email = json_object_get_string_member (principal, "email");
+ if (!email) {
+ g_warning ("JSON object has missing or invalid 'email' member");
goto out;
}
- email = json_object_get_string_member (principal, "email");
+ uri = soup_uri_new (MOZILLA_FXA_SERVER_URL);
expected = g_strdup_printf ("%s@%s",
ephy_sync_service_get_secret (self, secrets[UID]),
soup_uri_get_host (uri));
- if (g_strcmp0 (email, expected)) {
- g_warning ("Expected email %s, found %s", expected, email);
- goto free_expected;
- }
+ retval = g_strcmp0 (email, expected) == 0;
- retval = TRUE;
-
-free_expected:
- g_free (expected);
out:
+ g_free (expected);
g_object_unref (parser);
g_free (payload);
g_free (header);
g_strfreev (pieces);
- soup_uri_free (uri);
+ if (uri)
+ soup_uri_free (uri);
+ if (error)
+ g_error_free (error);
return retval;
}
@@ -582,55 +575,54 @@ obtain_storage_credentials_cb (SoupSession *session,
gpointer user_data)
{
EphySyncService *self;
- JsonNode *node;
- JsonObject *json;
+ JsonNode *node = NULL;
+ JsonObject *json = NULL;
GError *error = NULL;
- gboolean is_internal_error = TRUE;
+ const char *api_endpoint;
+ const char *id;
+ const char *key;
+ int duration;
+
+ self = ephy_shell_get_sync_service (ephy_shell_get_default ());
if (msg->status_code != 200) {
- g_warning ("Failed to get storage credentials from Token Server. Status code: %u, response: %s",
+ g_warning ("Failed to obtain storage credentials. Status code: %u, response: %s",
msg->status_code, msg->response_body->data);
goto out;
}
-
node = json_from_string (msg->response_body->data, &error);
if (error) {
g_warning ("Response is not a valid JSON: %s", error->message);
- g_error_free (error);
goto out;
}
- if (!JSON_NODE_HOLDS_OBJECT (node)) {
+ json = json_node_get_object (node);
+ if (!json) {
g_warning ("JSON node does not hold a JSON object");
- goto free_node;
+ goto out;
}
- json = json_node_get_object (node);
- if (!json_object_has_member (json, "api_endpoint") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "api_endpoint")) ||
- !json_object_has_member (json, "id") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "id")) ||
- !json_object_has_member (json, "key") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "key")) ||
- !json_object_has_member (json, "duration") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "duration"))) {
+ api_endpoint = json_object_get_string_member (json, "api_endpoint");
+ id = json_object_get_string_member (json, "id");
+ key = json_object_get_string_member (json, "key");
+ duration = json_object_get_int_member (json, "duration");
+ if (!api_endpoint || !id || !key || !duration) {
g_warning ("JSON object has missing or invalid members");
- goto free_node;
+ goto out;
}
- self = ephy_shell_get_sync_service (ephy_shell_get_default ());
- self->storage_endpoint = g_strdup (json_object_get_string_member (json, "api_endpoint"));
- self->storage_credentials_id = g_strdup (json_object_get_string_member (json, "id"));
- self->storage_credentials_key = g_strdup (json_object_get_string_member (json, "key"));
- self->storage_credentials_expiry_time = json_object_get_int_member (json, "duration") + g_get_real_time ()
/ 1000000;
- is_internal_error = FALSE;
+ self->storage_endpoint = g_strdup (api_endpoint);
+ self->storage_credentials_id = g_strdup (id);
+ self->storage_credentials_key = g_strdup (key);
+ self->storage_credentials_expiry_time = duration + g_get_real_time () / 1000000;
+
+ while (!g_queue_is_empty (self->storage_queue))
+ ephy_sync_service_send_storage_request (self, g_queue_pop_head (self->storage_queue));
-free_node:
- json_node_unref (node);
out:
self->locked = FALSE;
- if (!is_internal_error) {
- while (!g_queue_is_empty (self->storage_queue))
- ephy_sync_service_send_storage_request (self, g_queue_pop_head (self->storage_queue));
- }
+ if (node)
+ json_node_unref (node);
+ if (error)
+ g_error_free (error);
}
static char *
@@ -705,80 +697,64 @@ obtain_signed_certificate_cb (SoupSession *session,
gpointer user_data)
{
EphySyncService *self;
- JsonNode *node;
- JsonObject *json;
+ JsonNode *node = NULL;
+ JsonObject *json = NULL;
GError *error = NULL;
- const char *certificate;
const char *suggestion = NULL;
- char *message = NULL;
- gboolean is_internal_error = TRUE;
+ const char *message = NULL;
+ const char *certificate = NULL;
self = ephy_shell_get_sync_service (ephy_shell_get_default ());
node = json_from_string (msg->response_body->data, &error);
if (error) {
g_warning ("Response is not a valid JSON: %s", error->message);
- g_error_free (error);
- goto out;
+ goto out_error;
}
- if (!JSON_NODE_HOLDS_OBJECT (node)) {
+ json = json_node_get_object (node);
+ if (!json) {
g_warning ("JSON node does not hold a JSON object");
- goto free_node;
+ goto out_error;
}
- json = json_node_get_object (node);
- if (msg->status_code != 200) {
- if (!json_object_has_member (json, "errno") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "errno"))) {
- g_warning ("JSON object has missing or invalid 'errno' member");
- goto free_node;
+ if (msg->status_code == 200) {
+ certificate = json_object_get_string_member (json, "cert");
+ if (!certificate) {
+ g_warning ("JSON object has missing or invalid 'cert' member");
+ goto out_error;
}
-
- /* Since a new Firefox Account password implies new tokens, this will fail
- * with an error code 110 (Invalid authentication token in request signature)
- * if the user has changed his password since the last time he signed in.
- * When this happens, notify the user to sign in with the new password. */
- if (msg->status_code == 401 && json_object_get_int_member (json, "errno") == 110) {
- message = g_strdup_printf (_("The password of your Firefox account %s seems to have been changed."),
- ephy_sync_service_get_user_email (self));
- suggestion = _("Please visit Preferences and sign in with the new password to continue syncing.");
- goto free_node;
+ if (!ephy_sync_service_certificate_is_valid (self, certificate)) {
+ g_warning ("Invalid certificate");
+ ephy_sync_crypto_rsa_key_pair_free (self->keypair);
+ goto out_error;
}
-
- g_warning ("Failed to sign certificate. Status code: %u, response: %s",
- msg->status_code, msg->response_body->data);
- goto free_node;
- }
-
- if (!json_object_has_member (json, "cert") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "cert"))) {
- g_warning ("JSON object has missing or invalid 'cert' member");
- goto free_node;
+ self->certificate = g_strdup (certificate);
+ ephy_sync_service_obtain_storage_credentials (self);
+ goto out_no_error;
}
- certificate = json_object_get_string_member (json, "cert");
- if (!ephy_sync_service_certificate_is_valid (self, certificate)) {
- g_warning ("Invalid certificate");
- ephy_sync_crypto_rsa_key_pair_free (self->keypair);
- goto free_node;
+ /* Since a new Firefox Account password implies new tokens, this will fail
+ * with an error code 110 (Invalid authentication token in request signature)
+ * if the user has changed his password since the last time he signed in.
+ * When this happens, notify the user to sign in with the new password. */
+ if (json_object_get_int_member (json, "errno") == 110) {
+ message = _("The password of your Firefox account seems to have been changed.");
+ suggestion = _("Please visit Preferences and sign in with the new password to continue syncing.");
}
- self->certificate = g_strdup (certificate);
- is_internal_error = FALSE;
+ g_warning ("Failed to sign certificate. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
-free_node:
- json_node_unref (node);
-out:
- if (is_internal_error) {
- self->locked = FALSE;
- ephy_notification_show (ephy_notification_new (message ? message
- : _("Something went wrong while syncing."),
- suggestion ? suggestion
- : _("Please visit Preferences and sign in
again.")));
- g_free (message);
- } else {
- ephy_sync_service_obtain_storage_credentials (self);
- }
+out_error:
+ message = message ? message : _("Something went wrong while syncing.");
+ suggestion = suggestion ? suggestion : _("Please visit Preferences and sign in again.");
+ ephy_notification_show (ephy_notification_new (message, suggestion));
+ self->locked = FALSE;
+out_no_error:
+ if (node)
+ json_node_unref (node);
+ if (error)
+ g_error_free (error);
}
static void
@@ -878,9 +854,9 @@ download_synchronizable_cb (SoupSession *session,
{
EphySyncService *self;
EphySynchronizable *synchronizable;
- SyncCryptoKeyBundle *bundle;
+ SyncCryptoKeyBundle *bundle = NULL;
SyncAsyncData *data;
- JsonNode *node;
+ JsonNode *node = NULL;
GError *error = NULL;
GType type;
const char *collection;
@@ -894,21 +870,18 @@ download_synchronizable_cb (SoupSession *session,
msg->status_code, msg->response_body->data);
goto out;
}
-
node = json_from_string (msg->response_body->data, &error);
if (error) {
g_warning ("Response is not a valid JSON");
- g_error_free (error);
goto out;
}
-
type = ephy_synchronizable_manager_get_synchronizable_type (data->manager);
collection = ephy_synchronizable_manager_get_collection_name (data->manager);
bundle = ephy_sync_service_get_key_bundle (self, collection);
synchronizable = EPHY_SYNCHRONIZABLE (ephy_synchronizable_from_bso (node, type, bundle, &is_deleted));
if (!synchronizable) {
g_warning ("Failed to create synchronizable object from BSO");
- goto free_bundle;
+ goto out;
}
/* Delete the local object and add the remote one if it is not marked as deleted. */
@@ -919,10 +892,13 @@ download_synchronizable_cb (SoupSession *session,
}
g_object_unref (synchronizable);
-free_bundle:
- ephy_sync_crypto_key_bundle_free (bundle);
- json_node_unref (node);
out:
+ if (node)
+ json_node_unref (node);
+ if (error)
+ g_error_free (error);
+ if (bundle)
+ ephy_sync_crypto_key_bundle_free (bundle);
sync_async_data_free (data);
}
@@ -1029,11 +1005,11 @@ sync_collection_cb (SoupSession *session,
EphySynchronizable *remote;
SyncCryptoKeyBundle *bundle;
JsonNode *node = NULL;
- JsonArray *array;
+ JsonArray *array = NULL;
GError *error = NULL;
GList *remotes_updated = NULL;
GList *remotes_deleted = NULL;
- GList *to_upload;
+ GList *to_upload = NULL;
GType type;
const char *collection;
const char *timestamp;
@@ -1048,28 +1024,24 @@ sync_collection_cb (SoupSession *session,
LOG ("There are no new remote objects");
goto merge_remotes;
}
-
if (msg->status_code != 200) {
g_warning ("Failed to get records in collection %s. Status code: %u, response: %s",
collection, msg->status_code, msg->response_body->data);
goto out;
}
-
node = json_from_string (msg->response_body->data, &error);
if (error) {
g_warning ("Response is not a valid JSON: %s", error->message);
- g_error_free (error);
goto out;
}
- if (!JSON_NODE_HOLDS_ARRAY (node)) {
- g_warning ("JSON root does not hold an array");
- goto free_node;
+ array = json_node_get_array (node);
+ if (!array) {
+ g_warning ("JSON node does not hold an array");
+ goto out;
}
type = ephy_synchronizable_manager_get_synchronizable_type (data->manager);
bundle = ephy_sync_service_get_key_bundle (self, collection);
- array = json_node_get_array (node);
-
for (guint i = 0; i < json_array_get_length (array); i++) {
remote = EPHY_SYNCHRONIZABLE (ephy_synchronizable_from_bso (json_array_get_element (array, i),
type, bundle, &is_deleted));
@@ -1086,30 +1058,28 @@ sync_collection_cb (SoupSession *session,
merge_remotes:
to_upload = ephy_synchronizable_manager_merge_remotes (data->manager, data->is_initial,
remotes_deleted, remotes_updated);
+ for (GList *l = to_upload; l && l->data; l = l->next)
+ ephy_sync_service_upload_synchronizable (self, data->manager, EPHY_SYNCHRONIZABLE (l->data));
- if (to_upload) {
- LOG ("Uploading local objects to server...");
- for (GList *l = to_upload; l && l->data; l = l->next) {
- ephy_sync_service_upload_synchronizable (self, data->manager,
- EPHY_SYNCHRONIZABLE (l->data));
- }
- }
-
- ephy_synchronizable_manager_set_is_initial_sync (data->manager, FALSE);
/* Update sync time. */
timestamp = soup_message_headers_get_one (msg->response_headers, "X-Weave-Timestamp");
ephy_synchronizable_manager_set_sync_time (data->manager, g_ascii_strtod (timestamp, NULL));
+ ephy_synchronizable_manager_set_is_initial_sync (data->manager, FALSE);
- g_list_free_full (to_upload, g_object_unref);
- g_list_free_full (remotes_updated, g_object_unref);
- g_list_free_full (remotes_deleted, g_object_unref);
-free_node:
- if (node)
- json_node_unref (node);
out:
if (data->collection_index == data->num_collections)
g_signal_emit (self, signals[SYNC_FINISHED], 0);
+ if (to_upload)
+ g_list_free_full (to_upload, g_object_unref);
+ if (remotes_updated)
+ g_list_free_full (remotes_updated, g_object_unref);
+ if (remotes_deleted)
+ g_list_free_full (remotes_deleted, g_object_unref);
+ if (node)
+ json_node_unref (node);
+ if (error)
+ g_error_free (error);
sync_collection_async_data_free (data);
}
@@ -1516,13 +1486,12 @@ obtain_crypto_keys_cb (SoupSession *session,
{
EphySyncService *self;
SyncCryptoKeyBundle *bundle = NULL;
- JsonObject *json;
JsonNode *node = NULL;
+ JsonObject *json = NULL;
GError *error = NULL;
const char *payload;
- char *crypto_keys;
+ char *crypto_keys = NULL;
guint8 *kB = NULL;
- gboolean is_internal_error = TRUE;
self = ephy_shell_get_sync_service (ephy_shell_get_default ());
@@ -1534,55 +1503,50 @@ obtain_crypto_keys_cb (SoupSession *session,
if (msg->status_code != 200) {
g_warning ("Failed to get crypto/keys record. Status code: %u, response: %s",
msg->status_code, msg->response_body->data);
- goto out;
+ goto out_error;
}
node = json_from_string (msg->response_body->data, &error);
if (error) {
g_warning ("Response is not a valid JSON: %s", error->message);
- g_error_free (error);
- goto out;
- }
- if (!JSON_NODE_HOLDS_OBJECT (node)) {
- g_warning ("JSON root does not hold an object");
- goto free_node;
+ goto out_error;
}
json = json_node_get_object (node);
- if (!json_object_has_member (json, "payload")) {
- g_warning ("JSON object is missing 'payload' member");
- goto free_node;
+ if (!json) {
+ g_warning ("JSON node does not hold an object");
+ goto out_error;
+ }
+ payload = json_object_get_string_member (json, "payload");
+ if (!payload) {
+ g_warning ("JSON object has missing or invalid 'payload' member");
+ goto out_error;
}
-
/* Derive the Sync Key bundle from kB. The bundle consists of two 32 bytes keys:
* the first one used as a symmetric encryption key (AES) and the second one
* used as a HMAC key. */
kB = ephy_sync_crypto_decode_hex (ephy_sync_service_get_secret (self, secrets[MASTER_KEY]));
bundle = ephy_sync_crypto_derive_key_bundle (kB, TOKEN_LENGTH);
- payload = json_object_get_string_member (json, "payload");
crypto_keys = ephy_sync_crypto_decrypt_record (payload, bundle);
if (!crypto_keys) {
- g_warning ("Failed to decrypt crypto keys record");
- goto free_bundle;
+ g_warning ("Failed to decrypt crypto/keys record");
+ goto out_error;
}
store_secrets:
ephy_sync_service_set_secret (self, secrets[CRYPTO_KEYS], crypto_keys);
ephy_sync_secret_store_secrets (self);
- is_internal_error = FALSE;
-
- g_free (crypto_keys);
-free_bundle:
+ goto out_no_error;
+out_error:
+ ephy_sync_service_report_sign_in_error (self, _("Failed to retrieve crypto keys."), TRUE);
+out_no_error:
if (bundle)
ephy_sync_crypto_key_bundle_free (bundle);
- g_free (kB);
-free_node:
if (node)
json_node_unref (node);
-out:
- if (is_internal_error)
- ephy_sync_service_report_sign_in_error (self,
- _("Failed to retrieve crypto keys."),
- TRUE);
+ if (error)
+ g_error_free (error);
+ g_free (crypto_keys);
+ g_free (kB);
}
static void
@@ -1669,12 +1633,11 @@ check_storage_version_cb (SoupSession *session,
{
EphySyncService *self;
JsonParser *parser = NULL;
- JsonObject *json;
+ JsonObject *json = NULL;
GError *error = NULL;
char *payload = NULL;
char *message = NULL;
int storage_version;
- gboolean is_internal_error = TRUE;
self = ephy_shell_get_sync_service (ephy_shell_get_default ());
@@ -1684,74 +1647,64 @@ check_storage_version_cb (SoupSession *session,
}
if (msg->status_code != 200) {
- g_warning ("Failed to check storage version. Status code: %u, response: %s",
+ g_warning ("Failed to get meta/global record. Status code: %u, response: %s",
msg->status_code, msg->response_body->data);
- goto out;
+ goto out_error;
}
parser = json_parser_new ();
json_parser_load_from_data (parser, msg->response_body->data, -1, &error);
if (error) {
g_warning ("Response is not a valid JSON: %s", error->message);
- g_error_free (error);
- goto free_parser;
+ goto out_error;
}
- if (!JSON_NODE_HOLDS_OBJECT (json_parser_get_root (parser))) {
+ json = json_node_get_object (json_parser_get_root (parser));
+ if (!json) {
g_warning ("JSON node does not hold a JSON object");
- goto free_parser;
+ goto out_error;
}
-
- json = json_node_get_object (json_parser_get_root (parser));
- if (!json_object_has_member (json, "payload") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "payload"))) {
+ if (!json_object_get_string_member (json, "payload")) {
g_warning ("JSON object has missing or invalid 'payload' member");
- goto free_parser;
+ goto out_error;
}
payload = g_strdup (json_object_get_string_member (json, "payload"));
json_parser_load_from_data (parser, payload, -1, &error);
if (error) {
g_warning ("Payload is not a valid JSON: %s", error->message);
- g_error_free (error);
- goto free_payload;
+ goto out_error;
}
- if (!JSON_NODE_HOLDS_OBJECT (json_parser_get_root (parser))) {
+ json = json_node_get_object (json_parser_get_root (parser));
+ if (!json) {
g_warning ("JSON node does not hold a JSON object");
- goto free_payload;
+ goto out_error;
}
- json = json_node_get_object (json_parser_get_root (parser));
- if (!json_object_has_member (json, "storageVersion") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "storageVersion"))) {
+ if (!json_object_get_int_member (json, "storageVersion")) {
g_warning ("JSON object has missing or invalid 'storageVersion' member");
- goto free_payload;
+ goto out_error;
}
storage_version = json_object_get_int_member (json, "storageVersion");
if (storage_version != STORAGE_VERSION) {
- LOG ("Unsupported storage version: %d", storage_version);
/* Translators: the %d is the storage version, the \n is a newline character. */
message = g_strdup_printf (_("Your Firefox Account uses storage version %d "
"which Epiphany does not support.\n"
"Create a new account to use the latest storage version."),
storage_version);
- goto free_payload;
+ goto out_error;
}
obtain_crypto_keys:
ephy_sync_service_obtain_crypto_keys (self);
- is_internal_error = FALSE;
-
-free_payload:
- g_free (payload);
-free_parser:
+ goto out_no_error;
+out_error:
+ message = message ? message : _("Failed to verify storage version.");
+ ephy_sync_service_report_sign_in_error (self, message, TRUE);
+out_no_error:
if (parser)
g_object_unref (parser);
-out:
- if (is_internal_error) {
- ephy_sync_service_report_sign_in_error (self,
- message ? message
- : _("Failed to verify storage version."),
- TRUE);
- g_free (message);
- }
+ if (error)
+ g_error_free (error);
+ g_free (payload);
+ g_free (message);
}
static void
@@ -1783,18 +1736,15 @@ ephy_sync_service_conclude_sign_in (EphySyncService *self,
if (!ephy_sync_crypto_compute_sync_keys (bundle, data->respHMACkey,
data->respXORkey, unwrapKB,
&kA, &kB, TOKEN_LENGTH)) {
- ephy_sync_service_report_sign_in_error (self,
- _("Failed to retrieve the Sync Key"),
- FALSE);
+ ephy_sync_service_report_sign_in_error (self, _("Failed to retrieve the Sync Key"), FALSE);
goto out;
}
- kB_hex = ephy_sync_crypto_encode_hex (kB, TOKEN_LENGTH);
-
- /* Save the email and the tokens. */
+ /* Save email and tokens. */
self->user_email = g_strdup (data->email);
ephy_sync_service_set_secret (self, secrets[UID], data->uid);
ephy_sync_service_set_secret (self, secrets[SESSION_TOKEN], data->sessionToken);
+ kB_hex = ephy_sync_crypto_encode_hex (kB, TOKEN_LENGTH);
ephy_sync_service_set_secret (self, secrets[MASTER_KEY], kB_hex);
ephy_sync_service_check_storage_version (self);
@@ -1814,67 +1764,57 @@ get_account_keys_cb (SoupSession *session,
{
EphySyncService *self;
SignInAsyncData *data;
- JsonNode *node;
- JsonObject *json;
+ JsonNode *node = NULL;
+ JsonObject *json = NULL;
GError *error = NULL;
- gboolean is_internal_error = TRUE;
+ const char *bundle;
self = ephy_shell_get_sync_service (ephy_shell_get_default ());
data = (SignInAsyncData *)user_data;
node = json_from_string (msg->response_body->data, &error);
+
if (error) {
g_warning ("Response is not a valid JSON: %s", error->message);
- g_error_free (error);
- goto out;
+ goto out_error;
}
- if (!JSON_NODE_HOLDS_OBJECT (node)) {
+ json = json_node_get_object (node);
+ if (!json) {
g_warning ("JSON node does not hold a JSON object");
- goto free_node;
+ goto out_error;
}
- json = json_node_get_object (node);
- if (msg->status_code != 200) {
- if (!json_object_has_member (json, "errno") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "errno"))) {
- g_warning ("JSON objetc has invalid 'errno' member");
- goto free_node;
- }
-
- /* If account in not verified, poll the Firefox Accounts Server until the
- * verification has completed. */
- if (json_object_get_int_member (json, "errno") == 104) {
- LOG ("Account not verified, retrying...");
- ephy_sync_service_fxa_hawk_get_async (self, "account/keys", data->tokenID_hex,
- data->reqHMACkey, TOKEN_LENGTH,
- get_account_keys_cb, data);
- is_internal_error = FALSE;
- goto free_node;
+ if (msg->status_code == 200) {
+ bundle = json_object_get_string_member (json, "bundle");
+ if (!bundle) {
+ g_warning ("JSON object has invalid or missing 'bundle' member");
+ goto out_error;
}
-
- g_warning ("Failed to GET /account/keys. Status code: %u, response: %s",
- msg->status_code, msg->response_body->data);
- goto free_node;
+ /* Extract the master sync keys from the bundle and save tokens. */
+ ephy_sync_service_conclude_sign_in (self, data, bundle);
+ goto out_no_error;
}
- if (!json_object_has_member (json, "bundle") ||
- !JSON_NODE_HOLDS_VALUE (json_object_get_member (json, "bundle"))) {
- g_warning ("JSON object has invalid or missing 'bundle' member");
- goto free_node;
+ /* If account in not verified, poll the Firefox Accounts Server until the
+ * verification has completed. */
+ if (json_object_get_int_member (json, "errno") == 104) {
+ LOG ("Account not verified, retrying...");
+ ephy_sync_service_fxa_hawk_get_async (self, "account/keys", data->tokenID_hex,
+ data->reqHMACkey, TOKEN_LENGTH,
+ get_account_keys_cb, data);
+ goto out_no_error;
}
- /* Extract the master sync keys from the bundle and save tokens. */
- ephy_sync_service_conclude_sign_in (self, data,
- json_object_get_string_member (json, "bundle"));
- is_internal_error = FALSE;
-free_node:
- json_node_unref (node);
-out:
- if (is_internal_error) {
- ephy_sync_service_report_sign_in_error (self,
- _("Failed to retrieve the Sync Key"),
- FALSE);
- sign_in_async_data_free (data);
- }
+ g_warning ("Failed to get /account/keys. Status code: %u, response: %s",
+ msg->status_code, msg->response_body->data);
+
+out_error:
+ ephy_sync_service_report_sign_in_error (self, _("Failed to retrieve the Sync Key"), FALSE);
+ sign_in_async_data_free (data);
+out_no_error:
+ if (node)
+ json_node_unref (node);
+ if (error)
+ g_error_free (error);
}
void
diff --git a/src/sync/ephy-synchronizable.c b/src/sync/ephy-synchronizable.c
index c002687..077c784 100644
--- a/src/sync/ephy-synchronizable.c
+++ b/src/sync/ephy-synchronizable.c
@@ -210,68 +210,60 @@ ephy_synchronizable_from_bso (JsonNode *bso,
{
GObject *object = NULL;
GError *error = NULL;
- JsonNode *node;
+ JsonNode *node = NULL;
JsonObject *json;
- JsonObject *record;
- char *serialized;
- const char *payload;
+ char *serialized = NULL;
+ const char *payload = NULL;
double modified;
g_return_val_if_fail (bso, NULL);
g_return_val_if_fail (bundle, NULL);
g_return_val_if_fail (is_deleted, NULL);
- if (!JSON_NODE_HOLDS_OBJECT (bso))
- goto out;
-
json = json_node_get_object (bso);
- if (!json_object_has_member (json, "id") ||
- !json_object_has_member (json, "payload") ||
- !json_object_has_member (json, "modified")) {
- g_warning ("BSO has missing members");
+ if (!json) {
+ g_warning ("JSON node does not hold a JSON object");
goto out;
}
-
payload = json_object_get_string_member (json, "payload");
modified = json_object_get_double_member (json, "modified");
+ if (!payload || !modified) {
+ g_warning ("JSON object has missing or invalid members");
+ goto out;
+ }
+
serialized = ephy_sync_crypto_decrypt_record (payload, bundle);
if (!serialized) {
g_warning ("Failed to decrypt the BSO payload");
goto out;
}
-
node = json_from_string (serialized, &error);
if (error) {
g_warning ("Decrypted text is not a valid JSON: %s", error->message);
- g_error_free (error);
- goto free_serialized;
- }
- if (!JSON_NODE_HOLDS_OBJECT (node)) {
- g_warning ("JSON root does not hold a JSON object");
- goto free_node;
+ goto out;
}
- record = json_node_get_object (node);
- if (json_object_has_member (record, "deleted")) {
- if (JSON_NODE_HOLDS_VALUE (json_object_get_member (record, "deleted")))
- *is_deleted = json_object_get_boolean_member (record, "deleted");
- } else {
- *is_deleted = FALSE;
+ json = json_node_get_object (node);
+ if (!json) {
+ g_warning ("Decrypted JSON node does not hold a JSON object");
+ goto out;
}
+ *is_deleted = json_object_has_member (json, "deleted");
object = json_gobject_from_data (gtype, serialized, -1, &error);
if (error) {
g_warning ("Failed to create GObject from BSO: %s", error->message);
- g_error_free (error);
- goto free_node;
+ goto out;
}
ephy_synchronizable_set_modification_time (EPHY_SYNCHRONIZABLE (object), modified);
ephy_synchronizable_set_is_uploaded (EPHY_SYNCHRONIZABLE (object), TRUE);
-free_node:
- json_node_unref (node);
-free_serialized:
- g_free (serialized);
out:
+ if (node)
+ json_node_unref (node);
+ if (error)
+ g_error_free (error);
+ g_free (serialized);
+
return object;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]