1
0
mirror of https://github.com/e107inc/e107.git synced 2025-08-10 00:27:45 +02:00

Fix implementation of e_front_model::sanitize()

Handles recursive data field validation now
This commit is contained in:
Nick Liu
2021-04-17 02:57:10 -05:00
parent ce7f3b5d56
commit dc3ac65a70
2 changed files with 62 additions and 59 deletions

View File

@@ -2706,7 +2706,7 @@ class e_front_model extends e_model
* If $value is null, it'll be retrieved from object posted data * If $value is null, it'll be retrieved from object posted data
* If $key is an array, $value is omitted. * If $key is an array, $value is omitted.
* *
* NOTE: If $key is not found in object's _data_fields array, null is returned * NOTE: If $key is not found in object's _data_fields array, it is removed
* *
* @param mixed $key string key name or array data to be sanitized * @param mixed $key string key name or array data to be sanitized
* @param mixed $value * @param mixed $value
@@ -2714,56 +2714,12 @@ class e_front_model extends e_model
*/ */
public function sanitize($key, $value = null) public function sanitize($key, $value = null)
{ {
$tp = e107::getParser();
if(is_array($key)) if(is_array($key))
{ {
$ret = []; $expectedFields = e107::getParser()->fromFlatArray($this->_data_fields);
return $this->sanitizeRecursive($key, $expectedFields);
foreach($this->_data_fields as $fld => $type)
{
list($field) = explode("/", $fld); // ie the field being posted as an array.
if(!isset($key[$field]))
{
continue;
}
if(strpos($fld, '/') !== false) // multi-dimensional array field key name.
{
$md = explode('/', $fld); // split the field name
$value = $key[$field];
foreach($md as $f) // loop through the path (depth/of/array) to check $value[x][y][z] etc.
{
if(isset($value[$f]))
{
if(is_array($value[$f]))
{
$value = $value[$f];
}
else // the actual field being saved. .
{
// FIXME add the sanitized value into the end of the array.
$sanitized = $this->sanitizeValue($type, $value[$f], $fld);
$ret[$field] = $key[$field];
}
}
}
}
else // regular field.
{
$ret[$field] = $this->sanitize($field, $key[$field]);
}
}
return $ret;
} }
if(!isset($this->_data_fields[$key])) if(!isset($this->_data_fields[$key]))
{ {
return null; return null;
@@ -2774,12 +2730,36 @@ class e_front_model extends e_model
$value = $this->getPostedData($key); $value = $this->getPostedData($key);
} }
return $this->sanitizeValue($type, $value, $key); return $this->sanitizeValue($type, $value, $key);
} }
/**
* @param array $data
* @param array $fields
* @return array
*/
private function sanitizeRecursive($data, $fields)
{
foreach ($data as $fieldKey => $value)
{
if (!array_key_exists($fieldKey, $fields))
{
unset($data[$fieldKey]);
continue;
}
$expectedType = $fields[$fieldKey];
if (is_array($value) && is_array($expectedType))
{
$data[$fieldKey] = $this->sanitizeRecursive($value, $fields[$fieldKey]);
}
else
{
$data[$fieldKey] = $this->sanitizeValue($expectedType, $value, $fieldKey);
}
}
return $data;
}
public function destroy() public function destroy()
{ {

View File

@@ -126,7 +126,6 @@
array ( array (
'active' => '0', 'active' => '0',
'title' => 'PayPal Express' , 'title' => 'PayPal Express' ,
'icon' => 'fa-paypal',
) )
), ),
'other' => array( 'other' => array(
@@ -144,9 +143,8 @@
array ( array (
'paypal' => 'paypal' =>
array ( array (
'active' => 1, // converted to int. 'active' => 0, // converted to int.
'title' => 'PayPal Express', 'title' => 'PayPal Express',
// icon removed - as not valid.
), ),
), ),
'other' => 'other' =>
@@ -162,16 +160,41 @@
), ),
); );
// @todo FIXME - doesn't pass. More accurate check has been made, but not injected into the array yet.
$result = $this->model->sanitize($posted); $result = $this->model->sanitize($posted);
// $this->assertSame($expected, $result); $this->assertSame($expected, $result);
$this->assertNotSame($result, $posted);
} }
public function testSanitizeNoUnexpectedFields()
{
$dataFields = [
'expected' => 'bool',
'nested/expected' => 'int',
];
public function testCustomFieldsSantizie() $input = [
'expected' => '5',
'unexpected' => 'SHOULD_BE_REMOVED',
'nested' => [
'expected' => "7331",
'unexpected' => 'SHOULD BE REMOVED',
]
];
$expected = [
'expected' => true,
'nested' => [
'expected' => 7331
]
];
$this->model->setDataFields($dataFields);
$result = $this->model->sanitize($input);
$this->assertSame($expected, $result);
}
public function testCustomFieldsSanitize()
{ {
$dataFields = array ( 'chapter_id' => 'int', 'chapter_icon' => 'str', 'chapter_parent' => 'str', 'chapter_name' => 'str', 'chapter_template' => 'str', 'chapter_meta_description' => 'str', 'chapter_meta_keywords' => 'str', 'chapter_sef' => 'str', 'chapter_manager' => 'int', 'chapter_order' => 'str', 'chapter_visibility' => 'int', 'chapter_fields' => 'json', 'chapter_image' => 'str', ); $dataFields = array ( 'chapter_id' => 'int', 'chapter_icon' => 'str', 'chapter_parent' => 'str', 'chapter_name' => 'str', 'chapter_template' => 'str', 'chapter_meta_description' => 'str', 'chapter_meta_keywords' => 'str', 'chapter_sef' => 'str', 'chapter_manager' => 'int', 'chapter_order' => 'str', 'chapter_visibility' => 'int', 'chapter_fields' => 'json', 'chapter_image' => 'str', );
$this->model->setDataFields($dataFields); $this->model->setDataFields($dataFields);
@@ -188,6 +211,7 @@
'chapter_manager' => 254, 'chapter_manager' => 254,
'chapter_order' => '0', 'chapter_order' => '0',
'chapter_visibility' => 0, 'chapter_visibility' => 0,
'chapter_image' => '',
'chapter_fields' => '{ 'chapter_fields' => '{
"__tabs__": { "__tabs__": {
"additional": "Custom Fields 10" "additional": "Custom Fields 10"
@@ -295,7 +319,6 @@
"help": "" "help": ""
} }
}', }',
'chapter_image' => '',
); );
$result = $this->model->sanitize($posted); $result = $this->model->sanitize($posted);
$this->assertSame($expected, $result); $this->assertSame($expected, $result);