From a973f7b9c410d8eb525bee1d4f8b109bdc637628 Mon Sep 17 00:00:00 2001 From: btry Date: Mon, 13 Nov 2017 18:52:37 +0100 Subject: [PATCH] fix(field): avoid html entitization of accented chars --- inc/fields/checkboxesfield.class.php | 2 - inc/fields/multiselectfield.class.php | 4 +- inc/fields/radiosfield.class.php | 2 - inc/fields/selectfield.class.php | 2 - inc/question.class.php | 13 +++++- ...xFieldTest.php => CheckboxesFieldTest.php} | 43 ++++++++++++++++++- tests/0005_Unit/MultiselectFieldTest.php | 40 +++++++++++++++++ tests/0005_Unit/RadiosFieldTest.php | 43 +++++++++++++++++++ tests/0005_Unit/SelectFieldTest.php | 40 +++++++++++++++++ 9 files changed, 178 insertions(+), 11 deletions(-) rename tests/0005_Unit/{CheckboxFieldTest.php => CheckboxesFieldTest.php} (78%) create mode 100644 tests/0005_Unit/RadiosFieldTest.php diff --git a/inc/fields/checkboxesfield.class.php b/inc/fields/checkboxesfield.class.php index 46b7bcab1..67fa0a3bf 100644 --- a/inc/fields/checkboxesfield.class.php +++ b/inc/fields/checkboxesfield.class.php @@ -109,12 +109,10 @@ public function prepareQuestionInputForSave($input) { return []; } else { $input['values'] = $this->trimValue($input['values']); - $input['values'] = addslashes($input['values']); } } if (isset($input['default_values'])) { $input['default_values'] = $this->trimValue($input['default_values']); - $input['default_values'] = addslashes($input['default_values']); } return $input; } diff --git a/inc/fields/multiselectfield.class.php b/inc/fields/multiselectfield.class.php index d0ab70ea2..70427ad38 100644 --- a/inc/fields/multiselectfield.class.php +++ b/inc/fields/multiselectfield.class.php @@ -37,7 +37,7 @@ public function displayField($canEdit = true) { } else { $answer = $this->getAnswer(); echo '
'; - echo empty($answer) ? '' : implode('
', json_decode($answer)); + echo empty($answer) ? '' : implode('
', $answer); echo '
'; } } @@ -64,7 +64,7 @@ public function getAnswer() { $return[] = $value; } } - return json_encode($return); + return $return; } public static function getName() { diff --git a/inc/fields/radiosfield.class.php b/inc/fields/radiosfield.class.php index d7891c65f..6ec758bf7 100644 --- a/inc/fields/radiosfield.class.php +++ b/inc/fields/radiosfield.class.php @@ -57,13 +57,11 @@ public function prepareQuestionInputForSave($input) { } else { // trim values $input['values'] = $this->trimValue($input['values']); - $input['values'] = addslashes($input['values']); } } if (isset($input['default_values'])) { // trim values $input['default_values'] = $this->trimValue($input['default_values']); - $input['default_values'] = addslashes($input['default_values']); } return $input; } diff --git a/inc/fields/selectfield.class.php b/inc/fields/selectfield.class.php index f7f87c457..f6cce8aee 100644 --- a/inc/fields/selectfield.class.php +++ b/inc/fields/selectfield.class.php @@ -63,13 +63,11 @@ public function prepareQuestionInputForSave($input) { } else { // trim values $input['values'] = $this->trimValue($input['values']); - $input['values'] = addslashes($input['values']); } } if (isset($input['default_values'])) { // trim values $input['default_values'] = $this->trimValue($input['default_values']); - $input['default_values'] = addslashes($input['default_values']); } return $input; } diff --git a/inc/question.class.php b/inc/question.class.php index e2a80ef07..026e2e284 100644 --- a/inc/question.class.php +++ b/inc/question.class.php @@ -352,10 +352,19 @@ public function prepareInputForUpdate($input) { } // Decode (if already encoded) and encode strings to avoid problems with quotes + // The if() {} structures here will grow until the call to plugin_formcreator_encode + // becomes obsolete foreach ($input as $key => $value) { if ($input['fieldtype'] != 'dropdown' - || $input['fieldtype'] != 'dropdown' && $key != 'values') { - $input[$key] = plugin_formcreator_encode($value); + || $input['fieldtype'] != 'dropdown' && $key != 'values' && $key != 'default_values') { + if (!($input['fieldtype'] == 'select' && ($key == 'values' || $key == 'default_values')) + && !($input['fieldtype'] == 'checkboxes' && ($key == 'values' || $key == 'default_values')) + && !($input['fieldtype'] == 'radios' && ($key == 'values' || $key == 'default_values')) + && !($input['fieldtype'] == 'multiselect' && ($key == 'values' || $key == 'default_values'))) { + $input[$key] = plugin_formcreator_encode($value); + } else { + $input[$key] = str_replace('\r\n', "\r\n", $input[$key]); + } } } diff --git a/tests/0005_Unit/CheckboxFieldTest.php b/tests/0005_Unit/CheckboxesFieldTest.php similarity index 78% rename from tests/0005_Unit/CheckboxFieldTest.php rename to tests/0005_Unit/CheckboxesFieldTest.php index 8d711643d..f6ce0dbe1 100644 --- a/tests/0005_Unit/CheckboxFieldTest.php +++ b/tests/0005_Unit/CheckboxesFieldTest.php @@ -1,5 +1,5 @@ isValid($values); $this->assertEquals($expectedValidity, $isValid); } + + public function testPrepareInputForSave() { + $fields = array( + 'fieldtype' => 'checkboxes', + 'name' => 'question', + 'required' => '0', + 'default_values' => "1\r\n2\r\n3\r\n5\r\n6", + 'values' => "1\r\n2\r\n3\r\n4\r\n5\r\n6", + 'order' => '1', + 'show_rule' => 'always', + 'range_min' => 3, + 'range_max' => 4, + ); + $fieldInstance = new PluginFormcreatorCheckboxesField($fields); + + // Test a value is mandatory + $input = [ + 'values' => "", + 'name' => 'foo', + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals(0, count($out)); + + // Test accented chars are kept + $input = [ + 'values' => "éè\r\nsomething else", + 'default_values' => "éè", + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals("éè\r\nsomething else", $out['values']); + $this->assertEquals("éè", $out['default_values']); + + // Test values are trimmed + $input = [ + 'values' => ' something \r\n something else ', + 'default_values' => " something ", + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals('something\r\nsomething else', $out['values']); + $this->assertEquals("something", $out['default_values']); + } } \ No newline at end of file diff --git a/tests/0005_Unit/MultiselectFieldTest.php b/tests/0005_Unit/MultiselectFieldTest.php index 2ab0b077a..ea9c6a964 100644 --- a/tests/0005_Unit/MultiselectFieldTest.php +++ b/tests/0005_Unit/MultiselectFieldTest.php @@ -130,4 +130,44 @@ public function testFieldIsValid($fields, $data, $expectedValue, $expectedValidi $this->assertEquals($expectedValidity, $isValid); } + public function testPrepareInputForSave() { + $fields = array( + 'fieldtype' => 'multiselect', + 'name' => 'question', + 'required' => '0', + 'default_values' => "1\r\n2\r\n3\r\n5\r\n6", + 'values' => "1\r\n2\r\n3\r\n4\r\n5\r\n6", + 'order' => '1', + 'show_rule' => 'always', + 'range_min' => 3, + 'range_max' => 4, + ); + $fieldInstance = new PluginFormcreatorMultiselectField($fields); + + // Test a value is mandatory + $input = [ + 'values' => "", + 'name' => 'foo', + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals(0, count($out)); + + // Test accented chars are kept + $input = [ + 'values' => "éè\r\nsomething else", + 'default_values' => "éè", + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals("éè\r\nsomething else", $out['values']); + $this->assertEquals("éè", $out['default_values']); + + // Test values are trimmed + $input = [ + 'values' => ' something \r\n something else ', + 'default_values' => " something ", + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals('something\r\nsomething else', $out['values']); + $this->assertEquals("something", $out['default_values']); + } } \ No newline at end of file diff --git a/tests/0005_Unit/RadiosFieldTest.php b/tests/0005_Unit/RadiosFieldTest.php new file mode 100644 index 000000000..9c51db0f5 --- /dev/null +++ b/tests/0005_Unit/RadiosFieldTest.php @@ -0,0 +1,43 @@ + 'radios', + 'name' => 'question', + 'required' => '0', + 'default_values' => "1\r\n2\r\n3\r\n5\r\n6", + 'values' => "1\r\n2\r\n3\r\n4\r\n5\r\n6", + 'order' => '1', + 'show_rule' => 'always', + 'range_min' => 3, + 'range_max' => 4, + ); + $fieldInstance = new PluginFormcreatorRadiosField($fields); + + // Test a value is mandatory + $input = [ + 'values' => "", + 'name' => 'foo', + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals(0, count($out)); + + // Test accented chars are kept + $input = [ + 'values' => "éè\r\nsomething else", + 'default_values' => "éè", + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals("éè\r\nsomething else", $out['values']); + $this->assertEquals("éè", $out['default_values']); + + // Test values are trimmed + $input = [ + 'values' => ' something \r\n something else ', + 'default_values' => " something ", + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals('something\r\nsomething else', $out['values']); + $this->assertEquals("something", $out['default_values']); + } +} \ No newline at end of file diff --git a/tests/0005_Unit/SelectFieldTest.php b/tests/0005_Unit/SelectFieldTest.php index 2eff97e69..17dee9d40 100644 --- a/tests/0005_Unit/SelectFieldTest.php +++ b/tests/0005_Unit/SelectFieldTest.php @@ -120,4 +120,44 @@ public function testFieldIsValid($fields, $data, $expectedValue, $expectedValidi $this->assertEquals($expectedValidity, $isValid); } + public function testPrepareInputForSave() { + $fields = array( + 'fieldtype' => 'select', + 'name' => 'question', + 'required' => '0', + 'default_values' => "1\r\n2\r\n3\r\n5\r\n6", + 'values' => "1\r\n2\r\n3\r\n4\r\n5\r\n6", + 'order' => '1', + 'show_rule' => 'always', + 'range_min' => 3, + 'range_max' => 4, + ); + $fieldInstance = new PluginFormcreatorSelectField($fields); + + // Test a value is mandatory + $input = [ + 'values' => "", + 'name' => 'foo', + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals(0, count($out)); + + // Test accented chars are kept + $input = [ + 'values' => "éè\r\nsomething else", + 'default_values' => "éè", + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals("éè\r\nsomething else", $out['values']); + $this->assertEquals("éè", $out['default_values']); + + // Test values are trimmed + $input = [ + 'values' => ' something \r\n something else ', + 'default_values' => " something ", + ]; + $out = $fieldInstance->prepareQuestionInputForSave($input); + $this->assertEquals('something\r\nsomething else', $out['values']); + $this->assertEquals("something", $out['default_values']); + } } \ No newline at end of file