Skip to content

Commit ca0eb4e

Browse files
committed
fix(floatfield,integerfield,textfield): fix escaping in regex
Signed-off-by: Thierry Bugier <tbugier@teclib.com>
1 parent e3ae8f3 commit ca0eb4e

File tree

7 files changed

+114
-24
lines changed

7 files changed

+114
-24
lines changed

inc/field.class.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,19 @@ public final function deleteParameters(PluginFormcreatorQuestion $question) {
210210
public function getQuestionId() {
211211
return $this->fields['id'];
212212
}
213+
214+
/**
215+
* Validate a regular expression
216+
*
217+
* @param string $regex
218+
* @return boolean true if the regex is valid, false otherwise
219+
*/
220+
protected function checkRegex($regex) {
221+
// Avoid php notice when validating the regular expression
222+
set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) {});
223+
$isValid = !(preg_match($regex, null) === false);
224+
restore_error_handler();
225+
226+
return $isValid;
227+
}
213228
}

inc/fields/floatfield.class.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ public function isValid() {
103103
}
104104

105105
private function isValidValue($value) {
106+
if (strlen($value) == 0) {
107+
return true;
108+
}
109+
106110
if (!empty($value) && !is_numeric($value)) {
107111
Session::addMessageAfterRedirect(__('This is not a number:', 'formcreator') . ' ' . $this->fields['name'], false, ERROR);
108112
return false;
@@ -150,14 +154,10 @@ public function prepareQuestionInputForSave($input) {
150154
$fieldType = $this->getFieldTypeName();
151155
// Add leading and trailing regex marker automaticaly
152156
if (isset($input['_parameters'][$fieldType]['regex']['regex']) && !empty($input['_parameters'][$fieldType]['regex']['regex'])) {
153-
// Avoid php notice when validating the regular expression
154-
set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) {});
155-
$isValid = !(preg_match($input['_parameters'][$fieldType]['regex']['regex'], null) === false);
156-
restore_error_handler();
157-
158-
if (!$isValid) {
157+
$regex = Toolbox::stripslashes_deep($input['_parameters'][$fieldType]['regex']['regex']);
158+
$success = $this->checkRegex($regex);
159+
if (!$success) {
159160
Session::addMessageAfterRedirect(__('The regular expression is invalid', 'formcreator'), false, ERROR);
160-
$success = false;
161161
}
162162
}
163163
if (!$success) {

inc/fields/integerfield.class.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ public function isValid() {
104104
}
105105

106106
public function isValidValue($value) {
107+
if (strlen($value) == 0) {
108+
return true;
109+
}
110+
107111
if (!empty($value) && !ctype_digit($value)) {
108112
Session::addMessageAfterRedirect(__('This is not an integer:', 'formcreator') . ' ' . $this->fields['name'], false, ERROR);
109113
return false;
@@ -151,14 +155,10 @@ public function prepareQuestionInputForSave($input) {
151155
$fieldType = $this->getFieldTypeName();
152156
// Add leading and trailing regex marker automaticaly
153157
if (isset($input['_parameters'][$fieldType]['regex']['regex']) && !empty($input['_parameters'][$fieldType]['regex']['regex'])) {
154-
// Avoid php notice when validating the regular expression
155-
set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) {});
156-
$isValid = !(preg_match($input['_parameters'][$fieldType]['regex']['regex'], null) === false);
157-
restore_error_handler();
158-
159-
if (!$isValid) {
158+
$regex = Toolbox::stripslashes_deep($input['_parameters'][$fieldType]['regex']['regex']);
159+
$success = $this->checkRegex($regex);
160+
if (!$success) {
160161
Session::addMessageAfterRedirect(__('The regular expression is invalid', 'formcreator'), false, ERROR);
161-
$success = false;
162162
}
163163
}
164164
if (!$success) {

inc/fields/textfield.class.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ public function isValid() {
105105
}
106106

107107
private function isValidValue($value) {
108+
if (strlen($value) == 0) {
109+
return true;
110+
}
111+
108112
$parameters = $this->getParameters();
109113

110114
// Check the field matches the format regex
@@ -141,14 +145,10 @@ public function prepareQuestionInputForSave($input) {
141145
$fieldType = $this->getFieldTypeName();
142146
// Add leading and trailing regex marker automaticaly
143147
if (isset($input['_parameters'][$fieldType]['regex']['regex']) && !empty($input['_parameters'][$fieldType]['regex']['regex'])) {
144-
// Avoid php notice when validating the regular expression
145-
set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) {});
146-
$isValid = !(preg_match($input['_parameters'][$fieldType]['regex']['regex'], null) === false);
147-
restore_error_handler();
148-
149-
if (!$isValid) {
148+
$regex = Toolbox::stripslashes_deep($input['_parameters'][$fieldType]['regex']['regex']);
149+
$success = $this->checkRegex($regex);
150+
if (!$success) {
150151
Session::addMessageAfterRedirect(__('The regular expression is invalid', 'formcreator'), false, ERROR);
151-
$success = false;
152152
}
153153
}
154154
if (!$success) {

tests/suite-unit/PluginFormcreatorFloatField.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,30 @@ public function provider() {
157157
'expectedValue' => '3.141592',
158158
'expectedIsValid' => true
159159
],
160+
[
161+
'fields' => [
162+
'fieldtype' => 'float',
163+
'name' => 'question',
164+
'required' => '0',
165+
'default_values' => "",
166+
'order' => '1',
167+
'show_rule' => 'always',
168+
'show_empty' => '0',
169+
'values' => '',
170+
'_parameters' => [
171+
'float' => [
172+
'range' => [
173+
'range_min' => '',
174+
'range_max' => '',
175+
],
176+
'regex' => ['regex' => '/[0-9]{2}\\\\.[0-9]{3}\\\\.[0-9]{3}\\\\/[0-9]{4}-[0-9]{2}/'],
177+
]
178+
]
179+
],
180+
'data' => null,
181+
'expectedValue' => '',
182+
'expectedIsValid' => true
183+
],
160184
];
161185

162186
return $dataset;

tests/suite-unit/PluginFormcreatorIntegerField.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,30 @@ public function provider() {
181181
'expectedValue' => '4',
182182
'expectedIsValid' => true
183183
],
184+
[
185+
'fields' => [
186+
'fieldtype' => 'integer',
187+
'name' => 'question',
188+
'required' => '0',
189+
'default_values' => '',
190+
'order' => '1',
191+
'show_rule' => 'always',
192+
'show_empty' => '0',
193+
'values' => '',
194+
'_parameters' => [
195+
'integer' => [
196+
'range' => [
197+
'range_min' => '',
198+
'range_max' => '',
199+
],
200+
'regex' => ['regex' => '/[0-9]{2}\\\\.[0-9]{3}\\\\.[0-9]{3}\\\\/[0-9]{4}-[0-9]{2}/'],
201+
]
202+
],
203+
],
204+
'data' => null,
205+
'expectedValue' => '4',
206+
'expectedIsValid' => true
207+
],
184208
];
185209

186210
return $dataset;

tests/suite-unit/PluginFormcreatorTextField.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,32 @@ public function provider() {
166166
'expectedValue' => '1',
167167
'expectedIsValid' => false
168168
],
169+
'regex with escaped chars' => [
170+
'fields' => [
171+
'fieldtype' => 'text',
172+
'name' => 'question',
173+
'required' => '0',
174+
'show_empty' => '0',
175+
'default_values' => '',
176+
'values' => "",
177+
'order' => '1',
178+
'show_rule' => 'good',
179+
'_parameters' => [
180+
'text' => [
181+
'range' => [
182+
'range_min' => '',
183+
'range_max' => '',
184+
],
185+
'regex' => [
186+
'regex' => '/[0-9]{2}\\\\.[0-9]{3}\\\\.[0-9]{3}\\\\/[0-9]{4}-[0-9]{2}/'
187+
]
188+
]
189+
],
190+
],
191+
'data' => null,
192+
'expectedValue' => '',
193+
'expectedIsValid' => true
194+
],
169195
];
170196
return $dataset;
171197
}
@@ -181,10 +207,11 @@ public function testFieldIsValid($fields, $data, $expectedValue, $expectedValidi
181207
$question->add($fields);
182208
$question->updateParameters($fields);
183209

184-
$fieldInstance = new \PluginFormcreatorTextField($question->fields, $data);
210+
$instance = new \PluginFormcreatorTextField($question->fields, $data);
211+
$instance->deserializeValue($fields['default_values']);
185212

186-
$isValid = $fieldInstance->isValid($fields['default_values']);
187-
$this->boolean($isValid)->isEqualTo($expectedValidity, json_encode($_SESSION['MESSAGE_AFTER_REDIRECT'], JSON_PRETTY_PRINT));
213+
$isValid = $instance->isValid();
214+
$this->boolean((boolean) $isValid)->isEqualTo($expectedValidity);
188215
}
189216

190217
public function testGetEmptyParameters() {

0 commit comments

Comments
 (0)