From ef2986c0f3e0ce3346a28d86348d8cc1746e9b66 Mon Sep 17 00:00:00 2001 From: Aurelien Jacobs Date: Thu, 12 Feb 2015 15:46:42 +0100 Subject: [PATCH] device: ensure bind_enum() checks availability of Capability::LIST. This avoids a segfault calling bind_enum() with a non-initialized gvar_list. This closes bug #453. --- pv/binding/device.cpp | 21 ++++++++++----------- pv/binding/device.hpp | 7 +++---- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/pv/binding/device.cpp b/pv/binding/device.cpp index 224bc23a..7547a46b 100644 --- a/pv/binding/device.cpp +++ b/pv/binding/device.cpp @@ -62,15 +62,10 @@ Device::Device(shared_ptr configurable) : auto key = entry.first; auto capabilities = entry.second; - Glib::VariantContainerBase gvar_list; - if (!capabilities.count(Capability::GET) || !capabilities.count(Capability::SET)) continue; - if (capabilities.count(Capability::LIST)) - gvar_list = configurable->config_list(key); - string name_str; try { name_str = key->description(); @@ -106,7 +101,7 @@ Device::Device(shared_ptr configurable) : case SR_CONF_FILTER: case SR_CONF_COUPLING: case SR_CONF_CLOCK_EDGE: - bind_enum(name, gvar_list, get, set); + bind_enum(name, key, capabilities, get, set); break; case SR_CONF_EXTERNAL_CLOCK: @@ -115,15 +110,15 @@ Device::Device(shared_ptr configurable) : break; case SR_CONF_TIMEBASE: - bind_enum(name, gvar_list, get, set, print_timebase); + bind_enum(name, key, capabilities, get, set, print_timebase); break; case SR_CONF_VDIV: - bind_enum(name, gvar_list, get, set, print_vdiv); + bind_enum(name, key, capabilities, get, set, print_vdiv); break; case SR_CONF_VOLTAGE_THRESHOLD: - bind_enum(name, gvar_list, get, set, print_voltage_threshold); + bind_enum(name, key, capabilities, get, set, print_voltage_threshold); break; default: @@ -141,7 +136,8 @@ void Device::bind_bool(const QString &name, } void Device::bind_enum(const QString &name, - Glib::VariantContainerBase gvar_list, Property::Getter getter, + const ConfigKey *key, std::set capabilities, + Property::Getter getter, Property::Setter setter, function printer) { Glib::VariantBase gvar; @@ -149,7 +145,10 @@ void Device::bind_enum(const QString &name, assert(configurable_); - Glib::VariantIter iter(gvar_list); + if (!capabilities.count(Capability::LIST)) + return; + + Glib::VariantIter iter(configurable_->config_list(key)); while ((iter.next_value(gvar))) values.push_back(make_pair(gvar, printer(gvar))); diff --git a/pv/binding/device.hpp b/pv/binding/device.hpp index a8acd166..7dfe0246 100644 --- a/pv/binding/device.hpp +++ b/pv/binding/device.hpp @@ -30,9 +30,7 @@ #include -namespace sigrok { - class Configurable; -} +#include namespace pv { @@ -51,7 +49,8 @@ Q_SIGNALS: private: void bind_bool(const QString &name, prop::Property::Getter getter, prop::Property::Setter setter); - void bind_enum(const QString &name, Glib::VariantContainerBase gvar_list, + void bind_enum(const QString &name, + const sigrok::ConfigKey *key, std::set capabilities, prop::Property::Getter getter, prop::Property::Setter setter, std::function printer = print_gvariant); void bind_int(const QString &name, QString suffix, -- 2.30.2