summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiegfried-Angel Gevatter Pujals <siegfried@gevatter.com>2012-03-26 17:03:10 +0200
committerSiegfried-Angel Gevatter Pujals <siegfried@gevatter.com>2012-03-26 17:03:10 +0200
commitd9d77a665a3a0263885cd314e361f70bf7d42072 (patch)
tree5070b0165193b4d565b7772747a5d7196a2c32b5
parentafff91b26b3f8bde2a7ec7de2465cf15f0be4f7a (diff)
Set a limit on the result size FindEvents and GetEvents may return.
D-Bus has a hard limit of 1GB of data per call and Gio limits us to 100MB. We need to ensure we don't go over this limit, since otherwise Zeitgeist will crash. Additionally, ransfers of such size take several minutes and are clear misuse of the Zeitgeist engine. Therefore, this commit limit the result of FindEvents and GetEvents calls to not more than 4MiB of data (2MiB would probably be enough, but let's leave some margin). Queries requesting more than this limit will get an exception.
-rw-r--r--src/datamodel.vala38
-rw-r--r--src/errors.vala3
-rw-r--r--src/utils.vala1
-rw-r--r--src/zeitgeist-daemon.vala4
4 files changed, 43 insertions, 3 deletions
diff --git a/src/datamodel.vala b/src/datamodel.vala
index 16215d4c..a8d06a41 100644
--- a/src/datamodel.vala
+++ b/src/datamodel.vala
@@ -621,6 +621,44 @@ namespace Zeitgeist
return vb.end ();
}
+ public static Variant to_variant_with_limit (GenericArray<Event?> events)
+ throws EngineError
+ {
+ var vb = new VariantBuilder(new VariantType("a("+Utils.SIG_EVENT+")"));
+
+ size_t variant_size = 0;
+
+ for (int i = 0; i < events.length; ++i)
+ {
+ Variant event_variant;
+
+ if (events[i] != null)
+ {
+ event_variant = events[i].to_variant ();
+ }
+ else
+ {
+ event_variant = get_null_event_variant ();
+ }
+
+ variant_size += event_variant.get_size();
+ if (variant_size > Utils.MAX_DBUS_RESULT_SIZE)
+ {
+ size_t avg_event_size = variant_size / (i+1);
+ string error_message = ("Query exceeded size limit of % " +
+ size_t.FORMAT + "MiB (roughly ~%d events).").printf (
+ Utils.MAX_DBUS_RESULT_SIZE / 1024 / 1024,
+ Utils.MAX_DBUS_RESULT_SIZE / avg_event_size);
+ warning (error_message);
+ throw new EngineError.TOO_MANY_RESULTS (error_message);
+ }
+
+ vb.add_value (event_variant);
+ }
+
+ return vb.end ();
+ }
+
private static Variant get_null_event_variant ()
{
var vb = new VariantBuilder (new VariantType ("("+Utils.SIG_EVENT+")"));
diff --git a/src/errors.vala b/src/errors.vala
index 8c07cfe7..b0c23a7b 100644
--- a/src/errors.vala
+++ b/src/errors.vala
@@ -29,10 +29,11 @@ namespace Zeitgeist
DATABASE_CORRUPT,
DATABASE_ERROR,
DATABASE_RETIRE_FAILED,
+ EXISTING_INSTANCE,
INVALID_ARGUMENT,
INVALID_KEY,
- EXISTING_INSTANCE,
INVALID_SIGNATURE, // FIXME: change from EngineError to sth. + public
+ TOO_MANY_RESULTS,
}
// vala doesn't include proper headers, this fixes it
diff --git a/src/utils.vala b/src/utils.vala
index 033fcfb7..6157d26e 100644
--- a/src/utils.vala
+++ b/src/utils.vala
@@ -38,6 +38,7 @@ namespace Zeitgeist
// D-Bus
public const string DBUS_INTERFACE = "";
public const string SIG_EVENT = "asaasay";
+ public const size_t MAX_DBUS_RESULT_SIZE = 4 * 1024 * 1024; // 4MiB
// configure runtime cache for events
// default size is 2000
diff --git a/src/zeitgeist-daemon.vala b/src/zeitgeist-daemon.vala
index 1a1effda..c52c1343 100644
--- a/src/zeitgeist-daemon.vala
+++ b/src/zeitgeist-daemon.vala
@@ -138,7 +138,7 @@ namespace Zeitgeist
var timer = new Timer ();
GenericArray<Event> events = engine.get_events (event_ids);
debug ("%s executed in %f seconds", Log.METHOD, timer.elapsed ());
- return Events.to_variant (events);
+ return Events.to_variant_with_limit (events);
}
public string[] find_related_uris (Variant time_range,
@@ -176,7 +176,7 @@ namespace Zeitgeist
Events.from_variant (event_templates),
storage_state, num_events, result_type, sender);
debug ("%s executed in %f seconds", Log.METHOD, timer.elapsed ());
- return Events.to_variant (events);
+ return Events.to_variant_with_limit (events);
}
public uint32[] insert_events (