Skip to content

Commit

Permalink
MDL-33007 add buggy iconv workaround to configonlylib, add tests and …
Browse files Browse the repository at this point in the history
…fix minor issues
  • Loading branch information
skodak committed Jun 1, 2012
1 parent 4db0616 commit 3681e78
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 6 deletions.
63 changes: 57 additions & 6 deletions lib/configonlylib.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,35 @@
* @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);
}

/**
* 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;
Expand All @@ -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.
Expand Down Expand Up @@ -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
*/
Expand Down
144 changes: 144 additions & 0 deletions lib/tests/configonlylib_test.php
Original file line number Diff line number Diff line change
@@ -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', fix_utf8('abc'));
$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"));
$this->assertSame('', 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('', 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());
}
}

0 comments on commit 3681e78

Please sign in to comment.