From e5f6bd697999ba113877d0530dc0b822a85d8412 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 11 Feb 2018 16:39:21 -0600 Subject: [PATCH] Update: always return and assign a copy of objects by default, but provide a trait to use references The default behavior is to favor security and separation between different objects. Everytime an object is assigned or returned via a c_base_return class type, use a copy (clone) of that object. This is good practice for security and data integrity. In the event that a reference is needed (generally a good practice for performance and resource reasons), a trait is provided. This trait must be manually assigned to each class. This functionality must use distinct functions for assigning and retreiving the references to guarantee consistency in design and avoidance of accidents. It is very important to note that this design can cause performance issues if this particular design is not understood. This previous designs intended this behavior, but was not consistent. This behavior should now be more consistent. --- common/base/classes/base_return.php | 76 ++++++++++++++++++++++++++++++++++- common/theme/classes/theme_dom.php | 56 ++++++++++++++++++++------ common/theme/classes/theme_markup.php | 13 +++--- 3 files changed, 125 insertions(+), 20 deletions(-) diff --git a/common/base/classes/base_return.php b/common/base/classes/base_return.php index 4801c93..e67c008 100644 --- a/common/base/classes/base_return.php +++ b/common/base/classes/base_return.php @@ -37,6 +37,8 @@ trait t_base_return_value { /** * Assign the value. * + * If the value is an object, then this should create a copy of the object (a clone). + * * @param $value * This can be anything that is to be considered a return value. * @@ -44,7 +46,13 @@ trait t_base_return_value { * TRUE on success, FALSE otherwise. */ public function set_value($value) { - $this->value = $value; + if (is_object($value)) { + $this->value = clone($value); + } + else { + $this->value = $value; + } + return TRUE; } @@ -232,6 +240,68 @@ trait t_base_return_message { } /** + * A trait for a return value that may be assigned an object via reference. + */ +trait t_base_return_reference_set { + /** + * Assign the value, using reference instead of a copy. + * + * If the value is an object, then this should contain a reference to the object. + * + * @param $value + * This can be anything that is to be considered a return value. + * + * @return bool + * TRUE on success, FALSE otherwise. + * FALSE is returned when $value is not an object. + */ + public function set_value_reference($value) { + if (is_object($value)) { + $this->value = $value; + return TRUE; + } + + return FALSE; + } +} + +/** + * A trait for a return value that may return an object via reference. + */ +trait t_base_return_reference_get { + + /** + * Return the value, by reference. + * + * @return null|object $value + * A reference to the value within this class. + * NULL is returned if no reference can be returned. + */ + public function get_value_reference() { + if (is_object($this->value)) { + return $this->value; + } + + return NULL; + } +} + +/** + * A trait for a return value that may return an object via reference of the expected type. + */ +trait t_base_return_reference_get_exact { + + /** + * Return the value, by reference, of the expected type. + * + * @return object $value + * A reference to the value within this class. + * A new object is created and returned if a reference would otherwise be unreturnable. + */ + public abstract function get_value_reference_exact(); +} + +/** * A generic class for managing return values. * * This is the base template class used for specific return classes. @@ -1581,6 +1651,7 @@ class c_base_return_array extends c_base_return_value { * All specific object types should extend this class so that instanceof tests against c_base_return_object are always accurate. */ class c_base_return_object extends c_base_return_value { + /** * @see: t_base_return_value::p_s_new() */ @@ -1640,6 +1711,7 @@ class c_base_return_object extends c_base_return_value { * All specific resource types should extend this class so that instanceof tests against c_base_return_resource are always accurate. */ class c_base_return_resource extends c_base_return_value { + /** * @see: t_base_return_value::p_s_new() */ @@ -1693,6 +1765,7 @@ class c_base_return_resource extends c_base_return_value { * A return class whose value is represented as a stream resource. */ class c_base_return_resource_stream extends c_base_return_resource { + /** * @see: t_base_return_value::p_s_new() */ @@ -1746,6 +1819,7 @@ class c_base_return_resource_stream extends c_base_return_resource { * A return class whose value is represented as a socket resource. */ class c_base_return_resource_socket extends c_base_return_resource { + /** * @see: t_base_return_value::p_s_new() */ diff --git a/common/theme/classes/theme_dom.php b/common/theme/classes/theme_dom.php index 9d0c386..2f51819 100644 --- a/common/theme/classes/theme_dom.php +++ b/common/theme/classes/theme_dom.php @@ -470,7 +470,7 @@ class c_theme_return_c_theme_dom extends c_base_return_value { return NULL; } - return $this->value; + return clone($this->value); } /** @@ -484,7 +484,7 @@ class c_theme_return_c_theme_dom extends c_base_return_value { return new c_theme_dom(); } - return $this->value; + return clone($this->value); } } @@ -533,7 +533,7 @@ class c_theme_return_dom_node extends c_base_return_value { return FALSE; } - $this->value = $value; + $this->value = clone($value); return TRUE; } @@ -548,7 +548,7 @@ class c_theme_return_dom_node extends c_base_return_value { return NULL; } - return $this->value; + return clone($this->value); } /** @@ -562,8 +562,40 @@ class c_theme_return_dom_node extends c_base_return_value { return new DOMNode(); } + return clone($this->value); + } + + /** + * Return the value. + * + * This returns a reference instead of a copy. + * + * @return string|null $value + * The value array stored within this class. + */ + public function get_value_reference() { + if (!is_null($this->value) && !($this->value instanceof DOMNode)) { + return NULL; + } + return $this->value; } + + /** + * Return the value of the expected type. + * + * This returns a reference instead of a copy. + * + * @return DOMNode $value + * The value DOMNode stored within this class. + */ + public function get_value_reference_exact() { + if (!($this->value instanceof DOMNode)) { + return new DOMNode(); + } + + return clone($this->value); + } } /** @@ -611,7 +643,7 @@ class c_theme_return_dom_comment extends c_base_return_value { return FALSE; } - $this->value = $value; + $this->value = clone($value); return TRUE; } @@ -626,7 +658,7 @@ class c_theme_return_dom_comment extends c_base_return_value { return NULL; } - return $this->value; + return clone($this->value); } /** @@ -640,7 +672,7 @@ class c_theme_return_dom_comment extends c_base_return_value { return new DOMComment(); } - return $this->value; + return clone($this->value); } } @@ -689,7 +721,7 @@ class c_theme_return_dom_element extends c_base_return_value { return FALSE; } - $this->value = $value; + $this->value = clone($value); return TRUE; } @@ -704,7 +736,7 @@ class c_theme_return_dom_element extends c_base_return_value { return NULL; } - return $this->value; + return clone($this->value); } /** @@ -767,7 +799,7 @@ class c_theme_return_dom_text extends c_base_return_value { return FALSE; } - $this->value = $value; + $this->value = clone($value); return TRUE; } @@ -782,7 +814,7 @@ class c_theme_return_dom_text extends c_base_return_value { return NULL; } - return $this->value; + return clone($this->value); } /** @@ -796,6 +828,6 @@ class c_theme_return_dom_text extends c_base_return_value { return new DOMText(); } - return $this->value; + return clone($this->value); } } diff --git a/common/theme/classes/theme_markup.php b/common/theme/classes/theme_markup.php index 673b922..f82c408 100644 --- a/common/theme/classes/theme_markup.php +++ b/common/theme/classes/theme_markup.php @@ -1541,7 +1541,7 @@ class c_theme_return_tag extends c_base_return_value { return FALSE; } - $this->value = $value; + $this->value = clone($value); return TRUE; } @@ -1556,7 +1556,7 @@ class c_theme_return_tag extends c_base_return_value { $this->value = NULL; } - return $this->value; + return clone($this->value); } /** @@ -1570,7 +1570,7 @@ class c_theme_return_tag extends c_base_return_value { $this->value = new c_theme_tag(); } - return $this->value; + return clone($this->value); } } @@ -1907,7 +1907,6 @@ class c_theme_markup { */ class c_theme_return_markup extends c_base_return_value { use t_base_return_value_exact; - /** * @see: t_base_return_value::p_s_new() */ @@ -1944,7 +1943,7 @@ class c_theme_return_markup extends c_base_return_value { return FALSE; } - $this->value = $value; + $this->value = clone($value); return TRUE; } @@ -1959,7 +1958,7 @@ class c_theme_return_markup extends c_base_return_value { $this->value = NULL; } - return $this->value; + return clone($this->value); } /** @@ -1973,6 +1972,6 @@ class c_theme_return_markup extends c_base_return_value { $this->value = new c_theme_tag(); } - return $this->value; + return clone($this->value); } } -- 1.8.3.1