Skip to content

Commit

Permalink
Implement #6
Browse files Browse the repository at this point in the history
  • Loading branch information
Bui Sy Nguyen committed Apr 28, 2016
1 parent 1354c2a commit 4934c15
Show file tree
Hide file tree
Showing 4 changed files with 263 additions and 7 deletions.
5 changes: 3 additions & 2 deletions fproject/Zend/Amf/Adobe/Introspector.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
/** @see Zend_Server_Reflection */
require_once 'Zend/Server/Reflection.php';

use fproject\amf\loader\Loader;

/**
* This class implements a service for generating AMF service descriptions as XML.
*
Expand Down Expand Up @@ -92,8 +94,7 @@ public function introspect($serviceClass, $options = array())

// Introspect!
if (!class_exists($serviceClass)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($serviceClass, $this->_getServicePath());
Loader::loadClass($serviceClass, $this->_getServicePath());
}

$serv = $this->_xml->createElement('service-description');
Expand Down
5 changes: 2 additions & 3 deletions fproject/Zend/Loader/PluginLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@
/** Zend_Loader_PluginLoader_Interface */
require_once 'Zend/Loader/PluginLoader/Interface.php';

/** Zend_Loader */
require_once 'Zend/Loader.php';
use fproject\amf\loader\Loader;

/**
* Generic plugin class loader
Expand Down Expand Up @@ -397,7 +396,7 @@ public function load($name, $throwExceptions = true)

foreach ($paths as $path) {
$loadFile = $path . $classFile;
if (Zend_Loader::isReadable($loadFile)) {
if (Loader::isReadable($loadFile)) {
include_once $loadFile;
if (class_exists($className, false)) {
if (null !== $incFile) {
Expand Down
255 changes: 255 additions & 0 deletions fproject/amf/loader/Loader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
<?php
///////////////////////////////////////////////////////////////////////////////
//
// © Copyright f-project.net 2010-present.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////

namespace fproject\amf\loader;
use fproject\amf\AmfException;

/**
* Static methods for loading classes and files.
*
*/
class Loader
{
/**
* Loads a class from a PHP file. The filename must be formatted
* as "$class.php".
*
* If $dirs is a string or an array, it will search the directories
* in the order supplied, and attempt to load the first matching file.
*
* If $dirs is null, it will split the class name at underscores to
* generate a path hierarchy (e.g., "Zend_Example_Class" will map
* to "Zend/Example/Class.php").
*
* If the file was not found in the $dirs, or if no $dirs were specified,
* it will attempt to load it from PHP's include_path.
*
* @param string $class - The full class name of a Zend component.
* @param string|array $dirs - OPTIONAL Either a path or an array of paths
* to search.
* @return void
* @throws AmfException
*/
public static function loadClass($class, $dirs = null)
{
if (class_exists($class, false) || interface_exists($class, false)) {
return;
}

if ((null !== $dirs) && !is_string($dirs) && !is_array($dirs)) {
throw new AmfException('Directory argument must be a string or an array');
}

$file = self::standardiseFile($class);

if (!empty($dirs)) {
// use the autodiscovered path
$dirPath = dirname($file);
if (is_string($dirs)) {
$dirs = explode(PATH_SEPARATOR, $dirs);
}
foreach ($dirs as $key => $dir) {
if ($dir == '.') {
$dirs[$key] = $dirPath;
} else {
$dir = rtrim($dir, '\\/');
$dirs[$key] = $dir . DIRECTORY_SEPARATOR . $dirPath;
}
}
$file = basename($file);
self::loadFile($file, $dirs, true);
} else {
self::loadFile($file, null, true);
}

if (!class_exists($class, false) && !interface_exists($class, false)) {
throw new AmfException("File \"$file\" does not exist or class \"$class\" was not found in the file");
}
}

/**
* Loads a PHP file. This is a wrapper for PHP's include() function.
*
* $filename must be the complete filename, including any
* extension such as ".php". Note that a security check is performed that
* does not permit extended characters in the filename. This method is
* intended for loading Zend Framework files.
*
* If $dirs is a string or an array, it will search the directories
* in the order supplied, and attempt to load the first matching file.
*
* If the file was not found in the $dirs, or if no $dirs were specified,
* it will attempt to load it from PHP's include_path.
*
* If $once is TRUE, it will use include_once() instead of include().
*
* @param string $filename
* @param string|array $dirs - OPTIONAL either a path or array of paths
* to search.
* @param boolean $once
* @return boolean
* @throws AmfException
*/
public static function loadFile($filename, $dirs = null, $once = false)
{
self::_securityCheck($filename);

/**
* Search in provided directories, as well as include_path
*/
$incPath = false;
if (!empty($dirs) && (is_array($dirs) || is_string($dirs))) {
if (is_array($dirs)) {
$dirs = implode(PATH_SEPARATOR, $dirs);
}
$incPath = get_include_path();
set_include_path($dirs . PATH_SEPARATOR . $incPath);
}

/**
* Try finding for the plain filename in the include_path.
*/
if ($once) {
include_once $filename;
} else {
include $filename;
}

/**
* If searching in directories, reset include_path
*/
if ($incPath) {
set_include_path($incPath);
}

return true;
}

/**
* Returns TRUE if the $filename is readable, or FALSE otherwise.
* This function uses the PHP include_path, where PHP's is_readable()
* does not.
*
* Note from ZF-2900:
* If you use custom error handler, please check whether return value
* from error_reporting() is zero or not.
* At mark of fopen() can not suppress warning if the handler is used.
*
* @param string $filename
* @return boolean
*/
public static function isReadable($filename)
{
if (is_readable($filename)) {
// Return early if the filename is readable without needing the
// include_path
return true;
}

if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'
&& preg_match('/^[a-z]:/i', $filename)
) {
// If on windows, and path provided is clearly an absolute path,
// return false immediately
return false;
}

foreach (self::explodeIncludePath() as $path) {
if ($path == '.') {
if (is_readable($filename)) {
return true;
}
continue;
}
$file = $path . '/' . $filename;
if (is_readable($file)) {
return true;
}
}
return false;
}

/**
* Explode an include path into an array
*
* If no path provided, uses current include_path. Works around issues that
* occur when the path includes stream schemas.
*
* @param string|null $path
* @return array
*/
public static function explodeIncludePath($path = null)
{
if (null === $path) {
$path = get_include_path();
}

if (PATH_SEPARATOR == ':') {
// On *nix systems, include_paths which include paths with a stream
// schema cannot be safely explode'd, so we have to be a bit more
// intelligent in the approach.
$paths = preg_split('#:(?!//)#', $path);
} else {
$paths = explode(PATH_SEPARATOR, $path);
}
return $paths;
}

/**
* Ensure that filename does not contain exploits
*
* @param string $filename
* @return void
* @throws AmfException
*/
protected static function _securityCheck($filename)
{
/**
* Security check
*/
if (preg_match('/[^a-z0-9\\/\\\\_.:-]/i', $filename)) {
throw new AmfException('Security check: Illegal character in filename');
}
}

/**
* Standardise the filename.
*
* Convert the supplied filename into the namespace-aware standard,
* based on the Framework Interop Group reference implementation:
* http://groups.google.com/group/php-standards/web/psr-0-final-proposal
*
* The filename must be formatted as "$file.php".
*
* @param string $file - The file name to be loaded.
* @return string
*/
public static function standardiseFile($file)
{
$fileName = ltrim($file, '\\');
$file = '';
if ($lastNsPos = strripos($fileName, '\\')) {
$namespace = substr($fileName, 0, $lastNsPos);
$fileName = substr($fileName, $lastNsPos + 1);
$file = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$file .= str_replace('_', DIRECTORY_SEPARATOR, $fileName) . '.php';
return $file;
}
}
5 changes: 3 additions & 2 deletions fproject/amf/session/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

namespace fproject\amf\session;

use fproject\amf\loader\Loader;

class Session extends SessionAbstract
{
/**
Expand Down Expand Up @@ -761,8 +763,7 @@ private static function _processValidators()
{
foreach ($_SESSION['__ZF']['VALID'] as $validator_name => $valid_data) {
if (!class_exists($validator_name)) {
require_once 'Zend/Loader.php';
\Zend_Loader::loadClass($validator_name);
Loader::loadClass($validator_name);
}
/** @var SessionValidatorInterface $validator */
$validator = new $validator_name;
Expand Down

0 comments on commit 4934c15

Please sign in to comment.