From acec2559a5da3390dcf2728eb37e69ecedf33267 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Sun, 7 Feb 2010 14:08:54 +0200 Subject: [PATCH] C++: Make proxies safer If a user happens to store an ElementProxy or a PropertyProxy instance, we need to take a reference to the JSON value they point to. With PropertyProxy, the key needs to be copied as well. --- src/jansson.hpp | 12 +++++++----- src/jansson.ipp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/jansson.hpp b/src/jansson.hpp index bf723bd..ad6d177 100644 --- a/src/jansson.hpp +++ b/src/jansson.hpp @@ -166,8 +166,9 @@ namespace json { // proxies an array element class ElementProxy { public: - // constructor - ElementProxy(json_t* array, unsigned int index) : _array(array), _index(index) {} + ElementProxy(json_t* array, unsigned int index); + ElementProxy(const ElementProxy& other); + ~ElementProxy(); // assign to the proxied element inline ElementProxy& operator=(const Value& value); @@ -186,8 +187,9 @@ namespace json { // proxies an object property class PropertyProxy { public: - // constructor - PropertyProxy(json_t* array, const char* key) : _object(array), _key(key) {} + PropertyProxy(json_t* object, const char *key); + PropertyProxy(const PropertyProxy& other); + ~PropertyProxy(); // assign to the proxied element inline PropertyProxy& operator=(const Value& value); @@ -200,7 +202,7 @@ namespace json { json_t* _object; // key of property - const char* _key; + char* _key; }; } // namespace json::detail diff --git a/src/jansson.ipp b/src/jansson.ipp index 5938f0f..fd3a1bf 100644 --- a/src/jansson.ipp +++ b/src/jansson.ipp @@ -8,6 +8,8 @@ #error "jansson.ipp may only be included from jansson.hpp" #endif +#include + namespace json { namespace detail { // assignment operator @@ -310,6 +312,20 @@ namespace json { return v; } + ElementProxy::ElementProxy(json_t* array, unsigned int index) + : _array(array), _index(index) { + json_incref(_array); + } + + ElementProxy::ElementProxy(const ElementProxy& other) + : _array(other._array), _index(other._index) { + json_incref(_array); + } + + ElementProxy::~ElementProxy() { + json_decref(_array); + } + // assign value to proxied array element ElementProxy& ElementProxy::operator=(const Value& value) { json_array_set(_array, _index, value.as_json()); @@ -321,6 +337,23 @@ namespace json { return json_array_get(_array, _index); } + PropertyProxy::PropertyProxy(json_t* object, const char* key) + : _object(object) { + _key = strdup(key); + json_incref(_object); + } + + PropertyProxy::PropertyProxy(const PropertyProxy& other) + : _object(other._object) { + _key = strdup(other._key); + json_incref(_object); + } + + PropertyProxy::~PropertyProxy() { + free(_key); + json_decref(_object); + } + // assign value to proxied object property PropertyProxy& PropertyProxy::operator=(const Value& value) { json_object_set(_object, _key, value.as_json()); -- 2.1.4