Skip to content

Commit 14798e4

Browse files
committed
Display: Fix error when updating tool icon on the course homepage (introduced in 1.11.20 through security updates) - refs #4809
1 parent 5018a27 commit 14798e4

File tree

5 files changed

+106
-2
lines changed

5 files changed

+106
-2
lines changed

main/course_info/tools.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
$form->addHeader(get_lang('EditIcon'));
5656
$form->addHtml('<div class="col-md-7">');
5757
$form->addText('name', get_lang('Name'));
58-
$form->addText('link', get_lang('Links'));
58+
$form->addInternalUrl('link', get_lang('Links'));
5959
$allowedPictureTypes = ['jpg', 'jpeg', 'png'];
6060
$form->addFile('icon', get_lang('CustomIcon'));
6161
$form->addRule(
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
/* For licensing terms, see /license.txt */
3+
4+
/**
5+
* InternalUrl element (URL without the domain as prefix).
6+
*
7+
* Class InternalUrl
8+
*/
9+
class InternalUrl extends HTML_QuickForm_text
10+
{
11+
/**
12+
* InternalUrl constructor.
13+
*
14+
* @param string $elementName
15+
* @param string $elementLabel
16+
* @param array $attributes
17+
*/
18+
public function __construct($elementName = null, $elementLabel = null, $attributes = null)
19+
{
20+
if (!isset($attributes['id'])) {
21+
$attributes['id'] = $elementName;
22+
}
23+
24+
$attributes['type'] = 'text';
25+
$attributes['class'] = 'form-control';
26+
27+
parent::__construct($elementName, $elementLabel, $attributes);
28+
29+
$this->setType('text');
30+
}
31+
}

main/inc/lib/formvalidator/FormValidator.class.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,36 @@ public function addText($name, $label, $required = true, $attributes = [], $crea
224224
return $element;
225225
}
226226

227+
/**
228+
* Adds a text field to the form to be used as internal url (URL without the domain part).
229+
* A trim-filter is attached to the field.
230+
*
231+
* @param string|array $label The label for the form-element
232+
* @param string $name The element name
233+
* @param bool $required (optional) Is the form-element required (default=true)
234+
* @param array $attributes (optional) List of attributes for the form-element
235+
*
236+
* @return HTML_QuickForm_text
237+
*/
238+
public function addInternalUrl($name, $label, $required = true, $attributes = [], $createElement = false)
239+
{
240+
if ($createElement) {
241+
$element = $this->createElement('text', $name, $label, $attributes);
242+
} else {
243+
$element = $this->addElement('text', $name, $label, $attributes);
244+
}
245+
246+
$this->applyFilter($name, 'trim');
247+
$this->applyFilter($name, 'plain_url_filter');
248+
$this->addRule($name, get_lang('InsertAValidUrl'), 'internal_url');
249+
250+
if ($required) {
251+
$this->addRule($name, get_lang('ThisFieldIsRequired'), 'required');
252+
}
253+
254+
return $element;
255+
}
256+
227257
/**
228258
* Add hidden course params.
229259
*/
@@ -1268,6 +1298,7 @@ public function addUrl($name, $label, $required = true, $attributes = [])
12681298
{
12691299
$this->addElement('url', $name, $label, $attributes);
12701300
$this->applyFilter($name, 'trim');
1301+
12711302
$this->addRule($name, get_lang('InsertAValidUrl'), 'url');
12721303

12731304
if ($required) {
@@ -2048,3 +2079,20 @@ function mobile_phone_number_filter($mobilePhoneNumber)
20482079

20492080
return ltrim($mobilePhoneNumber, '0');
20502081
}
2082+
2083+
/**
2084+
* Cleans JS from a URL.
2085+
*
2086+
* @param string $html URL to clean
2087+
* @param int $mode (optional)
2088+
*
2089+
* @return string The cleaned URL
2090+
*/
2091+
function plain_url_filter($html, $mode = NO_HTML)
2092+
{
2093+
$allowed_tags = HTML_QuickForm_Rule_HTML::get_allowed_tags($mode);
2094+
$html = kses_no_null($html);
2095+
$html = kses_js_entities($html);
2096+
$allowed_html_fixed = kses_array_lc($allowed_tags);
2097+
return kses_split($html, $allowed_html_fixed, array('http', 'https'));
2098+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/**
4+
* Abstract base class for QuickForm validation rules.
5+
*/
6+
7+
/**
8+
* Validate internal urls (URLs without the domain).
9+
*/
10+
class HTML_QuickForm_Rule_InternalUrl extends HTML_QuickForm_Rule
11+
{
12+
/**
13+
* Validates internal url.
14+
* We cheat a little by using the adding the domain as prefix to use the domain validation process of filter_var().
15+
*
16+
* @param string $url
17+
*
18+
* @return bool returns true if valid, false otherwise
19+
*/
20+
public function validate($url, $options)
21+
{
22+
return (bool) filter_var(api_get_path(WEB_PATH).$url, FILTER_VALIDATE_URL);
23+
}
24+
}

main/inc/lib/pear/HTML/QuickForm/RuleRegistry.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ public function getRule($ruleName)
152152
'mimetype' => 'HTML_QuickForm_Rule_MimeType',
153153
'filename' => 'HTML_QuickForm_Rule_FileName',
154154
'validquestiontype' => 'HTML_QuickForm_Rule_QuestionType',
155-
'mintext' => 'Html_Quickform_Rule_MinText'
155+
'mintext' => 'Html_Quickform_Rule_MinText',
156+
'internal_url' => 'HTML_QuickForm_Rule_InternalUrl',
156157
);
157158

158159
$class = $rules[$ruleName];

0 commit comments

Comments
 (0)