Exemple #1
0
	public function getResultIterator(){
		return Operators::match($this->uniqueData,
			[
				[Iterators::_class,'any'],
				function($uniqueData){
					return $this->newResult()->setOptions([
						'unsafeData' => \array_keys($uniqueData),
					]);
				}
			],
			[
				Operators::identity(true), Operators::identity(new \EmptyIterator())
			]
		);
	}
Exemple #2
0
    public function __construct($args)
    {
        $this->fileObject = (new \Yasca\Core\FunctionPipe())->wrap($args)->pipe([Iterators::_class, 'elementAt'], 0)->pipe([Operators::_class, '_new'], 'w', '\\SplFileObject')->unwrap();
        $c = static function (callable $c) {
            return $c();
        };
        $this->fileObject->fwrite(<<<EOT
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>Yasca v{$c(static function () {
    return \Yasca\Scanner::VERSION;
})} - Report</title>
<style type="text/css">
    {$c(Operators::curry('\\file_get_contents', __DIR__ . '/lib/bootstrap.min.css'))}
</style>
<style type="text/css">
    {$c(Operators::curry('\\file_get_contents', __DIR__ . '/lib/prettify.css'))}
</style>
<style type="text/css">
    {$c(Operators::curry('\\file_get_contents', __DIR__ . '/lib/HtmlFileReport.css'))}
</style>
<script type="text/javascript">
    {$c(Operators::curry('\\file_get_contents', __DIR__ . '/lib/jquery-1.8.2.min.js'))}
</script>
<script type="text/javascript">
    {$c(Operators::curry('\\file_get_contents', __DIR__ . '/lib/bootstrap.min.js'))}
</script>
<script type="text/javascript">
    {$c(Operators::curry('\\file_get_contents', __DIR__ . '/lib/HtmlFileReport.js'))}
</script>
<script type="text/javascript">
    {$c(Operators::curry('\\file_get_contents', __DIR__ . '/lib/prettify.js'))}
</script>
<script type="text/javascript">
    {$c(Operators::curry('\\file_get_contents', __DIR__ . '/lib/showdown.js'))}
</script>
</head>
<body>
<div class="navbar navbar-inverse">
  <div class="navbar-inner">
    <ul class="nav">
      <li class="dropdown">
        <a href="#" class="brand dropdown-toggle" data-toggle="dropdown">
          Yasca
          <b class="caret"></b>
        </a>
        <ul class="dropdown-menu">
          <li><a href="#about-modal" role="button" data-toggle="modal">About</a></li>
          <li><a href="#" id="saveJson">Save</a></li>
          <li class="divider"></li>
          <li><a href="http://www.yasca.org/">Yasca Home Page</a></li>
          <li><a href="http://www.owasp.org/">OWASP</a></li>
        </ul>
      </li>
    </ul>
    <ul class="nav pull-right">
      <li><a href="#" class="brand">Output Report</a></li>
    </ul>
  </div>
</div>

<div id="about-modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true" aria-labelledby="about-modal-title">
    <div class="modal-header">
        <a class="close" data-dismiss="modal" aria-hidden="true">&times;</a>
        <h3 id="about-modal-title">About Yasca</h3>
    </div>
    <div class="modal-body">
        <p>Yasca is a multi-platform static analysis tool designed to help
           developers create high-quality, secure software. More information
           can be found at <a href="http://yasca.org/">yasca.org</a>.</p>

        <table>
            <tr>
                <td><strong>Yasca Version:</strong></td>
                <td>{$c(static function () {
    return \Yasca\Scanner::VERSION;
})}</td>
            </tr>
            <tr>
                <td><strong>Report Generated:</strong></td>
                <td>{$c(static function () {
    return \htmlspecialchars(\date(\DateTime::RFC850), ENT_NOQUOTES);
})}</td>
            </tr>
        </table>
        <div style="clear:both;"></div>
    </div>
    <div class="modal-footer">
        <a class="btn" data-dismiss="modal">Close</a>
    </div>
</div>

<h1 id="loading">Loading result <span id="loadingNum">0</span> of <span id="loadingOf">0</span></h1>
<div class="container-fluid">
  <div class="row-fluid">
    <div id="table-container" class="span12">
    </div>
  </div>
</div>
<div id="resultsJson" style="display:none">[
EOT
);
    }
Exemple #3
0
        $f = $this->fireLogEvent;
        $f($val);
    }
    private $fireLogEvent;
    public function __construct(callable $fireLogEvent)
    {
        $this->fireLogEvent = $fireLogEvent;
    }
}
\Closure::bind(static function () {
    static::$fileClasses = (new \Yasca\Core\FunctionPipe())->wrap(__FILE__ . '.FileClasses.json')->pipe('\\file_get_contents')->pipe([JSON::_class, 'decode'], true)->unwrap();
    static::$installedPlugins = (new \Yasca\Core\IteratorBuilder())->from(\get_declared_classes())->concat((new \Yasca\Core\IteratorBuilder())->from(new \RecursiveDirectoryIterator(__DIR__ . '/Plugins', \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_SELF | \FilesystemIterator::UNIX_PATHS))->select(static function ($rdi) {
        return $rdi->getSubPathname();
    })->whereRegex('`(?<!base)\\.php$`ui')->select(static function ($relativePath) {
        return __NAMESPACE__ . '\\Plugins\\' . (new \Yasca\Core\FunctionPipe())->wrap($relativePath)->pipe('\\substr', 0, -\strlen('.php'))->pipeLast('\\str_replace', '/', '\\')->unwrap();
    }))->where(static function ($current) {
        $c = new \ReflectionClass($current);
        if ($c->isAbstract() !== true && $c->isSubclassOf(__NAMESPACE__ . '\\Plugin') === true) {
            return true;
        }
        return false;
    })->selectKeys(static function ($plugin) {
        return [$plugin, (new \Yasca\Core\FunctionPipe())->wrap($plugin)->pipe([Iterators::_class, 'traitsOf'])->toIteratorBuilder()->where(static function ($trait) {
            return $trait === __NAMESPACE__ . '\\AggregateFileContentsPlugin' || $trait === __NAMESPACE__ . '\\MulticastPlugin' || $trait === __NAMESPACE__ . '\\SingleFileContentsPlugin' || $trait === __NAMESPACE__ . '\\SingleFilePathPlugin';
        })->firstOrNull()];
    })->where(static function ($plugin, $trait) {
        return $trait !== null;
    })->groupBy(static function ($plugin, $trait) {
        return $trait;
    })->select(Operators::paramLimit([Iterators::_class, 'toFixedArray'], 1))->toArray(true);
}, null, __NAMESPACE__ . '\\' . \basename(__FILE__, '.php'))->__invoke();
Exemple #4
0
  yasca.bat c:\\source_code
  yasca.sh /opt/dev/source_code
  php.exe Main.php --pluginsIgnore,FindBugs,PMD,Antic,JLint /opt/dev/source_code
  php.exe Main.php --log,ConsoleLog,7 "c:/orange/"
  php.exe Main.php --onlyPlugins,BuiltIn c:/example/


EOT;
    if ($_SERVER['argc'] < 2) {
        print $help;
        exit(0);
    }
    foreach ((new \Yasca\Core\IteratorBuilder())->from($_SERVER['argv'])->skip(1)->selectKeys(static function ($arg) {
        $options = \str_getcsv($arg);
        $switch = \array_shift($options);
        return [Operators::nullCoalesce($options, []), $switch];
    }) as $switch => $options) {
        //As of PHP 5.4, switch() uses loose comparision instead of strict.
        //Use if/elseif instead.
        if ($switch === '-h' || $switch === '--help' || $switch === '/?') {
            print $help;
            exit(0);
        } elseif ($switch === '-v' || $switch === '--version') {
            print $version;
            exit(0);
        } elseif ($switch === '--pluginInstalled' || $switch === '--pluginsInstalled' || $switch === '--installedPlugins' || $switch === '--installedPlugin') {
            (new \Yasca\Core\IteratorBuilder())->from(\Yasca\Plugin::$installedPlugins)->selectMany(static function ($plugins) {
                return $plugins;
            })->forAll(static function ($plugin) {
                print "{$plugin}\n";
            });
	public function __construct($options){
		list($subscribeIfCloseable, $closeSubscribedCloseables) =
			Operators::invoke(static function(){
				$closeables = new \SplObjectStorage();
				return [
					static function($object) use ($closeables){
						if (
							(new \Yasca\Core\IteratorBuilder)
							->from(Iterators::traitsOf($object))
							->contains('Yasca\Core\Closeable')
						){
							$closeables->attach($object);
						}
					},
					static function() use ($closeables){
						foreach($closeables as $closeable){
							$closeable->close();
						}
						$closeables->removeAllExcept(new \SplObjectStorage());
					},
				];
			});

		list($fireLogEvent, $fireResultEvent) =
			Operators::invoke(function() use ($subscribeIfCloseable){
				$newEvent = function($name) use ($subscribeIfCloseable){
					$event = new SplSubjectAdapter();
					$this->{"attach{$name}Observer"} = function(\SplObserver $observer) use ($event, $subscribeIfCloseable){
						$event->attach($observer);
						$subscribeIfCloseable($observer);
						return $this;
					};
					$this->{"detach{$name}Observer"} = function(\SplObserver $observer) use ($event, $subscribeIfCloseable){
						$event->detach($observer);
						$subscribeIfCloseable($observer);
						return $this;
					};
					return static function($value) use ($event){
						$event->raise($value);
					};
				};
				return [
					$newEvent('Log'),
					$newEvent('Result'),
				];
			});

		$targetDirectory =
			(new \Yasca\Core\FunctionPipe)
			->wrap($options)
			->pipe([Iterators::_class,'elementAtOrNull'], 'targetDirectory')
			->pipe('\realpath')
			->unwrap();

		$makeRelative =
			//Make filenames relative when publishing a result
			(new \Yasca\Core\FunctionPipe)
			->wrap($targetDirectory)
			->pipe('\preg_quote', '`')
			->pipe(static function($dirLiteral) { return "`^$dirLiteral`ui"; })
			->pipe(static function($regex){
				return Operators::curry('\preg_replace', $regex, '');
			})
			->unwrap();

		//Wrap Result event trigger to make changes to each Result
		$fireResultEvent = static function(Result $result) use ($fireResultEvent, $makeRelative){
			//Make adjustments based on adjustments data
			(new \Yasca\Core\FunctionPipe)
			->wrap(static::$adjustments)
			->pipe([Iterators::_class, 'elementAtOrNull'], $result->pluginName)
			->pipe([Iterators::_class, 'elementAtOrNull'], $result->category)
			->pipe(static function($options) use ($result){
				if ($options !== null){
					$result->setOptions($options);
				}
			});

			//Get unsafeSourceCode if needed, and then make the filename relative
			//to the scan directory
			if (isset($result->filename) === true && !Operators::isNullOrEmpty($result->filename)){
				if(isset($result->lineNumber) === true && isset($result->unsafeSourceCode) !== true){
					try {
						$result->unsafeSourceCode =
							(new \Yasca\Core\FunctionPipe)
							->wrap($result->filename)
							->pipe([Encoding::_class,'getFileContentsAsArray'])
							->toIteratorBuilder()
							->slice(
								\max($result->lineNumber - 10, 0),
								20
							)
							->toArray(true);
					} catch (\ErrorException $e){
						$tail = 'No such file or directory';
						if (\substr($e->getMessage(),0-strlen($tail)) === $tail){
							//External tool generated a filename that's not present
							//FindBugs can often do this if the matching .java files are missing.
						} else {
							throw $e;
						}
					}
				}
				$result->setOptions([
					'filename' => "{$makeRelative($result->filename)}",
				]);
			}
			$fireResultEvent($result);
		};

		$createPlugins =
			Operators::curry(
				static function($ignoreRegex, $onlyRegex) use ($fireLogEvent){
					$retval =
						(new \Yasca\Core\IteratorBuilder)
						->from(Plugin::$installedPlugins)
						->select(static function($plugins) use ($ignoreRegex, $onlyRegex, $fireLogEvent){
							return (new \Yasca\Core\IteratorBuilder)
							->from($plugins)
							->whereRegex($ignoreRegex)
							->whereRegex($onlyRegex)
							->select(static function($pluginName) use ($fireLogEvent){
								$p = new $pluginName($fireLogEvent);
								$fireLogEvent(["Plugin $pluginName Loaded", \Yasca\Logs\Level::DEBUG]);
								return $p;
							})
							->toObjectStorage();
						})
						->where([Iterators::_class,'any'])
						->toArray(true);
					$fireLogEvent(['Selected Plugins Loaded', \Yasca\Logs\Level::DEBUG]);
					return $retval;
				},
				(new \Yasca\Core\FunctionPipe)
				->wrap($options)
				->pipe([Iterators::_class, 'elementAtOrNull'], 'pluginsIgnore')
				->toIteratorBuilder()
				->select(static function($literal){return \preg_quote($literal, '`');})
				->toFunctionPipe()
				->pipe([Iterators::_class, 'join'], '|')
				->pipe(static function($string){
					if (Operators::isNullOrEmpty($string) === true){
						return null;
					} else {
						return "`^(?!.*($string).*$)`u";
					}
				})
				->unwrap(),
				(new \Yasca\Core\FunctionPipe)
				->wrap($options)
				->pipe([Iterators::_class, 'elementAtOrNull'], 'pluginsOnly')
				->toIteratorBuilder()
				->select(static function($literal){return \preg_quote($literal, '`');})
				->toFunctionPipe()
				->pipe([Iterators::_class, 'join'], '|')
				->pipe(static function($string){
					if (Operators::isNullOrEmpty($string) === true){
						return null;
					} else {
						return "`($string)`u";
					}
				})
				->unwrap()
			);

		$createTargetIterator =
			Operators::curry(
				static function($extensionRegex, $extensionsIgnoreRegex, $extensionsOnlyRegex, $pluginArray) use ($targetDirectory){
					//Only select files that plugins ask for
					return (new \Yasca\Core\IteratorBuilder)
					->from(new \RecursiveDirectoryIterator(
						$targetDirectory,
						\FilesystemIterator::KEY_AS_PATHNAME 	 |
						\FilesystemIterator::CURRENT_AS_FILEINFO |
						\FilesystemIterator::UNIX_PATHS
					))
					->whereRegex($extensionRegex($pluginArray), \RegexIterator::MATCH, \RegexIterator::USE_KEY)
					->whereRegex($extensionsIgnoreRegex, \RegexIterator::MATCH, \RegexIterator::USE_KEY)
					->whereRegex($extensionsOnlyRegex, \RegexIterator::MATCH, \RegexIterator::USE_KEY)
					;
				},
				static function($pluginArray){
					return (new \Yasca\Core\IteratorBuilder)
					->from($pluginArray)
					->selectMany(static function($plugins){
						return (new \Yasca\Core\IteratorBuilder)
						->from($plugins);
					})
					->selectMany(static function($plugin){
						return (new \Yasca\Core\IteratorBuilder)
						->from($plugin->getSupportedFileTypes());
					})
					->unique()
					->select(static function($ext){
						return \preg_quote($ext, '`');
					})
					->toFunctionPipe()
					->pipe([Iterators::_class, 'join'], '|')
					->pipe(static function($string){
						if (Operators::isNullOrEmpty($string) === true){
							return null;
						} else {
							return "`\.($string)$`ui";
						}
					})
					->unwrap();
				},
				(new \Yasca\Core\FunctionPipe)
				->wrap($options)
				->pipe([Iterators::_class, 'elementAtOrNull'], 'extensionsIgnore')
				->toIteratorBuilder()
				->select(static function($ext){return '.' . \trim($ext, '.');})
				->select(static function($literal){return \preg_quote($literal, '`');})
				->toFunctionPipe()
				->pipe([Iterators::_class, 'join'], '|')
				->pipe(static function($string){
					if (Operators::isNullOrEmpty($string) === true){
						return null;
					} else {
						return "`(?<!$string)$`ui";
					}
				})
				->unwrap(),
				(new \Yasca\Core\FunctionPipe)
				->wrap($options)
				->pipe([Iterators::_class, 'elementAtOrNull'], 'extensionsOnly')
				->toIteratorBuilder()
				->select(static function($ext){return '.' . \trim($ext, '.');})
				->select(static function($literal){return \preg_quote($literal, '`');})
				->toFunctionPipe()
				->pipe([Iterators::_class, 'join'], '|')
				->pipe(static function($string){
					if (Operators::isNullOrEmpty($string) === true){
						return null;
					} else {
						return "`($string)$`ui";
					}
				})
				->unwrap()
			);

		$debug =
			(new \Yasca\Core\FunctionPipe)
			->wrap($options)
			->pipe([Iterators::_class,'elementAtOrNull'], 'debug')
			->pipe([Operators::_class,'equals'], true)
			->unwrap();

		$processResults =
			static function($results) use ($fireResultEvent, &$processResults){
				if ($results instanceof Result){
					$fireResultEvent($results);
					return new \EmptyIterator();
				} elseif ($results instanceof Async){
					if ($results->isDone() === true){
						return $processResults($results->result());
					} else {
						return Iterators::ensureIsIterator([$results]);
					}
				} elseif ($results instanceof Wrapper){
					return $processResults($results->unwrap());
				} else {
					return (new \Yasca\Core\IteratorBuilder)
					->from($results)
					->selectMany($processResults);
				}
			};

		$this->executeAsync = static function() use (
			$fireLogEvent,
			$processResults,
			$closeSubscribedCloseables, $debug,
			$makeRelative, $createPlugins,
			$targetDirectory, $createTargetIterator
		){
			try {
				$fireLogEvent(['Yasca ' . Scanner::VERSION . ' - http://www.yasca.org/ - Michael V. Scovetta', \Yasca\Logs\Level::INFO]);
				$fireLogEvent(["Scanning $targetDirectory", \Yasca\Logs\Level::INFO]);


				$plugins = $createPlugins();

				$multicasts = Iterators::elementAtOrNull($plugins, __NAMESPACE__ . '\MulticastPlugin');

				$lastStatusReportedTime = \time();
				$filesProcessed = 0;
				$awaits = [];
				foreach($createTargetIterator($plugins) as $filePath => $targetFileInfo){
					$fireLogEvent(["Checking file {$makeRelative($filePath)}", \Yasca\Logs\Level::DEBUG]);

					$n = \time();
					if ($n - $lastStatusReportedTime > self::SECONDS_PER_NOTIFY){
						$fireLogEvent(["$filesProcessed files scanned", \Yasca\Logs\Level::INFO]);
						$lastStatusReportedTime = $n;
					}

					$ext = $targetFileInfo->getExtension();
					$getFileContents =
						(new \Yasca\Core\FunctionPipe)
						->wrap($filePath)
						->pipeLast([Operators::_class,'curry'], [Encoding::_class, 'getFileContentsAsArray'])
						->pipe([Operators::_class,'lazy'])
						->unwrap();

					$awaits =
						(new \Yasca\Core\IteratorBuilder)
						->from($awaits)
						->concat(
							//Multicast plugin results
							(new \Yasca\Core\IteratorBuilder)
							->from($multicasts)

							//Make a copy to allow removing elements iterated over
							->toFunctionPipe()
							->pipe([Iterators::_class,'toList'])
							->toIteratorBuilder()

							->where(static function($plugin) use ($ext){
								return $plugin->supportsExtension($ext);
							})
							->select(static function($plugin) use ($multicasts, $targetDirectory){
								$multicasts->detach($plugin);
								return $plugin->getResultIterator($targetDirectory);
							}),

							//Single file path plugin results
							(new \Yasca\Core\FunctionPipe)
							->wrap($plugins)
							->pipe([Iterators::_class, 'elementAtOrNull'], __NAMESPACE__ . '\SingleFilePathPlugin')
							->toIteratorBuilder()
							->where(static function($plugin) use ($ext){
								return $plugin->supportsExtension($ext);
							})
							->select(static function($plugin) use ($filePath){
								return $plugin->getResultIterator($filePath);
							}),

							//Single file contents plugin results
							(new \Yasca\Core\FunctionPipe)
							->wrap($plugins)
							->pipe([Iterators::_class, 'elementAtOrNull'], __NAMESPACE__ . '\SingleFileContentsPlugin')
							->toIteratorBuilder()
							->where(static function($plugin) use ($ext){
								return $plugin->supportsExtension($ext);
							})
							->select(static function($plugin) use ($getFileContents, $filePath){
								return $plugin->getResultIterator($getFileContents(), $filePath);
							})
						)
						->selectMany($processResults)
						->toList();

					(new \Yasca\Core\FunctionPipe)
					->wrap($plugins)
					->pipe([Iterators::_class, 'elementAtOrNull'], __NAMESPACE__ . '\AggregateFileContentsPlugin')
					->toIteratorBuilder()
					->where(static function($plugin) use ($ext){
						return $plugin->supportsExtension($ext);
					})
					->forAll(static function($plugin) use ($getFileContents, $filePath){
						$plugin->apply($getFileContents(), $filePath);
					});

					Async::tickAll();
					$filesProcessed += 1;
				}
				$fireLogEvent(['Finished with files. Gathering results from Aggregate plugins', \Yasca\Logs\Level::DEBUG]);

				$awaits =
					(new \Yasca\Core\FunctionPipe)
					->wrap($plugins)
					->pipe([Iterators::_class, 'elementAtOrNull'], __NAMESPACE__ . '\AggregateFileContentsPlugin')
					->toIteratorBuilder()
					->select(static function($plugin){return $plugin->getResultIterator();})
					->concat($awaits)
					->selectMany($processResults)
					->toList();
				if (Iterators::any($awaits) === true){
					$fireLogEvent(['Waiting on external plugins', \Yasca\Logs\Level::INFO]);
					return (new Async(
						static function() use (
							&$awaits, $processResults, $fireLogEvent
						){
							$awaits =
								(new \Yasca\Core\IteratorBuilder)
								->from($awaits)
								->selectMany($processResults)
								->toList();
							return Iterators::any($awaits) === false;
						},
						static function() use ($fireLogEvent) {
							$fireLogEvent(['Scan complete', \Yasca\Logs\Level::INFO]);
							return null;
						},
						static function(\Exception $exception) use ($fireLogEvent, $debug){
							$fireLogEvent(['Scan aborted', \Yasca\Logs\Level::ERROR]);
							if ($debug === true){
								throw $exception;
							} else {
								$fireLogEvent([$exception->getMessage(), \Yasca\Logs\Level::ERROR]);
								return null;
							}
						}
					))
					->whenDone($closeSubscribedCloseables);
				} else {
					$fireLogEvent(['Scan complete', \Yasca\Logs\Level::INFO]);
					return Async::fromResult(null)->whenDone($closeSubscribedCloseables);
				}
			} catch (\Exception $exception){
				$fireLogEvent(['Scan aborted', \Yasca\Logs\Level::ERROR]);
				if ($debug === true) {
					$closeSubscribedCloseables();
					throw $exception;
				} else {
					$fireLogEvent([$exception->getMessage(), \Yasca\Logs\Level::ERROR]);
					return Async::fromResult(null)->whenDone($closeSubscribedCloseables);
				}
			}
		};

		$this->execute = function(){
			$f = $this->executeAsync;
			return $f()->result();
		};
	}
Exemple #6
0
if ($_SERVER['argc'] < 2){
    print($help);
    exit(0);
}

foreach (
    (new \Yasca\Core\IteratorBuilder)
    ->from($_SERVER['argv'])
    //Skip the name of the script file
    ->skip(1)
    ->selectKeys(static function($arg){
        $options = \str_getcsv($arg);
        $switch = \array_shift($options);
        return [
            Operators::nullCoalesce($options,[]),
            $switch,
        ];
    })

    as $switch => $options
){
    //As of PHP 5.4, switch() uses loose comparision instead of strict.
    //Use if/elseif instead.
    if          ($switch === '-h'         ||
              $switch === '--help'  ||
              $switch === '/?'
      ){
        print($help);
        exit(0);
Exemple #7
0
                                            return $trait ===
                                                     __NAMESPACE__ .
                                                     '\AggregateFileContentsPlugin' || $trait === __NAMESPACE__ .
                                                     '\MulticastPlugin' ||
                                                     $trait ===
                                                     __NAMESPACE__ .
                                                     '\SingleFileContentsPlugin' || $trait === __NAMESPACE__ .
                                                     '\SingleFilePathPlugin';
                                        })
                                    ->firstOrNull()
                        ];
                    })
                ->where(
                    static function  ($plugin, $trait)
                    {
                        return $trait !== null;
                    })
                ->groupBy(
                    static function  ($plugin, $trait)
                    {
                        return $trait;
                    })
                ->select(
                    Operators::paramLimit(
                            [
                                    Iterators::_class,
                                    'toFixedArray'
                            ], 1))
                ->toArray(true);
        }, null, __NAMESPACE__ . '\\' . \basename(__FILE__, '.php'))->__invoke();