MDL-45616 repositories: use json encoding instead of serialization

This commit is contained in:
Marina Glancy 2014-06-26 08:53:25 +08:00 committed by Damyon Wiese
parent 5ad3f3c61e
commit 56964b7948
7 changed files with 49 additions and 23 deletions

View File

@ -63,7 +63,7 @@ class repository_coursefiles extends repository {
$browser = get_file_browser();
if (!empty($encodedpath)) {
$params = unserialize(base64_decode($encodedpath));
$params = json_decode(base64_decode($encodedpath), true);
if (is_array($params)) {
$filepath = is_null($params['filepath']) ? NULL : clean_param($params['filepath'], PARAM_PATH);
$filename = is_null($params['filename']) ? NULL : clean_param($params['filename'], PARAM_FILE);
@ -80,12 +80,12 @@ class repository_coursefiles extends repository {
if ($fileinfo = $browser->get_file_info($context, $component, $filearea, $itemid, $filepath, $filename)) {
// build path navigation
$pathnodes = array();
$encodedpath = base64_encode(serialize($fileinfo->get_params()));
$encodedpath = base64_encode(json_encode($fileinfo->get_params()));
$pathnodes[] = array('name'=>$fileinfo->get_visible_name(), 'path'=>$encodedpath);
$level = $fileinfo->get_parent();
while ($level) {
$params = $level->get_params();
$encodedpath = base64_encode(serialize($params));
$encodedpath = base64_encode(json_encode($params));
if ($params['contextid'] != $context->id) {
break;
}
@ -102,7 +102,7 @@ class repository_coursefiles extends repository {
if ($child->is_directory()) {
$params = $child->get_params();
$subdir_children = $child->get_children();
$encodedpath = base64_encode(serialize($params));
$encodedpath = base64_encode(json_encode($params));
$node = array(
'title' => $child->get_visible_name(),
'datemodified' => $child->get_timemodified(),
@ -113,7 +113,7 @@ class repository_coursefiles extends repository {
);
$list[] = $node;
} else {
$encodedpath = base64_encode(serialize($child->get_params()));
$encodedpath = base64_encode(json_encode($child->get_params()));
$node = array(
'title' => $child->get_visible_name(),
'size' => $child->get_filesize(),

View File

@ -55,7 +55,7 @@ if (isset($info->license)) {
$license = s(clean_param($info->license, PARAM_ALPHAEXT));
}
$source = base64_encode(serialize((object)array('url'=>$url,'filename'=>$filename)));
$source = base64_encode(json_encode(array('url'=>$url,'filename'=>$filename)));
$js =<<<EOD
<html>

View File

@ -125,7 +125,11 @@ class repository_equella extends repository {
* @return string file referece
*/
public function get_file_reference($source) {
return $source;
// Internally we store serialized value but user input is json-encoded for security reasons.
$ref = json_decode(base64_decode($source));
$filename = clean_param($ref->filename, PARAM_FILE);
$url = clean_param($ref->url, PARAM_URL);
return base64_encode(serialize((object)array('url' => $url, 'filename' => $filename)));
}
/**
@ -400,12 +404,13 @@ class repository_equella extends repository {
/**
* Return the source information
*
* @param stdClass $url
* @param string $source
* @return string|null
*/
public function get_file_source_info($url) {
$ref = unserialize(base64_decode($url));
return 'EQUELLA: ' . $ref->filename;
public function get_file_source_info($source) {
$ref = json_decode(base64_decode($source));
$filename = clean_param($ref->filename, PARAM_FILE);
return 'EQUELLA: ' . $filename;
}
/**

View File

@ -1666,12 +1666,32 @@ abstract class repository implements cacheable_object {
* Prepare file reference information
*
* @param string $source source of the file, returned by repository as 'source' and received back from user (not cleaned)
* @return string file referece
* @return string file reference, ready to be stored
*/
public function get_file_reference($source) {
if ($source && $this->has_moodle_files()) {
$params = file_storage::unpack_reference($source);
if (!is_array($params)) {
$params = @json_decode(base64_decode($source), true);
if (!$params && !in_array($this->get_typename(), array('recent', 'user', 'local', 'coursefiles'))) {
// IMPORTANT! Since default format for moodle files was changed in the minor release as a security fix
// we maintain an old code here in order not to break 3rd party repositories that deal
// with moodle files. Repositories are strongly encouraged to be upgraded, see MDL-45616.
// In Moodle 2.8 this fallback will be removed.
$params = file_storage::unpack_reference($source, true);
return file_storage::pack_reference($params);
}
if (!is_array($params) || empty($params['contextid'])) {
throw new repository_exception('invalidparams', 'repository');
}
$params = array(
'component' => empty($params['component']) ? '' : clean_param($params['component'], PARAM_COMPONENT),
'filearea' => empty($params['filearea']) ? '' : clean_param($params['filearea'], PARAM_AREA),
'itemid' => empty($params['itemid']) ? 0 : clean_param($params['itemid'], PARAM_INT),
'filename' => empty($params['filename']) ? null : clean_param($params['filename'], PARAM_FILE),
'filepath' => empty($params['filepath']) ? null : clean_param($params['filepath'], PARAM_PATH),
'contextid' => clean_param($params['contextid'], PARAM_INT)
);
// Check if context exists.
if (!context::instance_by_id($params['contextid'], IGNORE_MISSING)) {
throw new repository_exception('invalidparams', 'repository');
}
return file_storage::pack_reference($params);

View File

@ -56,7 +56,7 @@ class repository_local extends repository {
$component = null;
if (!empty($encodedpath)) {
$params = unserialize(base64_decode($encodedpath));
$params = json_decode(base64_decode($encodedpath), true);
if (is_array($params) && isset($params['contextid'])) {
$component = is_null($params['component']) ? NULL : clean_param($params['component'], PARAM_COMPONENT);
$filearea = is_null($params['filearea']) ? NULL : clean_param($params['filearea'], PARAM_AREA);
@ -205,7 +205,7 @@ class repository_local extends repository {
*/
private function get_node(file_info $fileinfo) {
global $OUTPUT;
$encodedpath = base64_encode(serialize($fileinfo->get_params()));
$encodedpath = base64_encode(json_encode($fileinfo->get_params()));
$node = array(
'title' => $fileinfo->get_visible_name(),
'datemodified' => $fileinfo->get_timemodified(),
@ -245,7 +245,7 @@ class repository_local extends repository {
* @return array
*/
private function get_node_path(file_info $fileinfo) {
$encodedpath = base64_encode(serialize($fileinfo->get_params()));
$encodedpath = base64_encode(json_encode($fileinfo->get_params()));
return array(
'path' => $encodedpath,
'name' => $fileinfo->get_visible_name()

View File

@ -126,7 +126,7 @@ class repository_recent extends repository {
$fileinfo = $browser->get_file_info($context, $file['component'],
$file['filearea'], $file['itemid'], $file['filepath'], $file['filename']);
if ($fileinfo) {
$params = base64_encode(serialize($file));
$params = base64_encode(json_encode($file));
$node = array(
'title' => $fileinfo->get_visible_name(),
'size' => $fileinfo->get_filesize(),
@ -192,7 +192,8 @@ class repository_recent extends repository {
*/
public function file_is_accessible($source) {
global $USER;
$file = self::get_moodle_file($source);
$reference = $this->get_file_reference($source);
$file = self::get_moodle_file($reference);
return (!empty($file) && $file->get_userid() == $USER->id);
}

View File

@ -61,7 +61,7 @@ class repository_user extends repository {
$list = array();
if (!empty($encodedpath)) {
$params = unserialize(base64_decode($encodedpath));
$params = json_decode(base64_decode($encodedpath), true);
if (is_array($params)) {
$filepath = clean_param($params['filepath'], PARAM_PATH);
$filename = clean_param($params['filename'], PARAM_FILE);
@ -84,7 +84,7 @@ class repository_user extends repository {
$level = $fileinfo;
$params = $fileinfo->get_params();
while ($level && $params['component'] == 'user' && $params['filearea'] == 'private') {
$encodedpath = base64_encode(serialize($level->get_params()));
$encodedpath = base64_encode(json_encode($level->get_params()));
$pathnodes[] = array('name'=>$level->get_visible_name(), 'path'=>$encodedpath);
$level = $level->get_parent();
$params = $level->get_params();
@ -95,7 +95,7 @@ class repository_user extends repository {
$children = $fileinfo->get_children();
foreach ($children as $child) {
if ($child->is_directory()) {
$encodedpath = base64_encode(serialize($child->get_params()));
$encodedpath = base64_encode(json_encode($child->get_params()));
$node = array(
'title' => $child->get_visible_name(),
'datemodified' => $child->get_timemodified(),
@ -106,7 +106,7 @@ class repository_user extends repository {
);
$list[] = $node;
} else {
$encodedpath = base64_encode(serialize($child->get_params()));
$encodedpath = base64_encode(json_encode($child->get_params()));
$node = array(
'title' => $child->get_visible_name(),
'size' => $child->get_filesize(),