diff options
author | Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com> | 2012-03-26 17:03:10 +0200 |
---|---|---|
committer | Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com> | 2012-03-26 17:03:10 +0200 |
commit | d9d77a665a3a0263885cd314e361f70bf7d42072 (patch) | |
tree | 5070b0165193b4d565b7772747a5d7196a2c32b5 | |
parent | afff91b26b3f8bde2a7ec7de2465cf15f0be4f7a (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.vala | 38 | ||||
-rw-r--r-- | src/errors.vala | 3 | ||||
-rw-r--r-- | src/utils.vala | 1 | ||||
-rw-r--r-- | src/zeitgeist-daemon.vala | 4 |
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 ( |