mirror of
https://github.com/moodle/moodle.git
synced 2025-01-31 04:33:13 +01:00
Merge branch 'w23_MDL-33007_m23_buggyiconv' of git://github.com/skodak/moodle
This commit is contained in:
commit
a301675101
@ -44,11 +44,6 @@ if (!function_exists('iconv')) {
|
||||
echo 'Moodle requires the iconv PHP extension. Please install or enable the iconv extension.';
|
||||
die();
|
||||
}
|
||||
if (iconv('UTF-8', 'UTF-8//IGNORE', 'abc') !== 'abc') {
|
||||
// known to be broken in mid-2011 MAMP installations
|
||||
echo 'Broken iconv PHP extension detected, installation/upgrade can not continue.';
|
||||
die();
|
||||
}
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
@ -434,6 +429,8 @@ $availableupdates = $updateschecker->get_update_info('core',
|
||||
array('minmaturity' => $CFG->updateminmaturity, 'notifybuilds' => $CFG->updatenotifybuilds));
|
||||
$availableupdatesfetch = $updateschecker->get_last_timefetched();
|
||||
|
||||
$buggyiconvnomb = (!function_exists('mb_convert_encoding') and @iconv('UTF-8', 'UTF-8//IGNORE', '100'.chr(130).'€') !== '100€');
|
||||
|
||||
admin_externalpage_setup('adminnotifications');
|
||||
|
||||
if ($fetchupdates) {
|
||||
@ -444,4 +441,4 @@ if ($fetchupdates) {
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
|
||||
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch);
|
||||
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb);
|
||||
|
@ -242,13 +242,14 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
* @param bool $cronoverdue warn cron not running
|
||||
* @param bool $dbproblems warn db has problems
|
||||
* @param bool $maintenancemode warn in maintenance mode
|
||||
* @param bool $buggyiconvnomb warn iconv problems
|
||||
* @param array|null $availableupdates array of available_update_info objects or null
|
||||
* @param int|null $availableupdatesfetch timestamp of the most recent updates fetch or null (unknown)
|
||||
*
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
|
||||
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch) {
|
||||
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb) {
|
||||
global $CFG;
|
||||
$output = '';
|
||||
|
||||
@ -257,6 +258,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$output .= empty($CFG->disableupdatenotifications) ? $this->available_updates($availableupdates, $availableupdatesfetch) : '';
|
||||
$output .= $this->insecure_dataroot_warning($insecuredataroot);
|
||||
$output .= $this->display_errors_warning($errorsdisplayed);
|
||||
$output .= $this->buggy_iconv_warning($buggyiconvnomb);
|
||||
$output .= $this->cron_overdue_warning($cronoverdue);
|
||||
$output .= $this->db_problems($dbproblems);
|
||||
$output .= $this->maintenance_mode_warning($maintenancemode);
|
||||
@ -381,6 +383,19 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return $this->warning(get_string('displayerrorswarning', 'admin'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an appropriate message if iconv is buggy and mbstring missing.
|
||||
* @param bool $buggyiconvnomb
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function buggy_iconv_warning($buggyiconvnomb) {
|
||||
if (!$buggyiconvnomb) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->warning(get_string('warningiconvbuggy', 'admin'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an appropriate message if cron has not been run recently.
|
||||
* @param bool $cronoverdue
|
||||
|
@ -73,11 +73,6 @@ if (!function_exists('iconv')) {
|
||||
echo 'Moodle requires the iconv PHP extension. Please install or enable the iconv extension.';
|
||||
die();
|
||||
}
|
||||
if (iconv('UTF-8', 'UTF-8//IGNORE', 'abc') !== 'abc') {
|
||||
// known to be broken in mid-2011 MAMP installations
|
||||
echo 'Broken iconv PHP extension detected, installation can not continue.';
|
||||
die;
|
||||
}
|
||||
|
||||
if (PHP_INT_SIZE > 4) {
|
||||
// most probably 64bit PHP - we need a lot more memory
|
||||
|
@ -1031,6 +1031,7 @@ $string['usetags'] = 'Enable tags functionality';
|
||||
$string['validateerror'] = 'This value was not valid:';
|
||||
$string['verifychangedemail'] = 'Restrict domains when changing email';
|
||||
$string['warningcurrentsetting'] = 'Invalid current value: {$a}';
|
||||
$string['warningiconvbuggy'] = 'Your version of the iconv library does not support the //IGNORE modifier. You should install the mbstring extension which can be used instead for cleaning strings containing invalid UTF-8 characters.';
|
||||
$string['webproxy'] = 'Web proxy';
|
||||
$string['webproxyinfo'] = 'Fill in following options if your Moodle server can not access internet directly. Internet access is required for download of environment data, language packs, RSS feeds, timezones, etc.<br /><em>PHP cURL extension is highly recommended.</em>';
|
||||
$string['xmlrpcrecommended'] = 'The xmlrpc extension is needed for hub communication, and useful for web services and Moodle networking';
|
||||
|
@ -36,13 +36,18 @@
|
||||
* @return mixed
|
||||
*/
|
||||
function min_optional_param($name, $default, $type) {
|
||||
$value = $default;
|
||||
if (isset($_GET[$name])) {
|
||||
$value = $_GET[$name];
|
||||
|
||||
} else if (isset($_GET['amp;'.$name])) {
|
||||
// very, very, very ugly hack, unfortunately $OUTPUT->pix_url() is not used properly in javascript code :-(
|
||||
$value = $_GET['amp;'.$name];
|
||||
|
||||
} else if (isset($_POST[$name])) {
|
||||
$value = $_POST[$name];
|
||||
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return min_clean_param($value, $type);
|
||||
@ -50,15 +55,16 @@ function min_optional_param($name, $default, $type) {
|
||||
|
||||
/**
|
||||
* Minimalistic parameter cleaning function.
|
||||
* Can not use optional param because moodlelib.php is not loaded yet
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
*
|
||||
* Note: Can not use optional param because moodlelib.php is not loaded yet.
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $type
|
||||
* @return mixed
|
||||
*/
|
||||
function min_clean_param($value, $type) {
|
||||
switch($type) {
|
||||
case 'RAW': $value = iconv('UTF-8', 'UTF-8//IGNORE', $value);
|
||||
case 'RAW': $value = min_fix_utf8((string)$value);
|
||||
break;
|
||||
case 'INT': $value = (int)$value;
|
||||
break;
|
||||
@ -74,6 +80,49 @@ function min_clean_param($value, $type) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimalistic UTF-8 sanitisation.
|
||||
*
|
||||
* Note: This duplicates fix_utf8() intentionally for now.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
function min_fix_utf8($value) {
|
||||
// Lower error reporting because glibc throws bogus notices.
|
||||
$olderror = error_reporting();
|
||||
if ($olderror & E_NOTICE) {
|
||||
error_reporting($olderror ^ E_NOTICE);
|
||||
}
|
||||
|
||||
static $buggyiconv = null;
|
||||
if ($buggyiconv === null) {
|
||||
$buggyiconv = (!function_exists('iconv') or iconv('UTF-8', 'UTF-8//IGNORE', '100'.chr(130).'€') !== '100€');
|
||||
}
|
||||
|
||||
if ($buggyiconv) {
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
$subst = mb_substitute_character();
|
||||
mb_substitute_character('');
|
||||
$result = mb_convert_encoding($value, 'utf-8', 'utf-8');
|
||||
mb_substitute_character($subst);
|
||||
|
||||
} else {
|
||||
// Warn admins on admin/index.php page.
|
||||
$result = $value;
|
||||
}
|
||||
|
||||
} else {
|
||||
$result = iconv('UTF-8', 'UTF-8//IGNORE', $value);
|
||||
}
|
||||
|
||||
if ($olderror & E_NOTICE) {
|
||||
error_reporting($olderror);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tries to enable output compression if possible.
|
||||
* This function must be called before any output or headers.
|
||||
@ -112,7 +161,9 @@ function min_enable_zlib_compression() {
|
||||
|
||||
/**
|
||||
* Returns the slashargument part of the URL.
|
||||
* Note: ".php" is NOT allowed in slasharguments!
|
||||
*
|
||||
* Note: ".php" is NOT allowed in slasharguments,
|
||||
* it is intended for ASCII characters only.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@ -1127,15 +1127,39 @@ function fix_utf8($value) {
|
||||
// shortcut
|
||||
return $value;
|
||||
}
|
||||
// lower error reporting because glibc throws bogus notices
|
||||
|
||||
// Lower error reporting because glibc throws bogus notices.
|
||||
$olderror = error_reporting();
|
||||
if ($olderror & E_NOTICE) {
|
||||
error_reporting($olderror ^ E_NOTICE);
|
||||
}
|
||||
$result = iconv('UTF-8', 'UTF-8//IGNORE', $value);
|
||||
|
||||
// Note: this duplicates min_fix_utf8() intentionally.
|
||||
static $buggyiconv = null;
|
||||
if ($buggyiconv === null) {
|
||||
$buggyiconv = (!function_exists('iconv') or iconv('UTF-8', 'UTF-8//IGNORE', '100'.chr(130).'€') !== '100€');
|
||||
}
|
||||
|
||||
if ($buggyiconv) {
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
$subst = mb_substitute_character();
|
||||
mb_substitute_character('');
|
||||
$result = mb_convert_encoding($value, 'utf-8', 'utf-8');
|
||||
mb_substitute_character($subst);
|
||||
|
||||
} else {
|
||||
// Warn admins on admin/index.php page.
|
||||
$result = $value;
|
||||
}
|
||||
|
||||
} else {
|
||||
$result = iconv('UTF-8', 'UTF-8//IGNORE', $value);
|
||||
}
|
||||
|
||||
if ($olderror & E_NOTICE) {
|
||||
error_reporting($olderror);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
} else if (is_array($value)) {
|
||||
|
144
lib/tests/configonlylib_test.php
Normal file
144
lib/tests/configonlylib_test.php
Normal file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Unit tests for config only library functions-
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
// Global CFG not used here intentionally to make sure it is not required inside the lib.
|
||||
require_once(__DIR__ . '/../configonlylib.php');
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for config only library functions.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_configonlylib_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test cleaning of invalid utf-8 entities.
|
||||
*/
|
||||
public function test_min_fix_utf8() {
|
||||
$this->assertSame('abc', min_fix_utf8('abc'));
|
||||
$this->assertSame("žlutý koníček přeskočil potůček \n\t\r\0", min_fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
|
||||
$this->assertSame('aš', min_fix_utf8('a'.chr(130).'š'), 'This fails with buggy iconv() when mbstring extenstion is not available as fallback.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test minimalistic parameter cleaning.
|
||||
*/
|
||||
public function test_min_clean_param() {
|
||||
$this->assertSame('foo', min_clean_param('foo', 'RAW'));
|
||||
$this->assertSame('aš', min_clean_param('a'.chr(130).'š', 'RAW'));
|
||||
|
||||
$this->assertSame(1, min_clean_param('1', 'INT'));
|
||||
$this->assertSame(1, min_clean_param('1aa', 'INT'));
|
||||
|
||||
$this->assertSame('1abc-d_f', min_clean_param('/.1ačž"b?;c-d{}\\_f.', 'SAFEDIR'));
|
||||
$this->assertSame(1, min_clean_param('1aa', 'INT'));
|
||||
|
||||
$this->assertSame('/a/b/./c5', min_clean_param('/a*?$//b/.../c5', 'SAFEPATH'));
|
||||
$this->assertSame(1, min_clean_param('1aa', 'INT'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test minimalistic getting of page parameters.
|
||||
*/
|
||||
public function test_min_optional_param() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$_GET['foo'] = 'bar';
|
||||
$_GET['num'] = '1';
|
||||
$_GET['xnum'] = '1aa';
|
||||
|
||||
$_POST['foo'] = 'rebar';
|
||||
$_POST['oof'] = 'rab';
|
||||
|
||||
$this->assertSame('bar', min_optional_param('foo', null, 'RAW'));
|
||||
$this->assertSame(null, min_optional_param('foo2', null, 'RAW'));
|
||||
$this->assertSame('rab', min_optional_param('oof', null, 'RAW'));
|
||||
|
||||
$this->assertSame(1, min_optional_param('num', null, 'INT'));
|
||||
$this->assertSame(1, min_optional_param('xnum', null, 'INT'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fail-safe minimalistic slashargument processing.
|
||||
*/
|
||||
public function min_get_slash_argument() {
|
||||
global $CFG;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->assertEquals('http://www.example.com/moode', $CFG->wwwroot);
|
||||
|
||||
$_SERVER = array();
|
||||
$_SERVER['SERVER_SOFTWARE'] = 'Apache/2.2.22 (Unix)';
|
||||
$_SERVER['QUERY_STRING'] = 'theme=standard&component=core&rev=5&image=u/f1';
|
||||
$_SEREVR['REQUEST_URI'] = '/moodle/theme/image.php?theme=standard&component=core&rev=5&image=u/f1';
|
||||
$_SERVER['SCRIPT_NAME'] = '/moodle/theme/image.php';
|
||||
$this->assertSame('', min_get_slash_argument());
|
||||
|
||||
$_SERVER = array();
|
||||
$_SERVER['SERVER_SOFTWARE'] = 'Apache/2.2.22 (Unix)';
|
||||
$_SERVER['QUERY_STRING'] = '';
|
||||
$_SEREVR['REQUEST_URI'] = '/moodle/theme/image.php/standard/core/5/u/f1';
|
||||
$_SERVER['PATH_INFO'] = '/standard/core/5/u/f1';
|
||||
$_SERVER['SCRIPT_NAME'] = '/moodle/theme/image.php';
|
||||
$_GET = array();
|
||||
$this->assertSame('/standard/core/5/u/f1', min_get_slash_argument());
|
||||
|
||||
// IIS no url rewriting
|
||||
$_SERVER = array();
|
||||
$_SERVER['SERVER_SOFTWARE'] = 'Microsoft-IIS/7.0';
|
||||
$_SERVER['QUERY_STRING'] = '';
|
||||
$_SEREVR['REQUEST_URI'] = '/moodle/theme/image.php/standard/core/5/u/f1';
|
||||
$_SERVER['PATH_INFO'] = '/standard/core/5/u/f1';
|
||||
$_SERVER['SCRIPT_NAME'] = '/moodle/theme/image.php';
|
||||
$_GET = array();
|
||||
$this->assertSame('/standard/core/5/u/f1', min_get_slash_argument());
|
||||
|
||||
// IIS with url rewriting
|
||||
$_SERVER = array();
|
||||
$_SERVER['SERVER_SOFTWARE'] = 'Microsoft-IIS/7.0';
|
||||
$_SERVER['QUERY_STRING'] = 'file=/standard/core/5/u/f1';
|
||||
$_SEREVR['REQUEST_URI'] = '/moodle/theme/image.php/standard/core/5/u/f1';
|
||||
$_SERVER['PATH_INFO'] = '/';
|
||||
$_SERVER['SCRIPT_NAME'] = '/moodle/theme/image.php';
|
||||
$_GET = array();
|
||||
$_GET['file'] = '/standard/core/5/u/f1';
|
||||
$this->assertSame('/standard/core/5/u/f1', min_get_slash_argument());
|
||||
|
||||
$_SERVER = array();
|
||||
$_SERVER['SERVER_SOFTWARE'] = 'Weird server';
|
||||
$_SERVER['QUERY_STRING'] = '';
|
||||
$_SEREVR['REQUEST_URI'] = '/moodle/theme/image.php/standard/core/5/u/f1';
|
||||
$_SERVER['PATH_INFO'] = '/moodle/theme/image.php/standard/core/5/u/f1';
|
||||
$_SERVER['SCRIPT_NAME'] = '/moodle/theme/image.php';
|
||||
$_GET = array();
|
||||
$this->assertSame('/standard/core/5/u/f1', min_get_slash_argument());
|
||||
}
|
||||
}
|
@ -301,6 +301,7 @@ class moodlelib_testcase extends advanced_testcase {
|
||||
$this->assertSame(1.1, fix_utf8(1.1));
|
||||
$this->assertSame(true, fix_utf8(true));
|
||||
$this->assertSame('', fix_utf8(''));
|
||||
$this->assertSame('abc', fix_utf8('abc'));
|
||||
$array = array('do', 're', 'mi');
|
||||
$this->assertSame($array, fix_utf8($array));
|
||||
$object = new stdClass();
|
||||
@ -312,7 +313,7 @@ class moodlelib_testcase extends advanced_testcase {
|
||||
$this->assertSame("žlutý koníček přeskočil potůček \n\t\r\0", fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
|
||||
|
||||
// invalid utf8 string
|
||||
$this->assertSame('aaabbb', fix_utf8('aaa'.chr(130).'bbb'));
|
||||
$this->assertSame('aš', fix_utf8('a'.chr(130).'š'), 'This fails with buggy iconv() when mbstring extenstion is not available as fallback.');
|
||||
}
|
||||
|
||||
function test_optional_param() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user