From 4e875be0dd781336edd532aec08e867ec8af5d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20Aceda=C5=84ski?= Date: Sat, 25 Feb 2017 14:59:34 +0100 Subject: [PATCH] Added SGStringValueMethods property implementation This is to be used in places where SGRawValueMethods returning .c_str() from local strings were used, causing use-after-free later. --- simgear/props/props.hxx | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/simgear/props/props.hxx b/simgear/props/props.hxx index 84552a32..620928b5 100644 --- a/simgear/props/props.hxx +++ b/simgear/props/props.hxx @@ -602,6 +602,45 @@ private: }; +/** + * A string value managed through an object and access methods. + * + * This class stores the std::string returned by the getter, so that + * the value returned by c_str() is still valid. + * + * A read-only value will not have a setter; a write-only value will + * not have a getter. + */ +template +class SGStringValueMethods : public SGRawValue +{ +public: + typedef std::string (C::*getter_t)() const; + typedef void (C::*setter_t)(const std::string&); + SGStringValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0) + : _obj(obj), _getter(getter), _setter(setter) {} + virtual ~SGStringValueMethods () {} + virtual const char* getValue () const { + SGStringValueMethods* pthis = const_cast(this); + if (_getter) { pthis->_value = (_obj.*_getter)(); + return pthis->_value.c_str(); } + else { return SGRawValue::DefaultValue(); } + } + virtual bool setValue (const char* value) { + if (_setter) { (_obj.*_setter)(value ? value : ""); return true; } + else return false; + } + virtual SGRaw* clone () const { + return new SGStringValueMethods(_obj, _getter, _setter); + } +private: + C &_obj; + getter_t _getter; + setter_t _setter; + std::string _value; +}; + + /** * An indexed value managed through an object and access methods. *