mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-01 15:10:56 +00:00
clipboard: match client labels against focus
When setting the config attribute 'match_labels="yes"', the clipboard performs plausibility checks for copy and paste operations against the nitpicker focus. Issue #3437
This commit is contained in:
parent
71ce1442c8
commit
db6e013577
@ -76,15 +76,11 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||||||
|
|
||||||
Genode::Attached_rom_dataspace _config { _env, "config" };
|
Genode::Attached_rom_dataspace _config { _env, "config" };
|
||||||
|
|
||||||
bool _verbose_config()
|
bool _verbose = false;
|
||||||
{
|
bool _match_labels = false;
|
||||||
char const *attr = "verbose";
|
|
||||||
return _config.xml().attribute_value(attr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool verbose { _verbose_config() };
|
|
||||||
|
|
||||||
typedef Genode::String<100> Domain;
|
typedef Genode::String<100> Domain;
|
||||||
|
typedef Genode::String<100> Label;
|
||||||
|
|
||||||
Genode::Attached_rom_dataspace _focus_ds { _env, "focus" };
|
Genode::Attached_rom_dataspace _focus_ds { _env, "focus" };
|
||||||
|
|
||||||
@ -94,6 +90,7 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||||||
{ _env.ep(), *this, &Main::_handle_focus };
|
{ _env.ep(), *this, &Main::_handle_focus };
|
||||||
|
|
||||||
Domain _focused_domain { };
|
Domain _focused_domain { };
|
||||||
|
Label _focused_label { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle configuration changes
|
* Handle configuration changes
|
||||||
@ -101,7 +98,8 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||||||
void _handle_config()
|
void _handle_config()
|
||||||
{
|
{
|
||||||
_config.update();
|
_config.update();
|
||||||
verbose = _verbose_config();
|
_verbose = _config.xml().attribute_value("verbose", false);
|
||||||
|
_match_labels = _config.xml().attribute_value("match_labels", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,14 +112,14 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||||||
_focus_ds.update();
|
_focus_ds.update();
|
||||||
|
|
||||||
_focused_domain = Domain();
|
_focused_domain = Domain();
|
||||||
|
_focused_label = Label();
|
||||||
|
|
||||||
try {
|
Genode::Xml_node const focus = _focus_ds.xml();
|
||||||
Genode::Xml_node focus(_focus_ds.local_addr<char>(), _focus_ds.size());
|
|
||||||
|
|
||||||
if (focus.attribute_value("active", false))
|
if (focus.attribute_value("active", false)) {
|
||||||
_focused_domain = focus.attribute_value("domain", Domain());
|
_focused_domain = focus.attribute_value("domain", Domain());
|
||||||
|
_focused_label = focus.attribute_value("label", Label());
|
||||||
} catch (...) { }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Domain _domain(Genode::Session_label const &label) const
|
Domain _domain(Genode::Session_label const &label) const
|
||||||
@ -135,20 +133,30 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||||||
return Domain();
|
return Domain();
|
||||||
}
|
}
|
||||||
|
|
||||||
Domain _domain(Rom::Reader const &reader) const
|
Label _label(Rom::Reader const &reader) const
|
||||||
{
|
{
|
||||||
Rom::Session_component const &rom_session =
|
Rom::Session_component const &rom_session =
|
||||||
static_cast<Rom::Session_component const &>(reader);
|
static_cast<Rom::Session_component const &>(reader);
|
||||||
|
|
||||||
return _domain(rom_session.label());
|
return rom_session.label();
|
||||||
}
|
}
|
||||||
|
|
||||||
Domain _domain(Rom::Writer const &writer) const
|
Domain _domain(Rom::Reader const &reader) const
|
||||||
|
{
|
||||||
|
return _domain(_label(reader));
|
||||||
|
}
|
||||||
|
|
||||||
|
Label _label(Rom::Writer const &writer) const
|
||||||
{
|
{
|
||||||
Report::Session_component const &report_session =
|
Report::Session_component const &report_session =
|
||||||
static_cast<Report::Session_component const &>(writer);
|
static_cast<Report::Session_component const &>(writer);
|
||||||
|
|
||||||
return _domain(report_session.label());
|
return report_session.label();
|
||||||
|
}
|
||||||
|
|
||||||
|
Domain _domain(Rom::Writer const &writer) const
|
||||||
|
{
|
||||||
|
return _domain(_label(writer));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _flow_defined(Domain const &from, Domain const &to) const
|
bool _flow_defined(Domain const &from, Domain const &to) const
|
||||||
@ -175,6 +183,39 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _client_label_matches_focus(Genode::Session_label const &label) const
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The client label has the suffix " -> clipboard". Strip off this
|
||||||
|
* part to make the label comparable with the label of the client's
|
||||||
|
* nitpicker session (which has of course no such suffix).
|
||||||
|
*/
|
||||||
|
char const *suffix = " -> clipboard";
|
||||||
|
size_t const suffix_len = strlen(suffix);
|
||||||
|
|
||||||
|
if (label.length() < suffix_len + 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
size_t const truncated_label_len = label.length() - suffix_len - 1;
|
||||||
|
|
||||||
|
Session_label const
|
||||||
|
truncated_label(Cstring(label.string(), truncated_label_len));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We accept any subsystem of the client to have the nitpicker focus.
|
||||||
|
* E.g., a multi-window application may have multiple nitpicker
|
||||||
|
* sessions, one for each window. The labels of all of those nitpicker
|
||||||
|
* session share the first part with application's clipboard label.
|
||||||
|
*/
|
||||||
|
bool const focus_lies_in_client_subsystem =
|
||||||
|
!strcmp(_focused_label.string(), truncated_label.string(),
|
||||||
|
truncated_label_len);
|
||||||
|
|
||||||
|
return focus_lies_in_client_subsystem;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rom::Module::Read_policy interface
|
* Rom::Module::Read_policy interface
|
||||||
*/
|
*/
|
||||||
@ -185,6 +226,9 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||||||
Domain const from_domain = _domain(writer);
|
Domain const from_domain = _domain(writer);
|
||||||
Domain const to_domain = _domain(reader);
|
Domain const to_domain = _domain(reader);
|
||||||
|
|
||||||
|
if (_match_labels && !_client_label_matches_focus(_label(reader)))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (from_domain == to_domain)
|
if (from_domain == to_domain)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -194,14 +238,16 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rom::Module::Write_policy interface
|
* Rom::Module::Write_policy interface
|
||||||
*/
|
*/
|
||||||
bool write_permitted(Rom::Module const &module,
|
bool write_permitted(Rom::Module const &module,
|
||||||
Rom::Writer const &writer) const override
|
Rom::Writer const &writer) const override
|
||||||
{
|
{
|
||||||
if (_focused_domain.valid() && _domain(writer) == _focused_domain)
|
bool const domain_matches =
|
||||||
|
_focused_domain.valid() && _domain(writer) == _focused_domain;
|
||||||
|
|
||||||
|
if ((!_match_labels || _client_label_matches_focus(_label(writer))) && domain_matches)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
warning("unexpected attempt by '", writer.label(), "' "
|
warning("unexpected attempt by '", writer.label(), "' "
|
||||||
@ -212,11 +258,12 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
|
|||||||
|
|
||||||
Rom::Registry _rom_registry { _env.ram(), _env.rm(), *this, *this };
|
Rom::Registry _rom_registry { _env.ram(), _env.rm(), *this, *this };
|
||||||
|
|
||||||
Report::Root report_root = { _env, _sliced_heap, _rom_registry, verbose };
|
Report::Root report_root = { _env, _sliced_heap, _rom_registry, _verbose };
|
||||||
Rom ::Root rom_root = { _env, _sliced_heap, _rom_registry };
|
Rom ::Root rom_root = { _env, _sliced_heap, _rom_registry };
|
||||||
|
|
||||||
Main(Genode::Env &env) : _env(env)
|
Main(Genode::Env &env) : _env(env)
|
||||||
{
|
{
|
||||||
|
_handle_config();
|
||||||
_focus_ds.sigh(_focus_handler);
|
_focus_ds.sigh(_focus_handler);
|
||||||
|
|
||||||
_handle_focus();
|
_handle_focus();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user