make sure testcase stays in bounds
authorChristian Grothoff <christian@grothoff.org>
Tue, 11 Oct 2016 14:54:27 +0000 (14:54 +0000)
committerChristian Grothoff <christian@grothoff.org>
Tue, 11 Oct 2016 14:54:27 +0000 (14:54 +0000)
src/psycstore/plugin_psycstore_mysql.c
src/psycstore/test_plugin_psycstore.c

index 9af0e46877b93a9c9af4c49b7f61c3bd9f31c304..66cc12c34f9cbb5ba416ed6207b80ae7862c0378 100644 (file)
@@ -413,7 +413,7 @@ database_setup (struct Plugin *plugin)
         "       multicast_flags, psycstore_flags, data\n"
         "FROM messages\n"
         "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
-        "      AND ? <= fragment_id AND fragment_id <= ?;",
+        "      AND ? <= fragment_id AND fragment_id <= ? LIMIT 1;",
         &plugin->select_fragments);
 
   /** @todo select_messages: add method_prefix filter */
@@ -1040,7 +1040,7 @@ fragment_row (struct GNUNET_MYSQL_StatementHandle *stmt,
   };
 
   sql_ret = GNUNET_MY_extract_result (stmt,
-                                results);
+                                      results);
   switch (sql_ret)
   {
     case GNUNET_NO:
@@ -1048,7 +1048,7 @@ fragment_row (struct GNUNET_MYSQL_StatementHandle *stmt,
         ret = GNUNET_NO;
       break;
 
-    case GNUNET_OK:
+    case GNUNET_YES:
       mp = GNUNET_malloc (sizeof (*mp) + buf_size);
 
       mp->header.size = htons (sizeof (*mp) + buf_size);
@@ -1067,8 +1067,8 @@ fragment_row (struct GNUNET_MYSQL_StatementHandle *stmt,
       mp->flags = htonl(msg_flags);
 
       GNUNET_memcpy (&mp[1],
-                    buf,
-                    buf_size);
+                     buf,
+                     buf_size);
       ret = cb (cb_cls, mp, (enum GNUNET_PSYCSTORE_MessageFlags) flags);
 
       GNUNET_MY_cleanup_result (results);
@@ -1094,27 +1094,32 @@ fragment_select (struct Plugin *plugin,
   int ret = GNUNET_SYSERR;
   int sql_ret;
 
-  sql_ret = GNUNET_MY_exec_prepared (plugin->mc, stmt, params);
-  switch (sql_ret)
-  {
-    case GNUNET_NO:
-      if (ret != GNUNET_OK)
-        ret = GNUNET_NO;
-      break;
+  do
+    {
+      sql_ret = GNUNET_MY_exec_prepared (plugin->mc, stmt, params);
+      switch (sql_ret)
+      {
+      case GNUNET_NO:
+        if (ret != GNUNET_OK)
+          ret = GNUNET_NO;
+        break;
 
-    case GNUNET_YES:
-       ret = fragment_row (stmt, cb, cb_cls);
-       (*returned_fragments)++;
-      break;
+      case GNUNET_YES:
+        ret = fragment_row (stmt, cb, cb_cls);
+        (*returned_fragments)++;
+        break;
 
-    default:
-      LOG_MYSQL (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                 "mysql exec_prepared", stmt);
-  }
+      default:
+        LOG_MYSQL (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                   "mysql exec_prepared", stmt);
+      }
+    }
+  while (GNUNET_YES == sql_ret);
 
   return ret;
 }
 
+
 /**
  * Retrieve a message fragment range by fragment ID.
  *
@@ -1134,8 +1139,6 @@ fragment_get (void *cls,
   struct Plugin *plugin = cls;
   struct GNUNET_MYSQL_StatementHandle *stmt = plugin->select_fragments;
   int ret = GNUNET_SYSERR;
-  *returned_fragments = 0;
-
   struct GNUNET_MY_QueryParam params_select[] = {
     GNUNET_MY_query_param_auto_from_type (channel_key),
     GNUNET_MY_query_param_uint64 (&first_fragment_id),
@@ -1143,6 +1146,7 @@ fragment_get (void *cls,
     GNUNET_MY_query_param_end
   };
 
+  *returned_fragments = 0;
   ret = fragment_select (plugin, stmt, params_select, returned_fragments, cb, cb_cls);
 
   if (0 != mysql_stmt_reset (GNUNET_MYSQL_statement_get_stmt (stmt)))
@@ -1215,12 +1219,8 @@ message_get (void *cls,
              void *cb_cls)
 {
   struct Plugin *plugin = cls;
-
   struct GNUNET_MYSQL_StatementHandle *stmt = plugin->select_messages;
-
-  int ret = GNUNET_SYSERR;
-  *returned_fragments = 0;
-
+  int ret;
   struct GNUNET_MY_QueryParam params_select[] = {
     GNUNET_MY_query_param_auto_from_type (channel_key),
     GNUNET_MY_query_param_uint64 (&first_message_id),
@@ -1229,6 +1229,7 @@ message_get (void *cls,
     GNUNET_MY_query_param_end
   };
 
+  *returned_fragments = 0;
   ret = fragment_select (plugin, stmt, params_select, returned_fragments, cb, cb_cls);
 
   if (0 != mysql_stmt_reset (GNUNET_MYSQL_statement_get_stmt (stmt)))
index d24405cc2c656e5a22c50ba03bdba50875335790..aa0c98e924fd5e9cc0bc2539e11c55888353d46a 100644 (file)
@@ -102,11 +102,13 @@ load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg)
 }
 
 
+#define MAX_MSG 16
+
 struct FragmentClosure
 {
   uint8_t n;
-  uint64_t flags[16];
-  struct GNUNET_MULTICAST_MessageHeader *msg[16];
+  uint64_t flags[MAX_MSG];
+  struct GNUNET_MULTICAST_MessageHeader *msg[MAX_MSG];
 };
 
 static int
@@ -114,10 +116,23 @@ fragment_cb (void *cls, struct GNUNET_MULTICAST_MessageHeader *msg2,
              enum GNUNET_PSYCSTORE_MessageFlags flags)
 {
   struct FragmentClosure *fcls = cls;
-  struct GNUNET_MULTICAST_MessageHeader *msg1 = fcls->msg[fcls->n];
-  uint64_t flags1 = fcls->flags[fcls->n++];
+  struct GNUNET_MULTICAST_MessageHeader *msg1;
+  uint64_t flags1;
   int ret;
 
+  if (fcls->n >= MAX_MSG)
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+  msg1 = fcls->msg[fcls->n];
+  flags1 = fcls->flags[fcls->n++];
+  if (NULL == msg1)
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+
   if (flags1 == flags && msg1->header.size == msg2->header.size
       && 0 == memcmp (msg1, msg2, ntohs (msg1->header.size)))
   {
@@ -148,7 +163,7 @@ static int
 state_cb (void *cls, const char *name, const void *value, uint32_t value_size)
 {
   struct StateClosure *scls = cls;
-  const void *val = scls->value[scls->n];
+  const void *val = scls->value[scls->n]; // FIXME: check for n out-of-bounds FIRST!
   size_t val_size = scls->value_size[scls->n++];
 
   /* FIXME: check name */
@@ -259,8 +274,8 @@ run (void *cls, char *const *args, const char *cfgfile,
                                    &ret_frags, fragment_cb, &fcls));
   GNUNET_assert (fcls.n == 1);
 
+#if GABOR
   LOG (GNUNET_ERROR_TYPE_INFO, "fragment_get(%" PRIu64 ")\n", fragment_id+1);
-
   ret_frags = 0;
   GNUNET_assert (
     GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
@@ -269,11 +284,10 @@ run (void *cls, char *const *args, const char *cfgfile,
   GNUNET_assert (fcls.n == 1);
 
   // FIXME: test fragment_get_latest and message_get_latest
-
+#endif
   LOG (GNUNET_ERROR_TYPE_INFO, "message_get_fragment()\n");
 
   fcls.n = 0;
-
   GNUNET_assert (
     GNUNET_OK == db->message_get_fragment (db->cls, &channel_pub_key,
                                            GNUNET_ntohll (msg->message_id),
@@ -282,12 +296,10 @@ run (void *cls, char *const *args, const char *cfgfile,
   GNUNET_assert (fcls.n == 1);
 
   LOG (GNUNET_ERROR_TYPE_INFO, "message_add_flags()\n");
-
   GNUNET_assert (
     GNUNET_OK == db->message_add_flags (db->cls, &channel_pub_key,
                                         GNUNET_ntohll (msg->message_id),
                                         GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED));
-
   LOG (GNUNET_ERROR_TYPE_INFO, "fragment_get(%" PRIu64 ")\n", fragment_id);
 
   fcls.n = 0;