[epiphany/wip/sync: 25/31] sync: Simplify goto statements



commit 809dd363dc81637be431c7a4eec1c41d5b3a2d50
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 |  461 ++++++++++++++++++------------------------
 3 files changed, 289 insertions(+), 365 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..2222de7 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,56 @@ 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;
 
   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) {
+    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 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, json_object_get_string_member (json, "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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]