diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2588e80 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +autoload: + phpab --output src/ncc/autoload.php src/ncc \ No newline at end of file diff --git a/README.md b/README.md index 9386bdb..53ca8b7 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,15 @@ Nosial Code Compiler is a program written in PHP designed to be a multi-purpose compiler, package manager and toolkit. -# Copyright - - Copyright (C) 2022-2022. Nosial - All Rights Reserved. - - Copyright (c) 2015-2016 PHP School - - Copyright (c) 2011-2013, Benjamin Eberlei All rights reserved. - - Copyright (c) 2004-2022 Fabien Potencier +## Authors + - Zi Xing Narrakas (netkas) <[netkas@n64.cc](mailto:netkas@64.cc)> + - Marc Gutt (mgutt) <[marc@gutt.it](mailto:marc@gutt.it)> + +## Copyright + - Copyright (c) 2022-2022, Nosial - All Rights Reserved + - Copyright (c) 2015-2016, PHP School + - Copyright (c) 2011-2013, Benjamin Eberlei - All rights reserved + - Copyright (c) 2004-2022, Fabien Potencier # Licenses diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index 323fb65..6e96081 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -2,8 +2,11 @@ namespace ncc\Abstracts; + use ncc\Exceptions\AccessDeniedException; + use ncc\Exceptions\DirectoryNotFoundException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\InvalidProjectConfigurationException; + use ncc\Exceptions\InvalidScopeException; /** * @author Zi Xing Narrakas @@ -20,4 +23,19 @@ * @see FileNotFoundException; */ const FileNotFoundException = -1701; + + /** + * @see DirectoryNotFoundException + */ + const DirectoryNotFoundException = -1702; + + /** + * @see InvalidScopeException + */ + const InvalidScopeException = -1703; + + /** + * @see AccessDeniedException + */ + const AccessDeniedException = -1704; } \ No newline at end of file diff --git a/src/ncc/Abstracts/Scopes.php b/src/ncc/Abstracts/Scopes.php new file mode 100644 index 0000000..de3a51f --- /dev/null +++ b/src/ncc/Abstracts/Scopes.php @@ -0,0 +1,12 @@ +code = ExceptionCodes::DirectoryNotFoundException; + } + } \ No newline at end of file diff --git a/src/ncc/Exceptions/InvalidScopeException.php b/src/ncc/Exceptions/InvalidScopeException.php new file mode 100644 index 0000000..2bc6070 --- /dev/null +++ b/src/ncc/Exceptions/InvalidScopeException.php @@ -0,0 +1,21 @@ + + */ + public static function sanitizeFilename(string $input, bool $beautify=true): string + { + // sanitize filename + $input = preg_replace( + '~ + [<>:"/\\\|?*]| # file system reserved https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words + [\x00-\x1F]| # control characters http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx + [\x7F\xA0\xAD]| # non-printing characters DEL, NO-BREAK SPACE, SOFT HYPHEN + [#\[\]@!$&\'()+,;=]| # URI reserved https://www.rfc-editor.org/rfc/rfc3986#section-2.2 + [{}^\~`] # URL unsafe characters https://www.ietf.org/rfc/rfc1738.txt + ~x', + '-', $input); + // avoids ".", ".." or ".hiddenFiles" + $input = ltrim($input, '.-'); + // optional beautification + if ($beautify) $input = self::beautifyFilename($input); + // maximize filename length to 255 bytes http://serverfault.com/a/9548/44086 + $ext = pathinfo($input, PATHINFO_EXTENSION); + $input = mb_strcut(pathinfo($input, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($input)) . ($ext ? '.' . $ext : ''); + return $input; + } + + /** + * @param string $input + * @return string + * @author Marc Gutt + */ + public static function beautifyFilename(string $input): string + { + // reduce consecutive characters + $input = preg_replace(array( + // "file name.zip" becomes "file-name.zip" + '/ +/', + // "file___name.zip" becomes "file-name.zip" + '/_+/', + // "file---name.zip" becomes "file-name.zip" + '/-+/' + ), '-', $input); + $input = preg_replace(array( + // "file--.--.-.--name.zip" becomes "file.name.zip" + '/-*\.-*/', + // "file...name..zip" becomes "file.name.zip" + '/\.{2,}/' + ), '.', $input); + // lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625 + $input = mb_strtolower($input, mb_detect_encoding($input)); + // ".file-name.-" becomes "file-name" + $input = trim($input, '.-'); + + return $input; + } + } \ No newline at end of file diff --git a/src/ncc/Utilities/Validate.php b/src/ncc/Utilities/Validate.php index fdb8c44..8fa45f3 100644 --- a/src/ncc/Utilities/Validate.php +++ b/src/ncc/Utilities/Validate.php @@ -3,6 +3,8 @@ namespace ncc\Utilities; use ncc\Abstracts\RegexPatterns; + use ncc\Abstracts\Scopes; + use ncc\Exceptions\AccessDeniedException; /** * @author Zi Xing Narrakas @@ -29,4 +31,46 @@ return false; } + + /** + * Validates the scope + * + * @param string $input + * @param bool $resolve + * @return bool + * @noinspection PhpSwitchCanBeReplacedWithMatchExpressionInspection + */ + public static function scope(string $input, bool $resolve=true): bool + { + if($resolve) + { + $input = Resolver::resolveScope($input); + } + + switch($input) + { + case Scopes::System: + case Scopes::User: + return true; + + default: + return false; + } + } + + /** + * Determines if the user has access to the given scope permission + * + * @param string|null $input + * @return bool + */ + public static function scopePermission(?string $input=null): bool + { + $input = Resolver::resolveScope($input); + + if($input == Scopes::System && posix_getuid() !== 0) + return false; + + return true; + } } \ No newline at end of file diff --git a/src/ncc/autoload.php b/src/ncc/autoload.php index 954f7d7..a0b90cf 100644 --- a/src/ncc/autoload.php +++ b/src/ncc/autoload.php @@ -9,6 +9,7 @@ spl_autoload_register( $classes = array( 'ncc\\abstracts\\exceptioncodes' => '/Abstracts/ExceptionCodes.php', 'ncc\\abstracts\\regexpatterns' => '/Abstracts/RegexPatterns.php', + 'ncc\\abstracts\\scopes' => '/Abstracts/Scopes.php', 'ncc\\assert\\assert' => '/ThirdParty/beberlei/assert/Assert.php', 'ncc\\assert\\assertion' => '/ThirdParty/beberlei/assert/Assertion.php', 'ncc\\assert\\assertionchain' => '/ThirdParty/beberlei/assert/AssertionChain.php', @@ -16,8 +17,11 @@ spl_autoload_register( 'ncc\\assert\\invalidargumentexception' => '/ThirdParty/beberlei/assert/InvalidArgumentException.php', 'ncc\\assert\\lazyassertion' => '/ThirdParty/beberlei/assert/LazyAssertion.php', 'ncc\\assert\\lazyassertionexception' => '/ThirdParty/beberlei/assert/LazyAssertionException.php', + 'ncc\\exceptions\\accessdeniedexception' => '/Exceptions/AccessDeniedException.php', + 'ncc\\exceptions\\directorynotfoundexception' => '/Exceptions/DirectoryNotFoundException.php', 'ncc\\exceptions\\filenotfoundexception' => '/Exceptions/FileNotFoundException.php', 'ncc\\exceptions\\invalidprojectconfigurationexception' => '/Exceptions/InvalidProjectConfigurationException.php', + 'ncc\\exceptions\\invalidscopeexception' => '/Exceptions/InvalidScopeException.php', 'ncc\\ncc' => '/ncc.php', 'ncc\\objects\\projectconfiguration' => '/Objects/ProjectConfiguration.php', 'ncc\\objects\\projectconfiguration\\assembly' => '/Objects/ProjectConfiguration/Assembly.php', @@ -97,6 +101,9 @@ spl_autoload_register( 'ncc\\symfony\\component\\process\\process' => '/ThirdParty/Symfony/Process/Process.php', 'ncc\\symfony\\component\\process\\processutils' => '/ThirdParty/Symfony/Process/ProcessUtils.php', 'ncc\\utilities\\functions' => '/Utilities/Functions.php', + 'ncc\\utilities\\pathfinder' => '/Utilities/PathFinder.php', + 'ncc\\utilities\\resolver' => '/Utilities/Resolver.php', + 'ncc\\utilities\\security' => '/Utilities/Security.php', 'ncc\\utilities\\validate' => '/Utilities/Validate.php' ); } diff --git a/tests/utils/pathfinder.php b/tests/utils/pathfinder.php new file mode 100644 index 0000000..bc638e8 --- /dev/null +++ b/tests/utils/pathfinder.php @@ -0,0 +1,75 @@ +