diff options
Diffstat (limited to 'application')
96 files changed, 2291 insertions, 1188 deletions
diff --git a/application/.htaccess b/application/.htaccess index 14249c50b..6c63ed4c4 100644 --- a/application/.htaccess +++ b/application/.htaccess @@ -1 +1,6 @@ -Deny from all
\ No newline at end of file +<IfModule authz_core_module> + Require all denied +</IfModule> +<IfModule !authz_core_module> + Deny from all +</IfModule>
\ No newline at end of file diff --git a/application/cache/.htaccess b/application/cache/.htaccess deleted file mode 100644 index 14249c50b..000000000 --- a/application/cache/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all
\ No newline at end of file diff --git a/application/cache/index.html b/application/cache/index.html index c942a79ce..bcb7cae34 100644 --- a/application/cache/index.html +++ b/application/cache/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/config/autoload.php b/application/config/autoload.php index a471f3ab2..a95dc038a 100644 --- a/application/config/autoload.php +++ b/application/config/autoload.php @@ -1,4 +1,6 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + /* | ------------------------------------------------------------------- | AUTO-LOADER @@ -20,40 +22,64 @@ | | 1. Packages | 2. Libraries -| 3. Helper files -| 4. Custom config files -| 5. Language files -| 6. Models +| 3. Drivers +| 4. Helper files +| 5. Custom config files +| 6. Language files +| 7. Models | */ /* | ------------------------------------------------------------------- -| Auto-load Packges +| Auto-load Packages | ------------------------------------------------------------------- | Prototype: | | $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared'); | */ - $autoload['packages'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Libraries | ------------------------------------------------------------------- -| These are the classes located in the system/libraries folder -| or in your application/libraries folder. +| These are the classes located in system/libraries/ or your +| application/libraries/ directory, with the addition of the +| 'database' library, which is somewhat of a special case. | | Prototype: | -| $autoload['libraries'] = array('database', 'session', 'xmlrpc'); +| $autoload['libraries'] = array('database', 'email', 'session'); +| +| You can also supply an alternative library name to be assigned +| in the controller: +| +| $autoload['libraries'] = array('user_agent' => 'ua'); */ - $autoload['libraries'] = array('database'); +/* +| ------------------------------------------------------------------- +| Auto-load Drivers +| ------------------------------------------------------------------- +| These classes are located in system/libraries/ or in your +| application/libraries/ directory, but are also placed inside their +| own subdirectory and they extend the CI_Driver_Library class. They +| offer multiple interchangeable driver options. +| +| Prototype: +| +| $autoload['drivers'] = array('cache'); +| +| You can also supply an alternative property name to be assigned in +| the controller: +| +| $autoload['drivers'] = array('cache' => 'cch'); +| +*/ +$autoload['drivers'] = array(); /* | ------------------------------------------------------------------- @@ -63,10 +89,8 @@ $autoload['libraries'] = array('database'); | | $autoload['helper'] = array('url', 'file'); */ - $autoload['helper'] = array('url'); - /* | ------------------------------------------------------------------- | Auto-load Config files @@ -79,10 +103,8 @@ $autoload['helper'] = array('url'); | config files. Otherwise, leave it blank. | */ - $autoload['config'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Language files @@ -95,22 +117,19 @@ $autoload['config'] = array(); | "codeigniter_lang.php" would be referenced as array('codeigniter'); | */ - $autoload['language'] = array(); - /* | ------------------------------------------------------------------- | Auto-load Models | ------------------------------------------------------------------- | Prototype: | -| $autoload['model'] = array('model1', 'model2'); +| $autoload['model'] = array('first_model', 'second_model'); +| +| You can also supply an alternative model name to be assigned +| in the controller: | +| $autoload['model'] = array('first_model' => 'first'); */ - $autoload['model'] = array(); - - -/* End of file autoload.php */ -/* Location: ./application/config/autoload.php */
\ No newline at end of file diff --git a/application/config/config.php b/application/config/config.php index 5ec10e233..343528363 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -1,4 +1,5 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); /* |-------------------------------------------------------------------------- @@ -10,11 +11,19 @@ | | http://example.com/ | -| If this is not set then CodeIgniter will guess the protocol, domain and -| path to your installation. +| WARNING: You MUST set this value! +| +| If it is not set, then CodeIgniter will try to guess the protocol and +| path to your installation, but due to security concerns the hostname will +| be set to $_SERVER['SERVER_ADDR'] if available, or localhost otherwise. +| The auto-detection mechanism exists only for convenience during +| development and MUST NOT be used in production! +| +| If you need to allow multiple domains, remember that this file is still +| a PHP script and you can easily do that on your own. | */ -$config['base_url'] = ''; +$config['base_url'] = ''; /* |-------------------------------------------------------------------------- @@ -34,17 +43,16 @@ $config['index_page'] = 'index.php'; |-------------------------------------------------------------------------- | | This item determines which server global should be used to retrieve the -| URI string. The default setting of 'AUTO' works for most servers. +| URI string. The default setting of 'REQUEST_URI' works for most servers. | If your links do not seem to work, try one of the other delicious flavors: | -| 'AUTO' Default - auto detects -| 'PATH_INFO' Uses the PATH_INFO -| 'QUERY_STRING' Uses the QUERY_STRING -| 'REQUEST_URI' Uses the REQUEST_URI -| 'ORIG_PATH_INFO' Uses the ORIG_PATH_INFO +| 'REQUEST_URI' Uses $_SERVER['REQUEST_URI'] +| 'QUERY_STRING' Uses $_SERVER['QUERY_STRING'] +| 'PATH_INFO' Uses $_SERVER['PATH_INFO'] | +| WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded! */ -$config['uri_protocol'] = 'AUTO'; +$config['uri_protocol'] = 'REQUEST_URI'; /* |-------------------------------------------------------------------------- @@ -54,9 +62,10 @@ $config['uri_protocol'] = 'AUTO'; | This option allows you to add a suffix to all URLs generated by CodeIgniter. | For more information please see the user guide: | -| http://codeigniter.com/user_guide/general/urls.html +| https://codeigniter.com/userguide3/general/urls.html +| +| Note: This option is ignored for CLI requests. */ - $config['url_suffix'] = ''; /* @@ -79,6 +88,8 @@ $config['language'] = 'english'; | This determines which character set is used by default in various methods | that require a character set to be provided. | +| See https://secure.php.net/htmlspecialchars for a list of supported charsets. +| */ $config['charset'] = 'UTF-8'; @@ -93,7 +104,6 @@ $config['charset'] = 'UTF-8'; */ $config['enable_hooks'] = FALSE; - /* |-------------------------------------------------------------------------- | Class Extension Prefix @@ -102,29 +112,55 @@ $config['enable_hooks'] = FALSE; | This item allows you to set the filename/classname prefix when extending | native libraries. For more information please see the user guide: | -| http://codeigniter.com/user_guide/general/core_classes.html -| http://codeigniter.com/user_guide/general/creating_libraries.html +| https://codeigniter.com/userguide3/general/core_classes.html +| https://codeigniter.com/userguide3/general/creating_libraries.html | */ $config['subclass_prefix'] = 'MY_'; +/* +|-------------------------------------------------------------------------- +| Composer auto-loading +|-------------------------------------------------------------------------- +| +| Enabling this setting will tell CodeIgniter to look for a Composer +| package auto-loader script in application/vendor/autoload.php. +| +| $config['composer_autoload'] = TRUE; +| +| Or if you have your vendor/ directory located somewhere else, you +| can opt to set a specific path as well: +| +| $config['composer_autoload'] = '/path/to/vendor/autoload.php'; +| +| For more information about Composer, please visit https://getcomposer.org/ +| +| Note: This will NOT disable or override the CodeIgniter-specific +| autoloading (application/config/autoload.php) +*/ +$config['composer_autoload'] = FALSE; /* |-------------------------------------------------------------------------- | Allowed URL Characters |-------------------------------------------------------------------------- | -| This lets you specify with a regular expression which characters are permitted -| within your URLs. When someone tries to submit a URL with disallowed -| characters they will get a warning message. +| This lets you specify which characters are permitted within your URLs. +| When someone tries to submit a URL with disallowed characters they will +| get a warning message. | | As a security measure you are STRONGLY encouraged to restrict URLs to | as few characters as possible. By default only these are allowed: a-z 0-9~%.:_- | | Leave blank to allow all characters -- but only if you are insane. | +| The configured value is actually a regular expression character group +| and it will be executed as: ! preg_match('/^[<permitted_uri_chars>]+$/i +| | DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!! | +| Note: This option is ignored for CLI requests. +| */ if (php_sapi_name() == "cli") { $config['permitted_uri_chars'] = ''; @@ -132,7 +168,6 @@ if (php_sapi_name() == "cli") { $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-'; } - /* |-------------------------------------------------------------------------- | Enable Query Strings @@ -141,9 +176,6 @@ if (php_sapi_name() == "cli") { | By default CodeIgniter uses search-engine friendly segment based URLs: | example.com/who/what/where/ | -| By default CodeIgniter enables access to the $_GET array. If for some -| reason you would like to disable it, set 'allow_get_array' to FALSE. -| | You can optionally enable standard query string based URLs: | example.com?who=me&what=something&where=here | @@ -158,19 +190,16 @@ if (php_sapi_name() == "cli") { | use segment based URLs. | */ -$config['allow_get_array'] = TRUE; $config['enable_query_strings'] = FALSE; -$config['controller_trigger'] = 'c'; -$config['function_trigger'] = 'm'; -$config['directory_trigger'] = 'd'; // experimental not currently in use +$config['controller_trigger'] = 'c'; +$config['function_trigger'] = 'm'; +$config['directory_trigger'] = 'd'; /* |-------------------------------------------------------------------------- | Error Logging Threshold |-------------------------------------------------------------------------- | -| If you have enabled error logging, you can set an error threshold to -| determine what gets logged. Threshold options are: | You can enable error logging by setting a threshold over zero. The | threshold determines what gets logged. Threshold options are: | @@ -180,6 +209,10 @@ $config['directory_trigger'] = 'd'; // experimental not currently in use | 3 = Informational Messages | 4 = All Messages | +| You can also pass an array with threshold levels to show individual error types +| +| array(2) = Debug Messages, without Error Messages +| | For a live site you'll usually only enable Errors (1) to be logged otherwise | your log files will fill up very fast. | @@ -192,13 +225,36 @@ $config['log_threshold'] = 0; |-------------------------------------------------------------------------- | | Leave this BLANK unless you would like to set something other than the default -| application/logs/ folder. Use a full server path with trailing slash. +| application/logs/ directory. Use a full server path. | */ $config['log_path'] = ''; /* |-------------------------------------------------------------------------- +| Error Logging FILENAME +|-------------------------------------------------------------------------- +| +| Leave this BLANK unless you would like to set something other than the default +| 'log-'.date('Y-m-d').'.php'. No DIRECTORY_SEPARATOR(s), just the filename. +| +*/ +$config['log_filename'] = ''; + +/* +|-------------------------------------------------------------------------- +| Log File Permissions +|-------------------------------------------------------------------------- +| +| The file system permissions to be applied on newly created log files. +| +| IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal +| integer notation (i.e. 0700, 0644, etc.) +*/ +$config['log_file_permissions'] = 0644; + +/* +|-------------------------------------------------------------------------- | Date Format for Logs |-------------------------------------------------------------------------- | @@ -210,80 +266,143 @@ $config['log_date_format'] = 'Y-m-d H:i:s'; /* |-------------------------------------------------------------------------- +| Error Views Directory Path +|-------------------------------------------------------------------------- +| +| Leave this BLANK unless you would like to set something other than the default +| application/views/errors/ directory. Use a full server path. +| +*/ +$config['error_views_path'] = ''; + +/* +|-------------------------------------------------------------------------- | Cache Directory Path |-------------------------------------------------------------------------- | | Leave this BLANK unless you would like to set something other than the default -| system/cache/ folder. Use a full server path with trailing slash. +| application/cache/ directory. Use a full server path. | */ $config['cache_path'] = ''; /* |-------------------------------------------------------------------------- -| Encryption Key +| Cache Include Query String |-------------------------------------------------------------------------- | -| If you use the Encryption class or the Session class you -| MUST set an encryption key. See the user guide for info. +| Whether to take the URL query string into consideration when generating +| output cache files. Valid options are: +| +| FALSE = Disabled +| TRUE = Enabled, take all query parameters into account. +| Please be aware that this may result in numerous cache +| files generated for the same page over and over again. +| array('q') = Enabled, but only take into account the specified list +| of query parameters. | */ -$config['encryption_key'] = ''; +$config['cache_query_string'] = FALSE; /* |-------------------------------------------------------------------------- -| Session Variables +| Encryption Key |-------------------------------------------------------------------------- | -| 'sess_cookie_name' = the name you want for the cookie -| 'sess_expiration' = the number of SECONDS you want the session to last. -| by default sessions last 7200 seconds (two hours). Set to zero for no expiration. -| 'sess_expire_on_close' = Whether to cause the session to expire automatically -| when the browser window is closed -| 'sess_encrypt_cookie' = Whether to encrypt the cookie -| 'sess_use_database' = Whether to save the session data to a database -| 'sess_table_name' = The name of the session database table -| 'sess_match_ip' = Whether to match the user's IP address when reading the session data -| 'sess_match_useragent' = Whether to match the User Agent when reading the session data -| 'sess_time_to_update' = how many seconds between CI refreshing Session Information +| If you use the Encryption class, you must set an encryption key. +| See the user guide for more info. +| +| https://codeigniter.com/userguide3/libraries/encryption.html | */ -$config['sess_cookie_name'] = 'ci_session'; -$config['sess_expiration'] = 7200; -$config['sess_expire_on_close'] = FALSE; -$config['sess_encrypt_cookie'] = FALSE; -$config['sess_use_database'] = true; -$config['sess_table_name'] = 'ci_sessions'; -$config['sess_match_ip'] = FALSE; -$config['sess_match_useragent'] = TRUE; -$config['sess_time_to_update'] = 300; +$config['encryption_key'] = ''; /* |-------------------------------------------------------------------------- -| Cookie Related Variables +| Session Variables |-------------------------------------------------------------------------- | -| 'cookie_prefix' = Set a prefix if you need to avoid collisions -| 'cookie_domain' = Set to .your-domain.com for site-wide cookies -| 'cookie_path' = Typically will be a forward slash -| 'cookie_secure' = Cookies will only be set if a secure HTTPS connection exists. +| 'sess_driver' +| +| The storage driver to use: files, database, redis, memcached +| +| 'sess_cookie_name' +| +| The session cookie name, must contain only [0-9a-z_-] characters +| +| 'sess_samesite' +| +| Session cookie SameSite attribute: Lax (default), Strict or None +| +| 'sess_expiration' +| +| The number of SECONDS you want the session to last. +| Setting to 0 (zero) means expire when the browser is closed. +| +| 'sess_save_path' +| +| The location to save sessions to, driver dependent. +| +| For the 'files' driver, it's a path to a writable directory. +| WARNING: Only absolute paths are supported! +| +| For the 'database' driver, it's a table name. +| Please read up the manual for the format with other session drivers. +| +| IMPORTANT: You are REQUIRED to set a valid save path! +| +| 'sess_match_ip' +| +| Whether to match the user's IP address when reading the session data. +| +| WARNING: If you're using the database driver, don't forget to update +| your session table's PRIMARY KEY when changing this setting. +| +| 'sess_time_to_update' +| +| How many seconds between CI regenerating the session ID. +| +| 'sess_regenerate_destroy' +| +| Whether to destroy session data associated with the old session ID +| when auto-regenerating the session ID. When set to FALSE, the data +| will be later deleted by the garbage collector. +| +| Other session cookie settings are shared with the rest of the application, +| except for 'cookie_prefix' and 'cookie_httponly', which are ignored here. | */ -$config['cookie_prefix'] = ""; -$config['cookie_domain'] = ""; -$config['cookie_path'] = "/"; -$config['cookie_secure'] = FALSE; +$config['sess_driver'] = 'database'; +$config['sess_cookie_name'] = 'ci_session'; +$config['sess_samesite'] = 'Lax'; +$config['sess_expiration'] = 7200; +$config['sess_save_path'] = "ci_sessions"; +$config['sess_match_ip'] = FALSE; +$config['sess_time_to_update'] = 300; +$config['sess_regenerate_destroy'] = FALSE; /* |-------------------------------------------------------------------------- -| Global XSS Filtering +| Cookie Related Variables |-------------------------------------------------------------------------- | -| Determines whether the XSS filter is always active when GET, POST or -| COOKIE data is encountered +| 'cookie_prefix' = Set a cookie name prefix if you need to avoid collisions +| 'cookie_domain' = Set to .your-domain.com for site-wide cookies +| 'cookie_path' = Typically will be a forward slash +| 'cookie_secure' = Cookie will only be set if a secure HTTPS connection exists. +| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript) +| 'cookie_samesite' = Cookie's samesite attribute (Lax, Strict or None) +| +| Note: These settings (with the exception of 'cookie_prefix' and +| 'cookie_httponly') will also affect sessions. | */ -$config['global_xss_filtering'] = FALSE; +$config['cookie_prefix'] = ''; +$config['cookie_domain'] = ''; +$config['cookie_path'] = '/'; +$config['cookie_secure'] = FALSE; +$config['cookie_httponly'] = FALSE; +$config['cookie_samesite'] = 'Lax'; /* |-------------------------------------------------------------------------- @@ -296,11 +415,15 @@ $config['global_xss_filtering'] = FALSE; | 'csrf_token_name' = The token name | 'csrf_cookie_name' = The cookie name | 'csrf_expire' = The number in seconds the token should expire. +| 'csrf_regenerate' = Regenerate token on every submission +| 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks */ $config['csrf_protection'] = FALSE; // our controller enables this later $config['csrf_token_name'] = 'csrf_test_name'; $config['csrf_cookie_name'] = 'csrf_cookie_name'; $config['csrf_expire'] = 7200; +$config['csrf_regenerate'] = TRUE; +$config['csrf_exclude_uris'] = array(); /* |-------------------------------------------------------------------------- @@ -312,6 +435,9 @@ $config['csrf_expire'] = 7200; | Even if it does, however, not all browsers support compression | so enable only if you are reasonably sure your visitors can handle it. | +| Only used if zlib.output_compression is turned off in your php.ini. +| Please do not use it together with httpd-level output compression. +| | VERY IMPORTANT: If you are getting a blank page when compression is enabled it | means you are prematurely outputting something to your browser. It could | even be a line of whitespace at the end of one of your scripts. For @@ -326,38 +452,29 @@ $config['compress_output'] = FALSE; | Master Time Reference |-------------------------------------------------------------------------- | -| Options are 'local' or 'gmt'. This pref tells the system whether to use -| your server's local time as the master 'now' reference, or convert it to -| GMT. See the 'date helper' page of the user guide for information -| regarding date handling. +| Options are 'local' or any PHP supported timezone. This preference tells +| the system whether to use your server's local time as the master 'now' +| reference, or convert it to the configured one timezone. See the 'date +| helper' page of the user guide for information regarding date handling. | */ $config['time_reference'] = 'local'; - -/* -|-------------------------------------------------------------------------- -| Rewrite PHP Short Tags -|-------------------------------------------------------------------------- -| -| If your PHP installation does not have short tag support enabled CI -| can rewrite the tags on-the-fly, enabling you to utilize that syntax -| in your view files. Options are TRUE or FALSE (boolean) -| -*/ -$config['rewrite_short_tags'] = FALSE; - - /* |-------------------------------------------------------------------------- | Reverse Proxy IPs |-------------------------------------------------------------------------- | -| If your server is behind a reverse proxy, you must whitelist the proxy IP -| addresses from which CodeIgniter should trust the HTTP_X_FORWARDED_FOR -| header in order to properly identify the visitor's IP address. -| Comma-delimited, e.g. '10.0.1.200,10.0.1.201' +| If your server is behind a reverse proxy, you must whitelist the proxy +| IP addresses from which CodeIgniter should trust headers such as +| HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify +| the visitor's IP address. +| +| You can use both an array or a comma-separated list of proxy addresses, +| as well as specifying whole subnets. Here are a few examples: | +| Comma-separated: '10.0.1.200,192.168.5.0/24' +| Array: array('10.0.1.200', '192.168.5.0/24') */ $config['proxy_ips'] = ''; @@ -431,7 +548,13 @@ if (extension_loaded("ldap")) { ), // Please note that php-ldap converts attributes to lowercase "userid_field" => "uidnumber", // This has to be a unique integer - "username_field" => "uid" // This is the value the user supplies on the login form + "username_field" => "uid", // This is the value the user supplies on the login form + // Optional parameters + // "bind_rdn" => "uid=search-user,cn=users,dc=example,dc=com", // This is the user used to authenticate for searches + // "bind_password" => "***", // This is the password for the search user + // You can optionally filter the LDAP users who are allowed to log in using any valid LDAP filter. %s will be replaced + // by the user name. + // "filter" => "(&(uid=%s)(memberOf=cn=FileBinUsers,cn=groups,dc=example,dc=com))", ); } @@ -478,5 +601,11 @@ if (file_exists(APPPATH.'config/config-local.php')) { include APPPATH.'config/config-local.php'; } -/* End of file config.php */ -/* Location: ./application/config/config.php */ +if (getenv("ENVIRONMENT") === "testsuite" && isset($_SERVER['SERVER_PORT'])) { + $config['base_url'] = 'http://127.0.0.1:'.$_SERVER['SERVER_PORT'].'/'; +} + +if (getenv("ENVIRONMENT") === "testsuite") { + $config['upload_path'] = FCPATH.'testsuite-tmp'; + $config['auth_db']['hashing_options']['cost'] = 5; +} diff --git a/application/config/constants.php b/application/config/constants.php index 1185dbca0..4da7b1af2 100644 --- a/application/config/constants.php +++ b/application/config/constants.php @@ -1,4 +1,17 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + +/* +|-------------------------------------------------------------------------- +| Display Debug backtrace +|-------------------------------------------------------------------------- +| +| If set to TRUE, a backtrace will be displayed along with php errors. If +| error_reporting is disabled, the backtrace will not display, regardless +| of this setting +| +*/ +defined('SHOW_DEBUG_BACKTRACE') OR define('SHOW_DEBUG_BACKTRACE', TRUE); putenv('HOME='.FCPATH); @@ -15,10 +28,10 @@ putenv('HOME='.FCPATH); | always be used to set the mode correctly. | */ -define('FILE_READ_MODE', 0644); -define('FILE_WRITE_MODE', 0666); -define('DIR_READ_MODE', 0755); -define('DIR_WRITE_MODE', 0777); +defined('FILE_READ_MODE') OR define('FILE_READ_MODE', 0644); +defined('FILE_WRITE_MODE') OR define('FILE_WRITE_MODE', 0666); +defined('DIR_READ_MODE') OR define('DIR_READ_MODE', 0755); +defined('DIR_WRITE_MODE') OR define('DIR_WRITE_MODE', 0755); /* |-------------------------------------------------------------------------- @@ -28,16 +41,47 @@ define('DIR_WRITE_MODE', 0777); | These modes are used when working with fopen()/popen() | */ +defined('FOPEN_READ') OR define('FOPEN_READ', 'rb'); +defined('FOPEN_READ_WRITE') OR define('FOPEN_READ_WRITE', 'r+b'); +defined('FOPEN_WRITE_CREATE_DESTRUCTIVE') OR define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care +defined('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE') OR define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care +defined('FOPEN_WRITE_CREATE') OR define('FOPEN_WRITE_CREATE', 'ab'); +defined('FOPEN_READ_WRITE_CREATE') OR define('FOPEN_READ_WRITE_CREATE', 'a+b'); +defined('FOPEN_WRITE_CREATE_STRICT') OR define('FOPEN_WRITE_CREATE_STRICT', 'xb'); +defined('FOPEN_READ_WRITE_CREATE_STRICT') OR define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b'); -define('FOPEN_READ', 'rb'); -define('FOPEN_READ_WRITE', 'r+b'); -define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care -define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care -define('FOPEN_WRITE_CREATE', 'ab'); -define('FOPEN_READ_WRITE_CREATE', 'a+b'); -define('FOPEN_WRITE_CREATE_STRICT', 'xb'); -define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b'); - - -/* End of file constants.php */ -/* Location: ./application/config/constants.php */
\ No newline at end of file +/* +|-------------------------------------------------------------------------- +| Exit Status Codes +|-------------------------------------------------------------------------- +| +| Used to indicate the conditions under which the script is exit()ing. +| While there is no universal standard for error codes, there are some +| broad conventions. Three such conventions are mentioned below, for +| those who wish to make use of them. The CodeIgniter defaults were +| chosen for the least overlap with these conventions, while still +| leaving room for others to be defined in future versions and user +| applications. +| +| The three main conventions used for determining exit status codes +| are as follows: +| +| Standard C/C++ Library (stdlibc): +| https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html +| (This link also contains other GNU-specific conventions) +| BSD sysexits.h: +| https://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits +| Bash scripting: +| http://tldp.org/LDP/abs/html/exitcodes.html +| +*/ +defined('EXIT_SUCCESS') OR define('EXIT_SUCCESS', 0); // no errors +defined('EXIT_ERROR') OR define('EXIT_ERROR', 1); // generic error +defined('EXIT_CONFIG') OR define('EXIT_CONFIG', 3); // configuration error +defined('EXIT_UNKNOWN_FILE') OR define('EXIT_UNKNOWN_FILE', 4); // file not found +defined('EXIT_UNKNOWN_CLASS') OR define('EXIT_UNKNOWN_CLASS', 5); // unknown class +defined('EXIT_UNKNOWN_METHOD') OR define('EXIT_UNKNOWN_METHOD', 6); // unknown class member +defined('EXIT_USER_INPUT') OR define('EXIT_USER_INPUT', 7); // invalid user input +defined('EXIT_DATABASE') OR define('EXIT_DATABASE', 8); // database error +defined('EXIT__AUTO_MIN') OR define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code +defined('EXIT__AUTO_MAX') OR define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code diff --git a/application/config/doctypes.php b/application/config/doctypes.php index f7e1d19a2..59a7991e3 100644 --- a/application/config/doctypes.php +++ b/application/config/doctypes.php @@ -1,15 +1,24 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); $_doctypes = array( - 'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">', - 'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">', - 'xhtml1-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', - 'xhtml1-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">', - 'html5' => '<!DOCTYPE html>', - 'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">', - 'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">', - 'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">' - ); - -/* End of file doctypes.php */ -/* Location: ./application/config/doctypes.php */
\ No newline at end of file + 'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">', + 'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">', + 'xhtml1-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', + 'xhtml1-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">', + 'xhtml-basic11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">', + 'html5' => '<!DOCTYPE html>', + 'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">', + 'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">', + 'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">', + 'mathml1' => '<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">', + 'mathml2' => '<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">', + 'svg10' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">', + 'svg11' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">', + 'svg11-basic' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">', + 'svg11-tiny' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">', + 'xhtml-math-svg-xh' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">', + 'xhtml-math-svg-sh' => '<!DOCTYPE svg:svg PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">', + 'xhtml-rdfa-1' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">', + 'xhtml-rdfa-2' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">' +); diff --git a/application/config/example/config-local.php b/application/config/example/config-local.php index 941c8b119..172f0e1cc 100644 --- a/application/config/example/config-local.php +++ b/application/config/example/config-local.php @@ -6,6 +6,9 @@ * For descriptions of the options please refer to config.php. */ +# URL to the application +$config['base_url'] = ''; + // set this to a 32char random string $config['encryption_key'] = ''; diff --git a/application/config/example/database.php b/application/config/example/database.php index 097e276b3..3f5255766 100644 --- a/application/config/example/database.php +++ b/application/config/example/database.php @@ -1,4 +1,6 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + /* | ------------------------------------------------------------------- | DATABASE CONNECTIVITY SETTINGS @@ -12,18 +14,19 @@ | EXPLANATION OF VARIABLES | ------------------------------------------------------------------- | +| ['dsn'] The full DSN string describe a connection to the database. | ['hostname'] The hostname of your database server. | ['username'] The username used to connect to the database | ['password'] The password used to connect to the database | ['database'] The name of the database you want to connect to -| ['dbdriver'] The database type. ie: mysql. Currently supported: - mysql, mysqli, postgre, odbc, mssql, sqlite, oci8 +| ['dbdriver'] The database driver. e.g.: mysqli. +| Currently supported: +| cubrid, ibase, mssql, mysql, mysqli, oci8, +| odbc, pdo, postgre, sqlite3, sqlsrv | ['dbprefix'] You can add an optional prefix, which will be added -| to the table name when using the Active Record class +| to the table name when using the Query Builder class | ['pconnect'] TRUE/FALSE - Whether to use a persistent connection | ['db_debug'] TRUE/FALSE - Whether database errors should be displayed. -| ['cache_on'] TRUE/FALSE - Enables/disables query caching -| ['cachedir'] The path to the folder where cache files should be stored | ['char_set'] The character set used in communicating with the database | ['dbcollat'] The character collation used in communicating with the database | NOTE: For MySQL and MySQLi databases, this setting is only used @@ -34,44 +37,57 @@ | multi-byte character set and are running versions lower than these. | Sites using Latin-1 or UTF-8 database character set and collation are unaffected. | ['swap_pre'] A default table prefix that should be swapped with the dbprefix -| ['autoinit'] Whether or not to automatically initialize the database. +| ['encrypt'] Whether or not to use an encrypted connection. +| +| 'mysql' (deprecated), 'sqlsrv' and 'pdo/sqlsrv' drivers accept TRUE/FALSE +| 'mysqli' and 'pdo/mysql' drivers accept an array with the following options: +| +| 'ssl_key' - Path to the private key file +| 'ssl_cert' - Path to the public key certificate file +| 'ssl_ca' - Path to the certificate authority file +| 'ssl_capath' - Path to a directory containing trusted CA certificates in PEM format +| 'ssl_cipher' - List of *allowed* ciphers to be used for the encryption, separated by colons (':') +| 'ssl_verify' - TRUE/FALSE; Whether verify the server certificate or not +| +| ['compress'] Whether or not to use client compression (MySQL only) | ['stricton'] TRUE/FALSE - forces 'Strict Mode' connections | - good for ensuring strict SQL while developing +| ['ssl_options'] Used to set various SSL options that can be used when making SSL connections. +| ['failover'] array - A array with 0 or more data for connections if the main should fail. +| ['save_queries'] TRUE/FALSE - Whether to "save" all executed queries. +| NOTE: Disabling this will also effectively disable both +| $this->db->last_query() and profiling of DB queries. +| When you run a query, with this setting set to TRUE (default), +| CodeIgniter will store the SQL statement for debugging purposes. +| However, this may cause high memory usage, especially if you run +| a lot of SQL queries ... disable this to avoid that problem. | | The $active_group variable lets you choose which connection group to | make active. By default there is only one group (the 'default' group). -| -| The $active_record variables lets you determine whether or not to load -| the active record class */ - $active_group = 'default'; -$active_record = TRUE; - -$db['default']['hostname'] = "localhost"; -#$db['default']['port'] = 3306; -$db['default']['username'] = ""; -$db['default']['password'] = ""; -$db['default']['database'] = ""; -$db['default']['dbdriver'] = "mysqli"; -$db['default']['dbprefix'] = ""; -$db['default']['pconnect'] = TRUE; -$db['default']['db_debug'] = TRUE; -$db['default']['cache_on'] = FALSE; -$db['default']['cachedir'] = ""; -$db['default']['char_set'] = "utf8"; -$db['default']['dbcollat'] = "utf8_bin"; -$db['default']['swap_pre'] = ''; -$db['default']['autoinit'] = TRUE; -$db['default']['stricton'] = FALSE; +$db['default'] = array( + 'dsn' => '', + 'hostname' => 'localhost', + 'port' => 3306, + 'username' => '', + 'password' => '', + 'database' => '', + 'dbdriver' => 'mysqli', + 'dbprefix' => '', + 'pconnect' => FALSE, + 'db_debug' => TRUE, + 'char_set' => 'utf8mb4', // if you use postgres, set this to utf8 + 'dbcollat' => 'utf8mb4_bin', // if you use postgres, set this to utf8_bin + 'swap_pre' => '', + 'encrypt' => FALSE, + 'compress' => FALSE, + 'stricton' => TRUE, + 'failover' => array(), + 'save_queries' => TRUE +); if (getenv("ENVIRONMENT") === "testsuite") { - // Change these to your likeing, just make sure they - // don't overlap with the normal settings. $db['default']['database'] = "filebin_testsuite"; $db['default']['dbprefix'] = "testsuite_prefix_"; } - - -/* End of file database.php */ -/* Location: ./application/config/database.php */
\ No newline at end of file diff --git a/application/config/foreign_chars.php b/application/config/foreign_chars.php index 14b0d7373..0231f3592 100644 --- a/application/config/foreign_chars.php +++ b/application/config/foreign_chars.php @@ -1,4 +1,6 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + /* | ------------------------------------------------------------------- | Foreign Characters @@ -14,51 +16,99 @@ $foreign_characters = array( '/Ä/' => 'Ae', '/Ü/' => 'Ue', '/Ö/' => 'Oe', - '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A', - '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a', + '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά|Ả|Ạ|Ầ|Ẫ|Ẩ|Ậ|Ằ|Ắ|Ẵ|Ẳ|Ặ|А/' => 'A', + '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά|ả|ạ|ầ|ấ|ẫ|ẩ|ậ|ằ|ắ|ẵ|ẳ|ặ|а/' => 'a', + '/Б/' => 'B', + '/б/' => 'b', '/Ç|Ć|Ĉ|Ċ|Č/' => 'C', '/ç|ć|ĉ|ċ|č/' => 'c', - '/Ð|Ď|Đ/' => 'D', - '/ð|ď|đ/' => 'd', - '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E', - '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e', - '/Ĝ|Ğ|Ġ|Ģ/' => 'G', - '/ĝ|ğ|ġ|ģ/' => 'g', + '/Д|Δ/' => 'D', + '/д|δ/' => 'd', + '/Ð|Ď|Đ/' => 'Dj', + '/ð|ď|đ/' => 'dj', + '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E', + '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e', + '/Ф/' => 'F', + '/ф/' => 'f', + '/Ĝ|Ğ|Ġ|Ģ|Γ|Г|Ґ/' => 'G', + '/ĝ|ğ|ġ|ģ|γ|г|ґ/' => 'g', '/Ĥ|Ħ/' => 'H', '/ĥ|ħ/' => 'h', - '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I', - '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i', + '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I', + '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i', '/Ĵ/' => 'J', '/ĵ/' => 'j', - '/Ķ/' => 'K', - '/ķ/' => 'k', - '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L', - '/ĺ|ļ|ľ|ŀ|ł/' => 'l', - '/Ñ|Ń|Ņ|Ň/' => 'N', - '/ñ|ń|ņ|ň|ʼn/' => 'n', - '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O', - '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o', - '/Ŕ|Ŗ|Ř/' => 'R', - '/ŕ|ŗ|ř/' => 'r', - '/Ś|Ŝ|Ş|Š/' => 'S', - '/ś|ŝ|ş|š|ſ/' => 's', - '/Ţ|Ť|Ŧ/' => 'T', - '/ţ|ť|ŧ/' => 't', - '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U', - '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u', - '/Ý|Ÿ|Ŷ/' => 'Y', - '/ý|ÿ|ŷ/' => 'y', + '/Θ/' => 'TH', + '/θ/' => 'th', + '/Ķ|Κ|К/' => 'K', + '/ķ|κ|к/' => 'k', + '/Ĺ|Ļ|Ľ|Ŀ|Ł|Λ|Л/' => 'L', + '/ĺ|ļ|ľ|ŀ|ł|λ|л/' => 'l', + '/М/' => 'M', + '/м/' => 'm', + '/Ñ|Ń|Ņ|Ň|Ν|Н/' => 'N', + '/ñ|ń|ņ|ň|ʼn|ν|н/' => 'n', + '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ|Ỏ|Ọ|Ồ|Ố|Ỗ|Ổ|Ộ|Ờ|Ớ|Ỡ|Ở|Ợ|О/' => 'O', + '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ|ỏ|ọ|ồ|ố|ỗ|ổ|ộ|ờ|ớ|ỡ|ở|ợ|о/' => 'o', + '/П/' => 'P', + '/п/' => 'p', + '/Ŕ|Ŗ|Ř|Ρ|Р/' => 'R', + '/ŕ|ŗ|ř|ρ|р/' => 'r', + '/Ś|Ŝ|Ş|Ș|Š|Σ|С/' => 'S', + '/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's', + '/Ț|Ţ|Ť|Ŧ|Τ|Т/' => 'T', + '/ț|ţ|ť|ŧ|τ|т/' => 't', + '/Þ|þ/' => 'th', + '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U', + '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u', + '/Ƴ|Ɏ|Ỵ|Ẏ|Ӳ|Ӯ|Ў|Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y', + '/ẙ|ʏ|ƴ|ɏ|ỵ|ẏ|ӳ|ӯ|ў|ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ|й/' => 'y', + '/В/' => 'V', + '/в/' => 'v', '/Ŵ/' => 'W', '/ŵ/' => 'w', - '/Ź|Ż|Ž/' => 'Z', - '/ź|ż|ž/' => 'z', + '/Φ/' => 'F', + '/φ/' => 'f', + '/Χ/' => 'CH', + '/χ/' => 'ch', + '/Ź|Ż|Ž|Ζ|З/' => 'Z', + '/ź|ż|ž|ζ|з/' => 'z', '/Æ|Ǽ/' => 'AE', - '/ß/'=> 'ss', + '/ß/' => 'ss', '/IJ/' => 'IJ', '/ij/' => 'ij', '/Œ/' => 'OE', - '/ƒ/' => 'f' + '/ƒ/' => 'f', + '/Ξ/' => 'KS', + '/ξ/' => 'ks', + '/Π/' => 'P', + '/π/' => 'p', + '/Β/' => 'V', + '/β/' => 'v', + '/Μ/' => 'M', + '/μ/' => 'm', + '/Ψ/' => 'PS', + '/ψ/' => 'ps', + '/Ё/' => 'Yo', + '/ё/' => 'yo', + '/Є/' => 'Ye', + '/є/' => 'ye', + '/Ї/' => 'Yi', + '/Ж/' => 'Zh', + '/ж/' => 'zh', + '/Х/' => 'Kh', + '/х/' => 'kh', + '/Ц/' => 'Ts', + '/ц/' => 'ts', + '/Ч/' => 'Ch', + '/ч/' => 'ch', + '/Ш/' => 'Sh', + '/ш/' => 'sh', + '/Щ/' => 'Shch', + '/щ/' => 'shch', + '/Ъ|ъ|Ь|ь/' => '', + '/Ю/' => 'Yu', + '/ю/' => 'yu', + '/Я/' => 'Ya', + '/я/' => 'ya' ); - -/* End of file foreign_chars.php */ -/* Location: ./application/config/foreign_chars.php */
\ No newline at end of file diff --git a/application/config/hooks.php b/application/config/hooks.php index a4ad2be6d..79c5c162f 100644 --- a/application/config/hooks.php +++ b/application/config/hooks.php @@ -1,4 +1,6 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + /* | ------------------------------------------------------------------------- | Hooks @@ -6,11 +8,6 @@ | This file lets you define "hooks" to extend CI without hacking the core | files. Please see the user guide for info: | -| http://codeigniter.com/user_guide/general/hooks.html +| https://codeigniter.com/userguide3/general/hooks.html | */ - - - -/* End of file hooks.php */ -/* Location: ./application/config/hooks.php */
\ No newline at end of file diff --git a/application/config/index.html b/application/config/index.html index c942a79ce..bcb7cae34 100644 --- a/application/config/index.html +++ b/application/config/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/config/memcached.php b/application/config/memcached.php new file mode 100644 index 000000000..65a149617 --- /dev/null +++ b/application/config/memcached.php @@ -0,0 +1,19 @@ +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + +/* +| ------------------------------------------------------------------------- +| Memcached settings +| ------------------------------------------------------------------------- +| Your Memcached servers can be specified below. +| +| See: https://codeigniter.com/userguide3/libraries/caching.html#memcached +| +*/ +$config = array( + 'default' => array( + 'hostname' => '127.0.0.1', + 'port' => '11211', + 'weight' => '1', + ), +); diff --git a/application/config/migration.php b/application/config/migration.php index 659907cb8..ffddae2ac 100644 --- a/application/config/migration.php +++ b/application/config/migration.php @@ -1,15 +1,63 @@ -<?php defined('BASEPATH') OR exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + /* |-------------------------------------------------------------------------- | Enable/Disable Migrations |-------------------------------------------------------------------------- | -| Migrations are disabled by default but should be enabled -| whenever you intend to do a schema migration. +| Migrations are disabled by default for security reasons. +| You should enable migrations whenever you intend to do a schema migration +| and disable it back when you're done. | */ $config['migration_enabled'] = true; +/* +|-------------------------------------------------------------------------- +| Migration Type +|-------------------------------------------------------------------------- +| +| Migration file names may be based on a sequential identifier or on +| a timestamp. Options are: +| +| 'sequential' = Sequential migration naming (001_add_blog.php) +| 'timestamp' = Timestamp migration naming (20121031104401_add_blog.php) +| Use timestamp format YYYYMMDDHHIISS. +| +| Note: If this configuration value is missing the Migration library +| defaults to 'sequential' for backward compatibility with CI2. +| +*/ +$config['migration_type'] = 'sequential'; + +/* +|-------------------------------------------------------------------------- +| Migrations table +|-------------------------------------------------------------------------- +| +| This is the name of the table that will store the current migrations state. +| When migrations runs it will store in a database table which migration +| level the system is at. It then compares the migration level in this +| table to the $config['migration_version'] if they are not the same it +| will migrate up. This must be set. +| +*/ +$config['migration_table'] = 'migrations'; + +/* +|-------------------------------------------------------------------------- +| Auto Migrate To Latest +|-------------------------------------------------------------------------- +| +| If this is set to TRUE when you load the migrations class and have +| $config['migration_enabled'] set to TRUE the system will auto migrate +| to your latest migration (whatever $config['migration_version'] is +| set to). This way you do not have to call migrations anywhere else +| in your code to have the latest migration. +| +*/ +$config['migration_auto_latest'] = FALSE; /* |-------------------------------------------------------------------------- @@ -17,12 +65,11 @@ $config['migration_enabled'] = true; |-------------------------------------------------------------------------- | | This is used to set migration version that the file system should be on. -| If you run $this->migration->latest() this is the version that schema will +| If you run $this->migration->current() this is the version that schema will | be upgraded / downgraded to. | */ -$config['migration_version'] = 18; - +$config['migration_version'] = 21; /* |-------------------------------------------------------------------------- @@ -34,8 +81,5 @@ $config['migration_version'] = 18; | Also, writing permission is required within the migrations path. | */ -$config['migration_path'] = APPPATH . 'migrations/'; - +$config['migration_path'] = APPPATH.'migrations/'; -/* End of file migration.php */ -/* Location: ./application/config/migration.php */ diff --git a/application/config/mimes.php b/application/config/mimes.php index 100f7d442..b2e989fea 100644 --- a/application/config/mimes.php +++ b/application/config/mimes.php @@ -1,106 +1,186 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + /* | ------------------------------------------------------------------- | MIME TYPES | ------------------------------------------------------------------- -| This file contains an array of mime types. It is used by the +| This file contains an array of mime types. It is used by the | Upload class to help identify allowed file types. | */ - -$mimes = array( 'hqx' => 'application/mac-binhex40', - 'cpt' => 'application/mac-compactpro', - 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'), - 'bin' => 'application/macbinary', - 'dms' => 'application/octet-stream', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'exe' => array('application/octet-stream', 'application/x-msdownload'), - 'class' => 'application/octet-stream', - 'psd' => 'application/x-photoshop', - 'so' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'oda' => 'application/oda', - 'pdf' => array('application/pdf', 'application/x-download'), - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'mif' => 'application/vnd.mif', - 'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'), - 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'), - 'wbxml' => 'application/wbxml', - 'wmlc' => 'application/wmlc', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'dvi' => 'application/x-dvi', - 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-gzip', - 'php' => 'application/x-httpd-php', - 'php4' => 'application/x-httpd-php', - 'php3' => 'application/x-httpd-php', - 'phtml' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'js' => 'application/x-javascript', - 'swf' => 'application/x-shockwave-flash', - 'sit' => 'application/x-stuffit', - 'tar' => 'application/x-tar', - 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), - 'xhtml' => 'application/xhtml+xml', - 'xht' => 'application/xhtml+xml', - 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'), - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mpga' => 'audio/mpeg', - 'mp2' => 'audio/mpeg', - 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'), - 'aif' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'ram' => 'audio/x-pn-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'ra' => 'audio/x-realaudio', - 'rv' => 'video/vnd.rn-realvideo', - 'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'), - 'bmp' => array('image/bmp', 'image/x-windows-bmp'), - 'gif' => 'image/gif', - 'jpeg' => array('image/jpeg', 'image/pjpeg'), - 'jpg' => array('image/jpeg', 'image/pjpeg'), - 'jpe' => array('image/jpeg', 'image/pjpeg'), - 'png' => array('image/png', 'image/x-png'), - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'css' => 'text/css', - 'html' => 'text/html', - 'htm' => 'text/html', - 'shtml' => 'text/html', - 'txt' => 'text/plain', - 'text' => 'text/plain', - 'log' => array('text/plain', 'text/x-log'), - 'rtx' => 'text/richtext', - 'rtf' => 'text/rtf', - 'xml' => 'text/xml', - 'xsl' => 'text/xml', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'avi' => 'video/x-msvideo', - 'movie' => 'video/x-sgi-movie', - 'doc' => 'application/msword', - 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip'), - 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip'), - 'word' => array('application/msword', 'application/octet-stream'), - 'xl' => 'application/excel', - 'eml' => 'message/rfc822', - 'json' => array('application/json', 'text/json') - ); - - -/* End of file mimes.php */ -/* Location: ./application/config/mimes.php */ +return array( + 'hqx' => array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'), + 'cpt' => 'application/mac-compactpro', + 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'), + 'bin' => array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'), + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => array('application/octet-stream', 'application/x-msdownload'), + 'class' => 'application/octet-stream', + 'psd' => array('application/x-photoshop', 'image/vnd.adobe.photoshop'), + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'), + 'ai' => array('application/pdf', 'application/postscript'), + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'), + 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'), + 'pptx' => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'), + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'php' => array('application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'), + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => array('application/x-javascript', 'text/plain'), + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'), + 'z' => 'application/x-compress', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'), + 'rar' => array('application/x-rar', 'application/rar', 'application/x-rar-compressed'), + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'), + 'aif' => array('audio/x-aiff', 'audio/aiff'), + 'aiff' => array('audio/x-aiff', 'audio/aiff'), + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'), + 'bmp' => array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'), + 'gif' => 'image/gif', + 'jpeg' => array('image/jpeg', 'image/pjpeg'), + 'jpg' => array('image/jpeg', 'image/pjpeg'), + 'jpe' => array('image/jpeg', 'image/pjpeg'), + 'jp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'j2k' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpf' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpg2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpx' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'jpm' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'mj2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'mjp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'), + 'png' => array('image/png', 'image/x-png'), + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'heic' => 'image/heic', + 'heif' => 'image/heif', + 'css' => array('text/css', 'text/plain'), + 'html' => array('text/html', 'text/plain'), + 'htm' => array('text/html', 'text/plain'), + 'shtml' => array('text/html', 'text/plain'), + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => array('text/plain', 'text/x-log'), + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => array('application/xml', 'text/xml', 'text/plain'), + 'xsl' => array('application/xml', 'text/xsl', 'text/xml'), + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'), + 'movie' => 'video/x-sgi-movie', + 'doc' => array('application/msword', 'application/vnd.ms-office'), + 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'), + 'dot' => array('application/msword', 'application/vnd.ms-office'), + 'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'), + 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'), + 'word' => array('application/msword', 'application/octet-stream'), + 'xl' => 'application/excel', + 'eml' => 'message/rfc822', + 'json' => array('application/json', 'text/json'), + 'pem' => array('application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'), + 'p10' => array('application/x-pkcs10', 'application/pkcs10'), + 'p12' => 'application/x-pkcs12', + 'p7a' => 'application/x-pkcs7-signature', + 'p7c' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'), + 'p7m' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'), + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'crt' => array('application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'), + 'crl' => array('application/pkix-crl', 'application/pkcs-crl'), + 'der' => 'application/x-x509-ca-cert', + 'kdb' => 'application/octet-stream', + 'pgp' => 'application/pgp', + 'gpg' => 'application/gpg-keys', + 'sst' => 'application/octet-stream', + 'csr' => 'application/octet-stream', + 'rsa' => 'application/x-pkcs7', + 'cer' => array('application/pkix-cert', 'application/x-x509-ca-cert'), + '3g2' => 'video/3gpp2', + '3gp' => array('video/3gp', 'video/3gpp'), + 'mp4' => 'video/mp4', + 'm4a' => 'audio/x-m4a', + 'f4v' => array('video/mp4', 'video/x-f4v'), + 'flv' => 'video/x-flv', + 'webm' => 'video/webm', + 'aac' => array('audio/x-aac', 'audio/aac'), + 'm4u' => 'application/vnd.mpegurl', + 'm3u' => 'text/plain', + 'xspf' => 'application/xspf+xml', + 'vlc' => 'application/videolan', + 'wmv' => array('video/x-ms-wmv', 'video/x-ms-asf'), + 'au' => 'audio/x-au', + 'ac3' => 'audio/ac3', + 'flac' => 'audio/x-flac', + 'ogg' => array('audio/ogg', 'video/ogg', 'application/ogg'), + 'kmz' => array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'), + 'kml' => array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'), + 'ics' => 'text/calendar', + 'ical' => 'text/calendar', + 'zsh' => 'text/x-scriptzsh', + '7z' => array('application/x-7z-compressed', 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), + '7zip' => array('application/x-7z-compressed', 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), + 'cdr' => array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'), + 'wma' => array('audio/x-ms-wma', 'video/x-ms-asf'), + 'jar' => array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'), + 'svg' => array('image/svg+xml', 'image/svg', 'application/xml', 'text/xml'), + 'vcf' => 'text/x-vcard', + 'srt' => array('text/srt', 'text/plain'), + 'vtt' => array('text/vtt', 'text/plain'), + 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'), + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'otf' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web' +); diff --git a/application/config/profiler.php b/application/config/profiler.php index f8a5b1a1e..3436e931e 100644 --- a/application/config/profiler.php +++ b/application/config/profiler.php @@ -1,4 +1,6 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + /* | ------------------------------------------------------------------------- | Profiler Sections @@ -7,11 +9,6 @@ | data are displayed when the Profiler is enabled. | Please see the user guide for info: | -| http://codeigniter.com/user_guide/general/profiling.html +| https://codeigniter.com/userguide3/general/profiling.html | */ - - - -/* End of file profiler.php */ -/* Location: ./application/config/profiler.php */
\ No newline at end of file diff --git a/application/config/routes.php b/application/config/routes.php index f44f283f0..a5dae1efb 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -1,4 +1,6 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + /* | ------------------------------------------------------------------------- | URI ROUTING @@ -17,13 +19,13 @@ | | Please see the user guide for complete details: | -| http://codeigniter.com/user_guide/general/routing.html +| https://codeigniter.com/userguide3/general/routing.html | | ------------------------------------------------------------------------- | RESERVED ROUTES | ------------------------------------------------------------------------- | -| There area two reserved routes: +| There are three reserved routes: | | $route['default_controller'] = 'welcome'; | @@ -33,20 +35,26 @@ | | $route['404_override'] = 'errors/page_missing'; | -| This route will tell the Router what URI segments to use if those provided -| in the URL cannot be matched to a valid route. +| This route will tell the Router which controller/method to use if those +| provided in the URL cannot be matched to a valid route. +| +| $route['translate_uri_dashes'] = FALSE; +| +| This is not exactly a route, but allows you to automatically route +| controller and method names that contain dashes. '-' isn't a valid +| class or method name character, so it requires translation. +| When you set this option to TRUE, it will replace ALL dashes with +| underscores in the controller and method URI segments. | +| Examples: my-controller/index -> my_controller/index +| my-controller/my-method -> my_controller/my_method */ - -$route['default_controller'] = "file/file_default"; -$route['user/(:any)'] = "user/$1"; -$route['file/multipaste/(:any)'] = "file/multipaste/$1"; -$route['file/(:any)'] = "file/file_default/$1"; -$route['tools/(:any)'] = "tools/$1"; -$route['api/(:any)'] = "api/route/$1"; -$route['(:any)'] = "file/file_default/index/$1"; +$route['default_controller'] = "main"; +$route['user/(.+)'] = "user/$1"; +$route['file/multipaste/(.+)'] = "file/multipaste/$1"; +$route['file/(.+)'] = "main/$1"; +$route['tools/(.+)'] = "tools/$1"; +$route['api/(.+)'] = "api/route/$1"; +$route['(.+)'] = "main/index/$1"; $route['404_override'] = ''; - - -/* End of file routes.php */ -/* Location: ./application/config/routes.php */
\ No newline at end of file +$route['translate_uri_dashes'] = FALSE; diff --git a/application/config/smileys.php b/application/config/smileys.php deleted file mode 100644 index 25d28b2c4..000000000 --- a/application/config/smileys.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); -/* -| ------------------------------------------------------------------- -| SMILEYS -| ------------------------------------------------------------------- -| This file contains an array of smileys for use with the emoticon helper. -| Individual images can be used to replace multiple simileys. For example: -| :-) and :) use the same image replacement. -| -| Please see user guide for more info: -| http://codeigniter.com/user_guide/helpers/smiley_helper.html -| -*/ - -$smileys = array( - -// smiley image name width height alt - - ':-)' => array('grin.gif', '19', '19', 'grin'), - ':lol:' => array('lol.gif', '19', '19', 'LOL'), - ':cheese:' => array('cheese.gif', '19', '19', 'cheese'), - ':)' => array('smile.gif', '19', '19', 'smile'), - ';-)' => array('wink.gif', '19', '19', 'wink'), - ';)' => array('wink.gif', '19', '19', 'wink'), - ':smirk:' => array('smirk.gif', '19', '19', 'smirk'), - ':roll:' => array('rolleyes.gif', '19', '19', 'rolleyes'), - ':-S' => array('confused.gif', '19', '19', 'confused'), - ':wow:' => array('surprise.gif', '19', '19', 'surprised'), - ':bug:' => array('bigsurprise.gif', '19', '19', 'big surprise'), - ':-P' => array('tongue_laugh.gif', '19', '19', 'tongue laugh'), - '%-P' => array('tongue_rolleye.gif', '19', '19', 'tongue rolleye'), - ';-P' => array('tongue_wink.gif', '19', '19', 'tongue wink'), - ':P' => array('raspberry.gif', '19', '19', 'raspberry'), - ':blank:' => array('blank.gif', '19', '19', 'blank stare'), - ':long:' => array('longface.gif', '19', '19', 'long face'), - ':ohh:' => array('ohh.gif', '19', '19', 'ohh'), - ':grrr:' => array('grrr.gif', '19', '19', 'grrr'), - ':gulp:' => array('gulp.gif', '19', '19', 'gulp'), - '8-/' => array('ohoh.gif', '19', '19', 'oh oh'), - ':down:' => array('downer.gif', '19', '19', 'downer'), - ':red:' => array('embarrassed.gif', '19', '19', 'red face'), - ':sick:' => array('sick.gif', '19', '19', 'sick'), - ':shut:' => array('shuteye.gif', '19', '19', 'shut eye'), - ':-/' => array('hmm.gif', '19', '19', 'hmmm'), - '>:(' => array('mad.gif', '19', '19', 'mad'), - ':mad:' => array('mad.gif', '19', '19', 'mad'), - '>:-(' => array('angry.gif', '19', '19', 'angry'), - ':angry:' => array('angry.gif', '19', '19', 'angry'), - ':zip:' => array('zip.gif', '19', '19', 'zipper'), - ':kiss:' => array('kiss.gif', '19', '19', 'kiss'), - ':ahhh:' => array('shock.gif', '19', '19', 'shock'), - ':coolsmile:' => array('shade_smile.gif', '19', '19', 'cool smile'), - ':coolsmirk:' => array('shade_smirk.gif', '19', '19', 'cool smirk'), - ':coolgrin:' => array('shade_grin.gif', '19', '19', 'cool grin'), - ':coolhmm:' => array('shade_hmm.gif', '19', '19', 'cool hmm'), - ':coolmad:' => array('shade_mad.gif', '19', '19', 'cool mad'), - ':coolcheese:' => array('shade_cheese.gif', '19', '19', 'cool cheese'), - ':vampire:' => array('vampire.gif', '19', '19', 'vampire'), - ':snake:' => array('snake.gif', '19', '19', 'snake'), - ':exclaim:' => array('exclaim.gif', '19', '19', 'excaim'), - ':question:' => array('question.gif', '19', '19', 'question') // no comma after last item - - ); - -/* End of file smileys.php */ -/* Location: ./application/config/smileys.php */
\ No newline at end of file diff --git a/application/config/user_agents.php b/application/config/user_agents.php index e2d3c3af0..21251f46f 100644 --- a/application/config/user_agents.php +++ b/application/config/user_agents.php @@ -1,178 +1,223 @@ -<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + /* | ------------------------------------------------------------------- | USER AGENT TYPES | ------------------------------------------------------------------- -| This file contains four arrays of user agent data. It is used by the +| This file contains four arrays of user agent data. It is used by the | User Agent Class to help identify browser, platform, robot, and -| mobile device data. The array keys are used to identify the device +| mobile device data. The array keys are used to identify the device | and the array values are used to set the actual name of the item. -| */ - -$platforms = array ( - 'windows nt 6.0' => 'Windows Longhorn', - 'windows nt 5.2' => 'Windows 2003', - 'windows nt 5.0' => 'Windows 2000', - 'windows nt 5.1' => 'Windows XP', - 'windows nt 4.0' => 'Windows NT 4.0', - 'winnt4.0' => 'Windows NT 4.0', - 'winnt 4.0' => 'Windows NT', - 'winnt' => 'Windows NT', - 'windows 98' => 'Windows 98', - 'win98' => 'Windows 98', - 'windows 95' => 'Windows 95', - 'win95' => 'Windows 95', - 'windows' => 'Unknown Windows OS', - 'os x' => 'Mac OS X', - 'ppc mac' => 'Power PC Mac', - 'freebsd' => 'FreeBSD', - 'ppc' => 'Macintosh', - 'linux' => 'Linux', - 'debian' => 'Debian', - 'sunos' => 'Sun Solaris', - 'beos' => 'BeOS', - 'apachebench' => 'ApacheBench', - 'aix' => 'AIX', - 'irix' => 'Irix', - 'osf' => 'DEC OSF', - 'hp-ux' => 'HP-UX', - 'netbsd' => 'NetBSD', - 'bsdi' => 'BSDi', - 'openbsd' => 'OpenBSD', - 'gnu' => 'GNU/Linux', - 'unix' => 'Unknown Unix OS' - ); +$platforms = array( + 'windows nt 10.0' => 'Windows 10', + 'windows nt 6.3' => 'Windows 8.1', + 'windows nt 6.2' => 'Windows 8', + 'windows nt 6.1' => 'Windows 7', + 'windows nt 6.0' => 'Windows Vista', + 'windows nt 5.2' => 'Windows 2003', + 'windows nt 5.1' => 'Windows XP', + 'windows nt 5.0' => 'Windows 2000', + 'windows nt 4.0' => 'Windows NT 4.0', + 'winnt4.0' => 'Windows NT 4.0', + 'winnt 4.0' => 'Windows NT', + 'winnt' => 'Windows NT', + 'windows 98' => 'Windows 98', + 'win98' => 'Windows 98', + 'windows 95' => 'Windows 95', + 'win95' => 'Windows 95', + 'windows phone' => 'Windows Phone', + 'windows' => 'Unknown Windows OS', + 'android' => 'Android', + 'blackberry' => 'BlackBerry', + 'iphone' => 'iOS', + 'ipad' => 'iOS', + 'ipod' => 'iOS', + 'os x' => 'Mac OS X', + 'ppc mac' => 'Power PC Mac', + 'freebsd' => 'FreeBSD', + 'ppc' => 'Macintosh', + 'linux' => 'Linux', + 'debian' => 'Debian', + 'sunos' => 'Sun Solaris', + 'beos' => 'BeOS', + 'apachebench' => 'ApacheBench', + 'aix' => 'AIX', + 'irix' => 'Irix', + 'osf' => 'DEC OSF', + 'hp-ux' => 'HP-UX', + 'netbsd' => 'NetBSD', + 'bsdi' => 'BSDi', + 'openbsd' => 'OpenBSD', + 'gnu' => 'GNU/Linux', + 'unix' => 'Unknown Unix OS', + 'symbian' => 'Symbian OS' +); // The order of this array should NOT be changed. Many browsers return // multiple browser types so we want to identify the sub-type first. $browsers = array( - 'Flock' => 'Flock', - 'Chrome' => 'Chrome', - 'Opera' => 'Opera', - 'MSIE' => 'Internet Explorer', - 'Internet Explorer' => 'Internet Explorer', - 'Shiira' => 'Shiira', - 'Firefox' => 'Firefox', - 'Chimera' => 'Chimera', - 'Phoenix' => 'Phoenix', - 'Firebird' => 'Firebird', - 'Camino' => 'Camino', - 'Netscape' => 'Netscape', - 'OmniWeb' => 'OmniWeb', - 'Safari' => 'Safari', - 'Mozilla' => 'Mozilla', - 'Konqueror' => 'Konqueror', - 'icab' => 'iCab', - 'Lynx' => 'Lynx', - 'Links' => 'Links', - 'hotjava' => 'HotJava', - 'amaya' => 'Amaya', - 'IBrowse' => 'IBrowse' - ); + 'OPR' => 'Opera', + 'Flock' => 'Flock', + 'Edge' => 'Edge', + 'Chrome' => 'Chrome', + // Opera 10+ always reports Opera/9.80 and appends Version/<real version> to the user agent string + 'Opera.*?Version' => 'Opera', + 'Opera' => 'Opera', + 'MSIE' => 'Internet Explorer', + 'Internet Explorer' => 'Internet Explorer', + 'Trident.* rv' => 'Internet Explorer', + 'Shiira' => 'Shiira', + 'Firefox' => 'Firefox', + 'Chimera' => 'Chimera', + 'Phoenix' => 'Phoenix', + 'Firebird' => 'Firebird', + 'Camino' => 'Camino', + 'Netscape' => 'Netscape', + 'OmniWeb' => 'OmniWeb', + 'Safari' => 'Safari', + 'Mozilla' => 'Mozilla', + 'Konqueror' => 'Konqueror', + 'icab' => 'iCab', + 'Lynx' => 'Lynx', + 'Links' => 'Links', + 'hotjava' => 'HotJava', + 'amaya' => 'Amaya', + 'IBrowse' => 'IBrowse', + 'Maxthon' => 'Maxthon', + 'Ubuntu' => 'Ubuntu Web Browser', + 'Vivaldi' => 'Vivaldi' +); $mobiles = array( - // legacy array, old values commented out - 'mobileexplorer' => 'Mobile Explorer', -// 'openwave' => 'Open Wave', -// 'opera mini' => 'Opera Mini', -// 'operamini' => 'Opera Mini', -// 'elaine' => 'Palm', - 'palmsource' => 'Palm', -// 'digital paths' => 'Palm', -// 'avantgo' => 'Avantgo', -// 'xiino' => 'Xiino', - 'palmscape' => 'Palmscape', -// 'nokia' => 'Nokia', -// 'ericsson' => 'Ericsson', -// 'blackberry' => 'BlackBerry', -// 'motorola' => 'Motorola' + // legacy array, old values commented out + 'mobileexplorer' => 'Mobile Explorer', +// 'openwave' => 'Open Wave', +// 'opera mini' => 'Opera Mini', +// 'operamini' => 'Opera Mini', +// 'elaine' => 'Palm', + 'palmsource' => 'Palm', +// 'digital paths' => 'Palm', +// 'avantgo' => 'Avantgo', +// 'xiino' => 'Xiino', + 'palmscape' => 'Palmscape', +// 'nokia' => 'Nokia', +// 'ericsson' => 'Ericsson', +// 'blackberry' => 'BlackBerry', +// 'motorola' => 'Motorola' - // Phones and Manufacturers - 'motorola' => "Motorola", - 'nokia' => "Nokia", - 'palm' => "Palm", - 'iphone' => "Apple iPhone", - 'ipad' => "iPad", - 'ipod' => "Apple iPod Touch", - 'sony' => "Sony Ericsson", - 'ericsson' => "Sony Ericsson", - 'blackberry' => "BlackBerry", - 'cocoon' => "O2 Cocoon", - 'blazer' => "Treo", - 'lg' => "LG", - 'amoi' => "Amoi", - 'xda' => "XDA", - 'mda' => "MDA", - 'vario' => "Vario", - 'htc' => "HTC", - 'samsung' => "Samsung", - 'sharp' => "Sharp", - 'sie-' => "Siemens", - 'alcatel' => "Alcatel", - 'benq' => "BenQ", - 'ipaq' => "HP iPaq", - 'mot-' => "Motorola", - 'playstation portable' => "PlayStation Portable", - 'hiptop' => "Danger Hiptop", - 'nec-' => "NEC", - 'panasonic' => "Panasonic", - 'philips' => "Philips", - 'sagem' => "Sagem", - 'sanyo' => "Sanyo", - 'spv' => "SPV", - 'zte' => "ZTE", - 'sendo' => "Sendo", + // Phones and Manufacturers + 'motorola' => 'Motorola', + 'nokia' => 'Nokia', + 'nexus' => 'Nexus', + 'palm' => 'Palm', + 'iphone' => 'Apple iPhone', + 'ipad' => 'iPad', + 'ipod' => 'Apple iPod Touch', + 'sony' => 'Sony Ericsson', + 'ericsson' => 'Sony Ericsson', + 'blackberry' => 'BlackBerry', + 'cocoon' => 'O2 Cocoon', + 'blazer' => 'Treo', + 'lg' => 'LG', + 'amoi' => 'Amoi', + 'xda' => 'XDA', + 'mda' => 'MDA', + 'vario' => 'Vario', + 'htc' => 'HTC', + 'samsung' => 'Samsung', + 'sharp' => 'Sharp', + 'sie-' => 'Siemens', + 'alcatel' => 'Alcatel', + 'benq' => 'BenQ', + 'ipaq' => 'HP iPaq', + 'mot-' => 'Motorola', + 'playstation portable' => 'PlayStation Portable', + 'playstation 3' => 'PlayStation 3', + 'playstation vita' => 'PlayStation Vita', + 'hiptop' => 'Danger Hiptop', + 'nec-' => 'NEC', + 'panasonic' => 'Panasonic', + 'philips' => 'Philips', + 'sagem' => 'Sagem', + 'sanyo' => 'Sanyo', + 'spv' => 'SPV', + 'zte' => 'ZTE', + 'sendo' => 'Sendo', + 'nintendo dsi' => 'Nintendo DSi', + 'nintendo ds' => 'Nintendo DS', + 'nintendo 3ds' => 'Nintendo 3DS', + 'wii' => 'Nintendo Wii', + 'open web' => 'Open Web', + 'openweb' => 'OpenWeb', + 'meizu' => 'Meizu', + 'huawei' => 'Huawei', + 'xiaomi' => 'Xiaomi', + 'oppo' => 'Oppo', + 'vivo' => 'Vivo', + 'infinix' => 'Infinix', - // Operating Systems - 'symbian' => "Symbian", - 'SymbianOS' => "SymbianOS", - 'elaine' => "Palm", - 'palm' => "Palm", - 'series60' => "Symbian S60", - 'windows ce' => "Windows CE", + // Operating Systems + 'android' => 'Android', + 'symbian' => 'Symbian', + 'SymbianOS' => 'SymbianOS', + 'elaine' => 'Palm', + 'series60' => 'Symbian S60', + 'windows ce' => 'Windows CE', - // Browsers - 'obigo' => "Obigo", - 'netfront' => "Netfront Browser", - 'openwave' => "Openwave Browser", - 'mobilexplorer' => "Mobile Explorer", - 'operamini' => "Opera Mini", - 'opera mini' => "Opera Mini", + // Browsers + 'obigo' => 'Obigo', + 'netfront' => 'Netfront Browser', + 'openwave' => 'Openwave Browser', + 'mobilexplorer' => 'Mobile Explorer', + 'operamini' => 'Opera Mini', + 'opera mini' => 'Opera Mini', + 'opera mobi' => 'Opera Mobile', + 'fennec' => 'Firefox Mobile', - // Other - 'digital paths' => "Digital Paths", - 'avantgo' => "AvantGo", - 'xiino' => "Xiino", - 'novarra' => "Novarra Transcoder", - 'vodafone' => "Vodafone", - 'docomo' => "NTT DoCoMo", - 'o2' => "O2", + // Other + 'digital paths' => 'Digital Paths', + 'avantgo' => 'AvantGo', + 'xiino' => 'Xiino', + 'novarra' => 'Novarra Transcoder', + 'vodafone' => 'Vodafone', + 'docomo' => 'NTT DoCoMo', + 'o2' => 'O2', - // Fallback - 'mobile' => "Generic Mobile", - 'wireless' => "Generic Mobile", - 'j2me' => "Generic Mobile", - 'midp' => "Generic Mobile", - 'cldc' => "Generic Mobile", - 'up.link' => "Generic Mobile", - 'up.browser' => "Generic Mobile", - 'smartphone' => "Generic Mobile", - 'cellphone' => "Generic Mobile" - ); + // Fallback + 'mobile' => 'Generic Mobile', + 'wireless' => 'Generic Mobile', + 'j2me' => 'Generic Mobile', + 'midp' => 'Generic Mobile', + 'cldc' => 'Generic Mobile', + 'up.link' => 'Generic Mobile', + 'up.browser' => 'Generic Mobile', + 'smartphone' => 'Generic Mobile', + 'cellphone' => 'Generic Mobile' +); // There are hundreds of bots but these are the most common. $robots = array( - 'googlebot' => 'Googlebot', - 'msnbot' => 'MSNBot', - 'slurp' => 'Inktomi Slurp', - 'yahoo' => 'Yahoo', - 'askjeeves' => 'AskJeeves', - 'fastcrawler' => 'FastCrawler', - 'infoseek' => 'InfoSeek Robot 1.0', - 'lycos' => 'Lycos' - ); - -/* End of file user_agents.php */ -/* Location: ./application/config/user_agents.php */
\ No newline at end of file + 'googlebot' => 'Googlebot', + 'msnbot' => 'MSNBot', + 'baiduspider' => 'Baiduspider', + 'bingbot' => 'Bing', + 'slurp' => 'Inktomi Slurp', + 'yahoo' => 'Yahoo', + 'ask jeeves' => 'Ask Jeeves', + 'fastcrawler' => 'FastCrawler', + 'infoseek' => 'InfoSeek Robot 1.0', + 'lycos' => 'Lycos', + 'yandex' => 'YandexBot', + 'mediapartners-google' => 'MediaPartners Google', + 'CRAZYWEBCRAWLER' => 'Crazy Webcrawler', + 'adsbot-google' => 'AdsBot Google', + 'feedfetcher-google' => 'Feedfetcher Google', + 'curious george' => 'Curious George', + 'ia_archiver' => 'Alexa Crawler', + 'MJ12bot' => 'Majestic-12', + 'Uptimebot' => 'Uptimebot', + 'UptimeRobot' => 'UptimeRobot' +); diff --git a/application/controllers/api.php b/application/controllers/Api.php index 9540f1ff7..b41f090dd 100644 --- a/application/controllers/api.php +++ b/application/controllers/Api.php @@ -24,7 +24,7 @@ class Api extends MY_Controller { $function = $this->uri->segment(4); if (!preg_match("/^v([0-9]+)(.[0-9]+){0,2}$/", $requested_version)) { - throw new \exceptions\PublicApiException("api/invalid-version", "Invalid API version requested"); + throw new \exceptions\UserInputException("api/invalid-version", "Invalid API version requested"); } $requested_version = substr($requested_version, 1); @@ -32,11 +32,11 @@ class Api extends MY_Controller { $major = intval(explode(".", $requested_version)[0]); if (!preg_match("/^[a-zA-Z-_]+$/", $controller)) { - throw new \exceptions\PublicApiException("api/invalid-endpoint", "Invalid endpoint requested"); + throw new \exceptions\UserInputException("api/invalid-endpoint", "Invalid endpoint requested"); } if (!preg_match("/^[a-zA-Z-_]+$/", $function)) { - throw new \exceptions\PublicApiException("api/invalid-endpoint", "Invalid endpoint requested"); + throw new \exceptions\UserInputException("api/invalid-endpoint", "Invalid endpoint requested"); } $namespace = "controllers\\api\\v".$major; @@ -44,23 +44,50 @@ class Api extends MY_Controller { $class_info = $namespace."\\api_info"; if (!class_exists($class_info) || version_compare($class_info::get_version(), $requested_version, "<")) { - throw new \exceptions\PublicApiException("api/version-not-supported", "Requested API version is not supported"); + throw new \exceptions\UserInputException("api/version-not-supported", "Requested API version is not supported"); } if (!class_exists($class)) { - throw new \exceptions\PublicApiException("api/unknown-endpoint", "Unknown endpoint requested"); + throw new \exceptions\UserInputException("api/unknown-endpoint", "Unknown endpoint requested"); } $c= new $class; - if (!method_exists($c, $function)) { - throw new \exceptions\PublicApiException("api/unknown-endpoint", "Unknown endpoint requested"); + if (!method_exists($c, $function) || !is_callable([$c, $function])) { + throw new \exceptions\UserInputException("api/unknown-endpoint", "Unknown endpoint requested"); } - return send_json_reply($c->$function()); + return $this->send_json_reply($c->$function()); } catch (\exceptions\PublicApiException $e) { - return send_json_error_reply($e->get_error_id(), $e->getMessage(), $e->get_data()); + return $this->send_json_error_reply($e->get_error_id(), $e->getMessage(), $e->get_data()); } catch (\Exception $e) { \libraries\ExceptionHandler::log_exception($e); - return send_json_error_reply("internal-error", "An unhandled internal server error occured"); + return $this->send_json_error_reply("internal-error", "An unhandled internal server error occured"); } } + + private function send_json_reply($array, $status = "success") { + $reply = array(); + $reply["status"] = $status; + $reply["data"] = $array; + + $CI =& get_instance(); + $CI->output->set_content_type('application/json'); + $CI->output->set_output(json_encode($reply)); + } + + private function send_json_error_reply($error_id, $message, $array = null, $status_code = 400) { + $reply = array(); + $reply["status"] = "error"; + $reply["error_id"] = $error_id; + $reply["message"] = $message; + + if ($array !== null) { + $reply["data"] = $array; + } + + $CI =& get_instance(); + $CI->output->set_status_header($status_code); + $CI->output->set_content_type('application/json'); + $CI->output->set_output(json_encode($reply)); + } + } diff --git a/application/controllers/file/file_default.php b/application/controllers/Main.php index f4f106990..2cfaacb16 100644 --- a/application/controllers/file/file_default.php +++ b/application/controllers/Main.php @@ -7,7 +7,7 @@ * */ -class File_default extends MY_Controller { +class Main extends MY_Controller { function __construct() { @@ -19,14 +19,14 @@ class File_default extends MY_Controller { function index() { - if ($this->input->is_cli_request()) { - $this->load->library("../controllers/tools"); - return $this->tools->index(); + if (is_cli()) { + output_cli_usage(); + exit; } // Try to guess what the user would like to do. $id = $this->uri->segment(1); - if (strpos($id, "m-") === 0 && $this->mmultipaste->id_exists($id)) { + if (isset($id) && strpos($id, "m-") === 0 && $this->mmultipaste->id_exists($id)) { $this->_download(); } elseif ($id != "file" && $this->mfile->id_exists($id)) { $this->_download(); @@ -37,6 +37,28 @@ class File_default extends MY_Controller { } } + private function _handle_etag($etag) + { + $etag = strtolower($etag); + $modified = true; + + if(isset($_SERVER['HTTP_IF_NONE_MATCH'])) { + $oldtag = trim(strtolower($_SERVER['HTTP_IF_NONE_MATCH']), '"'); + if($oldtag == $etag) { + $modified = false; + } else { + $modified = true; + } + } + + header('Etag: "'.$etag.'"'); + + if (!$modified) { + header("HTTP/1.1 304 Not Modified"); + exit(); + } + } + /** * Generate a page title of the format "Multipaste - $filename, $filename, … (N more)". * This mainly helps in IRC channels to quickly determine what is in a multipaste. @@ -74,8 +96,9 @@ class File_default extends MY_Controller { function _download() { + session_write_close(); $id = $this->uri->segment(1); - $lexer = urldecode($this->uri->segment(2)); + $lexer = urldecode($this->uri->segment(2) ?? ''); $is_multipaste = false; if ($this->mmultipaste->id_exists($id)) { @@ -120,7 +143,7 @@ class File_default extends MY_Controller { break; case "qr": - handle_etag($etag); + $this->_handle_etag($etag); header("Content-disposition: inline; filename=\"".$id."_qr.png\"\n"); header("Content-Type: image/png\n"); $qr = new \Endroid\QrCode\QrCode(); @@ -155,7 +178,7 @@ class File_default extends MY_Controller { // user wants the plain file if ($lexer == 'plain') { assert(count($files) == 1); - handle_etag($etag); + $this->_handle_etag($etag); $filedata = $files[0]; $filepath = $this->mfile->file($filedata["data_id"]); @@ -171,7 +194,7 @@ class File_default extends MY_Controller { // autodetect the lexer for highlighting if the URL contains a / after the ID (/ID/) // /ID/lexer disables autodetection - $autodetect_lexer = !$lexer && substr_count(ltrim($this->uri->uri_string(), "/"), '/') >= 1; + $autodetect_lexer = !$lexer && preg_match('/^[^?]*\/(\?.*)?$/', $_SERVER['REQUEST_URI']); $autodetect_lexer = $is_multipaste ? true : $autodetect_lexer; if ($autodetect_lexer) { $lexer = $pygments->autodetect_lexer(); @@ -186,14 +209,19 @@ class File_default extends MY_Controller { $filesize_too_big = filesize($file) > $this->config->item('upload_max_text_size'); + if ($lexer == "asciinema") { + $output_cache->add(array("filedata" => $filedata), "file/fragments/asciinema-player"); + continue; + } + if (!$can_highlight || $filesize_too_big || !$lexer) { if (!$is_multipaste) { // prevent javascript from being executed and forbid frames // this should allow us to serve user submitted HTML content without huge security risks foreach (array("X-WebKit-CSP", "X-Content-Security-Policy", "Content-Security-Policy") as $header_name) { - header("$header_name: default-src 'none'; img-src *; media-src *; font-src *; style-src 'unsafe-inline' *; script-src 'none'; object-src *; frame-src 'none'; "); + header("$header_name: default-src 'none'; img-src data: *; media-src *; font-src data: *; style-src 'unsafe-inline' *; script-src 'none'; object-src *; frame-src 'none'; "); } - handle_etag($etag); + $this->_handle_etag($etag); $this->ddownload->serveFile($file, $filedata["filename"], $filedata["mimetype"]); exit(); } else { @@ -221,14 +249,10 @@ class File_default extends MY_Controller { } } - if ($lexer == "asciinema") { - $output_cache->add(array("filedata" => $filedata), "file/fragments/asciinema-player"); - } else { - $output_cache->add_function(function() use ($output_cache, $filedata, $lexer, $is_multipaste) { - $renderer = new \service\renderer($output_cache, $this->mfile, $this->data); - $renderer->highlight_file($filedata, $lexer, $is_multipaste); - }); - } + $output_cache->add_function(function() use ($output_cache, $filedata, $lexer, $is_multipaste) { + $renderer = new \service\renderer($output_cache, $this->mfile, $this->data); + $renderer->highlight_file($filedata, $lexer, $is_multipaste); + }); } // TODO: move lexers json to dedicated URL @@ -376,7 +400,7 @@ class File_default extends MY_Controller { $this->muser->require_session(); // keep the upload but require the user to login $last_upload = $this->session->userdata("last_upload"); - if ($last_upload === false) { + if ($last_upload === NULL) { $last_upload = array( "ids" => [], "lexer" => "", @@ -433,7 +457,7 @@ class File_default extends MY_Controller { $this->data['title'] .= ' - Upload'; $this->data['small_upload_size'] = $this->config->item('small_upload_size'); $this->data['max_upload_size'] = $this->config->item('upload_max_size'); - $this->data['upload_max_age'] = $this->config->item('upload_max_age')/60/60/24; + $this->data['upload_max_age'] = $this->config->item('upload_max_age'); $this->data['username'] = $this->muser->get_username(); @@ -441,10 +465,12 @@ class File_default extends MY_Controller { if ($repaste_id) { $filedata = $this->mfile->get_filedata($repaste_id); - - $pygments = new \libraries\Pygments($this->mfile->file($filedata["data_id"]), $filedata["mimetype"], $filedata["filename"]); - if ($filedata !== false && $pygments->can_highlight()) { - $this->data["textarea_content"] = file_get_contents($this->mfile->file($filedata["data_id"])); + if ($filedata !== false) { + $pygments = new \libraries\Pygments($this->mfile->file($filedata["data_id"]), $filedata["mimetype"], $filedata["filename"]); + if ($pygments->can_highlight()) { + $this->data["textarea_filename"] = $filedata["filename"]; + $this->data["textarea_content"] = file_get_contents($this->mfile->file($filedata["data_id"])); + } } } @@ -460,15 +486,9 @@ class File_default extends MY_Controller { $this->load->view('footer', $this->data); } - // Allow CLI clients to query the server for the maxium filesize so they can - // stop the upload before wasting time and bandwith - function get_max_size() - { - echo $this->config->item('upload_max_size'); - } - function thumbnail() { + session_write_close(); $id = $this->uri->segment(3); if (!$this->mfile->valid_id($id)) { @@ -476,7 +496,7 @@ class File_default extends MY_Controller { } $etag = "$id-thumb"; - handle_etag($etag); + $this->_handle_etag($etag); $thumb_size = 150; $cache_timeout = 60*60*24*30; # 1 month @@ -517,7 +537,6 @@ class File_default extends MY_Controller { (files.user = '.$this->db->escape($user).') AND ( mimetype LIKE \'image%\' - OR mimetype IN (\'application/pdf\') )', null, false) ->order_by('date', 'desc') ->get()->result_array(); @@ -566,7 +585,7 @@ class File_default extends MY_Controller { private function _append_multipaste_queue() { $ids = $this->input->post_array("ids"); - if ($ids === false) { + if ($ids === null) { $ids = []; } @@ -592,9 +611,6 @@ class File_default extends MY_Controller { ); $this->data['title'] .= ' - Upload history'; - foreach($fields as $length_key => $value) { - $lengths[$length_key] = mb_strlen($value); - } foreach ($history["multipaste_items"] as $key => $item) { $size = 0; @@ -645,7 +661,6 @@ class File_default extends MY_Controller { } $this->data["items"] = $history["items"]; - $this->data["lengths"] = $lengths; $this->data["fields"] = $fields; $this->data["total_size"] = format_bytes($history["total_size"]); @@ -778,7 +793,7 @@ class File_default extends MY_Controller { $last_upload = $this->session->userdata("last_upload"); - if ($last_upload === false) { + if ($last_upload === NULL) { throw new \exceptions\PublicApiException("file/claim_id/last_upload-failed", "Failed to get last upload data, unable to claim uploads"); } @@ -829,23 +844,7 @@ class File_default extends MY_Controller { { $this->_require_cli_request(); - $tarball_dir = $this->config->item("upload_path")."/special/multipaste-tarballs"; - if (is_dir($tarball_dir)) { - $tarball_cache_time = $this->config->item("tarball_cache_time"); - $it = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($tarball_dir), RecursiveIteratorIterator::SELF_FIRST); - - foreach ($it as $file) { - if ($file->isFile()) { - if ($file->getMTime() < time() - $tarball_cache_time) { - $lock = fopen($file, "r+"); - flock($lock, LOCK_EX); - unlink($file); - flock($lock, LOCK_UN); - } - } - } - } + \service\files::clean_multipaste_tarballs(); $oldest_time = (time() - $this->config->item('upload_max_age')); $oldest_session_time = (time() - $this->config->item("sess_expiration")); @@ -887,54 +886,9 @@ class File_default extends MY_Controller { { $this->_require_cli_request(); - $upload_path = $this->config->item("upload_path"); - $outer_dh = opendir($upload_path); - - while (($dir = readdir($outer_dh)) !== false) { - if (!is_dir($upload_path."/".$dir) || $dir == ".." || $dir == "." || $dir == "special") { - continue; - } - - $dh = opendir($upload_path."/".$dir); - - $empty = true; - - while (($file = readdir($dh)) !== false) { - if ($file == ".." || $file == ".") { - continue; - } - - try { - list($hash, $storage_id) = explode("-", $file); - } catch (\ErrorException $e) { - unlink($upload_path."/".$dir."/".$file); - continue; - } - - $query = $this->db->select('hash, id') - ->from('file_storage') - ->where('hash', $hash) - ->where('id', $storage_id) - ->limit(1) - ->get()->row_array(); - - if (empty($query)) { - $this->mfile->delete_data_id($file); - } else { - $empty = false; - } - } - - closedir($dh); - - if ($empty && file_exists($upload_path."/".$dir)) { - rmdir($upload_path."/".$dir); - } - } - closedir($outer_dh); - - // TODO: clean up special/multipaste-tarballs? cron() already expires - // after a rather short time, do we really need this here then? + \service\files::remove_files_missing_in_db(); + \service\files::remove_files_missing_on_disk(); + \service\files::clean_multipaste_tarballs(); } function nuke_id() @@ -971,11 +925,14 @@ class File_default extends MY_Controller { foreach ($query as $key => $item) { $data_id = $item["hash"].'-'.$item['id']; - $mimetype = mimetype($this->mfile->file($data_id)); + $filepath = $this->mfile->file($data_id); + $mimetype = mimetype($filepath); + $filesize = filesize($filepath); $this->db->where('id', $item['id']) ->set(array( 'mimetype' => $mimetype, + 'filesize' => $filesize, )) ->update('file_storage'); } diff --git a/application/controllers/tools.php b/application/controllers/Tools.php index c3209e8f7..040f0c711 100644 --- a/application/controllers/tools.php +++ b/application/controllers/Tools.php @@ -19,26 +19,24 @@ class Tools extends MY_Controller { function index() { - echo "php index.php <controller> <function> [arguments]\n"; - echo "\n"; - echo "Functions:\n"; - echo " file cron Cronjob\n"; - echo " file nuke_id <ID> Nukes all IDs sharing the same hash\n"; - echo " user cron Cronjob\n"; - echo " tools update_database Update/Initialise the database\n"; - echo "\n"; - echo "Functions that shouldn't have to be run:\n"; - echo " file clean_stale_files Remove files without database entries\n"; - echo " file update_file_metadata Update filesize and mimetype in database\n"; + output_cli_usage(); exit; } function update_database() { $this->load->library('migration'); - if ( ! $this->migration->current()) { + $upgraded = $this->migration->current(); + if ( ! $upgraded) { throw new \exceptions\ApiException("tools/update_database/migration-error", $this->migration->error_string()); } + + if ($upgraded === true) { + echo "Already at latest database version. No upgrade performed\n"; + return; + } + + echo "Database upgraded sucessfully to version: $upgraded\n"; } function drop_all_tables() @@ -107,7 +105,10 @@ class Tools extends MY_Controller { function generate_coverage_report() { include APPPATH."../vendor/autoload.php"; - $coverage = new \SebastianBergmann\CodeCoverage\CodeCoverage(); + $filter = new \SebastianBergmann\CodeCoverage\Filter; + $coverage = new \SebastianBergmann\CodeCoverage\CodeCoverage( + (new \SebastianBergmann\CodeCoverage\Driver\Selector)->forLineCoverage($filter), + $filter); foreach (glob(FCPATH."/test-coverage-data/*") as $file) { $coverage->merge(unserialize(file_get_contents($file))); } diff --git a/application/controllers/user.php b/application/controllers/User.php index d87b544c7..43b5040b3 100644 --- a/application/controllers/user.php +++ b/application/controllers/User.php @@ -16,7 +16,7 @@ class User extends MY_Controller { function index() { - if ($this->input->is_cli_request()) { + if (is_cli()) { $this->load->library("../controllers/tools"); return $this->tools->index(); } @@ -45,7 +45,7 @@ class User extends MY_Controller { $redirect_uri = $this->input->get("redirect_uri"); $this->muser->require_session(); - if (!preg_match('/^[0-9a-zA-Z\/_-]*$/', $redirect_uri)) { + if (!isset($redirect_uri) || !preg_match('/^[0-9a-zA-Z\/_-]*$/', $redirect_uri)) { $redirect_uri = '/'; } @@ -55,7 +55,7 @@ class User extends MY_Controller { $this->data['redirect_uri'] = $redirect_uri; - if ($this->input->post('process') !== false) { + if ($this->input->post('process') !== null) { $username = $this->input->post('username'); $password = $this->input->post('password'); @@ -82,10 +82,10 @@ class User extends MY_Controller { $userid = $this->muser->get_userid(); $comment = $this->input->post("comment"); - $comment = $comment === false ? "" : $comment; + $comment = $comment === null ? "" : $comment; $access_level = $this->input->post("access_level"); - if ($access_level === false) { + if ($access_level === null) { $access_level = "apikey"; } @@ -128,26 +128,20 @@ class User extends MY_Controller { $userid = $this->muser->get_userid(); - $invitations = $this->db->select('user') - ->from('actions') - ->where('user', $userid) - ->where('action', 'invitation') - ->count_all_results(); + \service\user::create_invitation_key($userid); - if ($invitations + 1 > $this->config->item('max_invitation_keys')) { - throw new \exceptions\PublicApiException("user/invitation-limit", "You can't create more invitation keys at this time."); - } + redirect("user/invite"); + } - $key = random_alphanum(12, 16); + function delete_invitation_key() + { + $this->duser->require_implemented("can_register_new_users"); + $this->muser->require_access(); - $this->db->set(array( - 'key' => $key, - 'user' => $userid, - 'date' => time(), - 'action' => 'invitation' - )) - ->insert('actions'); + $userid = $this->muser->get_userid(); + $key = $this->input->post("key"); + \service\user::delete_invitation_key($userid, $key); redirect("user/invite"); } @@ -188,7 +182,7 @@ class User extends MY_Controller { $this->data['redirect_uri'] = "/"; - if ($process !== false) { + if ($process !== null) { $username = $this->input->post("username"); $email = $this->input->post("email"); $password = $this->input->post("password"); @@ -271,10 +265,10 @@ class User extends MY_Controller { $this->email->to($useremail); $this->email->subject("FileBin account deleted"); $this->email->message("" - ."Your FileBin account '${username}' at ".site_url()."\n" + ."Your FileBin account '{$username}' at ".site_url()."\n" ."has been permemently deleted.\n" ."\n" - ."The request has been sent from the IP address '${_SERVER["REMOTE_ADDR"]}'\n" + ."The request has been sent from the IP address '{$_SERVER["REMOTE_ADDR"]}'\n" ."and was confirmed with your password.\n" ."\n" ."Thank you for using FileBin!\n" @@ -302,15 +296,15 @@ class User extends MY_Controller { $this->duser->require_implemented("can_reset_password"); $key = $this->uri->segment(3); - if ($_SERVER["REQUEST_METHOD"] == "GET" && $key === false) { + if ($_SERVER["REQUEST_METHOD"] == "GET" && $key === null) { return $this->_reset_password_username_form(); } - if ($key === false) { + if ($key === null) { return $this->_reset_password_send_mail(); } - if ($key !== false) { + if ($key !== null) { return $this->_reset_password_form(); } } @@ -332,7 +326,7 @@ class User extends MY_Controller { $username = $this->input->post("username"); if (!$this->muser->username_exists($username)) { - throw new \exceptions\PublicApiException("user/reset_password/invalid-username", "Invalid username"); + throw new \exceptions\UserInputException("user/reset_password/invalid-username", "Invalid username"); } $userinfo = $this->db->select('id, email, username') @@ -354,8 +348,8 @@ class User extends MY_Controller { $this->email->to($userinfo["email"]); $this->email->subject("FileBin password reset"); $this->email->message("" - ."Someone requested a password reset for the account '${userinfo["username"]}'\n" - ."from the IP address '${_SERVER["REMOTE_ADDR"]}'.\n" + ."Someone requested a password reset for the account '{$userinfo["username"]}'\n" + ."from the IP address '{$_SERVER["REMOTE_ADDR"]}'.\n" ."\n" ."Please follow this link to reset your password:\n" .site_url("user/reset_password/$key") @@ -381,7 +375,7 @@ class User extends MY_Controller { $userid = $query["user"]; - if ($process !== false) { + if ($process !== null) { $password = $this->input->post("password"); $password_confirm = $this->input->post("password_confirm"); @@ -462,7 +456,7 @@ class User extends MY_Controller { { $this->muser->require_access(); - if ($this->input->post("process") !== false) { + if ($this->input->post("process") !== null) { $this->_save_profile(); } @@ -491,18 +485,18 @@ class User extends MY_Controller { $values = explode("-", $value); if (!is_array($values) || count($values) != 2) { - throw new \exceptions\PublicApiException("user/profile/invalid-upload-id-limit", "Invalid upload id limit value"); + throw new \exceptions\UserInputException("user/profile/invalid-upload-id-limit", "Invalid upload id limit value"); } $lower = intval($values[0]); $upper = intval($values[1]); if ($lower > $upper) { - throw new \exceptions\PublicApiException("user/profile/lower-bigger-than-upper", "lower limit > upper limit"); + throw new \exceptions\UserInputException("user/profile/lower-bigger-than-upper", "lower limit > upper limit"); } if ($lower < 3 || $upper > 64) { - throw new \exceptions\PublicApiException("user/profile/limit-out-of-bounds", "upper or lower limit out of bounds (3-64)"); + throw new \exceptions\UserInputException("user/profile/limit-out-of-bounds", "upper or lower limit out of bounds (3-64)"); } return $lower."-".$upper; @@ -518,7 +512,7 @@ class User extends MY_Controller { } if (!$this->muser->valid_email($value)) { - throw new \exceptions\PublicApiException("user/profile/invalid-email", "Invalid email"); + throw new \exceptions\UserInputException("user/profile/invalid-email", "Invalid email"); } $this->load->library("email"); @@ -559,7 +553,7 @@ class User extends MY_Controller { $this->email->to($email['email']); $this->email->subject("FileBin email change confirmation"); $this->email->message("" - ."A request has been sent to change the email address of account '${old["username"]}'\n" + ."A request has been sent to change the email address of account '{$old["username"]}'\n" ."from ".$old['email']." to $value.\n" ."\n" ."Please follow this link to CONFIRM the change:\n" @@ -584,7 +578,7 @@ class User extends MY_Controller { foreach (array_keys($value_processor) as $field) { $value = $this->input->post($field); - if ($value !== false) { + if ($value !== null) { $new_value = $value_processor[$field]($value); if ($new_value !== null) { $data[$field] = $new_value; @@ -619,7 +613,7 @@ class User extends MY_Controller { $this->data["hash"] = false; $this->data["password"] = $password; - if ($process !== false) { + if ($process !== null) { if (!$password || $password !== $password_confirm) { $error[]= "No password or passwords don't match."; } else { @@ -702,4 +696,22 @@ class User extends MY_Controller { echo "User added\n"; } + + function delete_user() + { + $this->_require_cli_request(); + $this->duser->require_implemented("can_delete_account"); + + echo "\nWARNING: Deleting a user will delete ALL their data permanently.\n\n"; + + $username = $this->_get_line_cli("Username", function($username) { + if (get_instance()->muser->username_exists($username)) { + return true; + } + return false; + }); + $this->muser->delete_user_real($username); + echo "User removed\n"; + } + } diff --git a/application/controllers/api/api_controller.php b/application/controllers/api/api_controller.php index 2b9054b17..ad3ac6e73 100644 --- a/application/controllers/api/api_controller.php +++ b/application/controllers/api/api_controller.php @@ -9,6 +9,11 @@ namespace controllers\api; -abstract class api_controller extends \CI_Controller { +abstract class api_controller { + public $CI; + public function __construct() { + $this->CI =& get_instance(); + } + } diff --git a/application/controllers/api/v2/api_info.php b/application/controllers/api/v2/api_info.php index 8d2bdf6dc..bd1d63590 100644 --- a/application/controllers/api/v2/api_info.php +++ b/application/controllers/api/v2/api_info.php @@ -11,6 +11,6 @@ namespace controllers\api\v2; class api_info extends \controllers\api\api_controller { static public function get_version() { - return "2.1.1"; + return "2.2.0"; } } diff --git a/application/controllers/api/v2/file.php b/application/controllers/api/v2/file.php index 15a43fc45..2e792e577 100644 --- a/application/controllers/api/v2/file.php +++ b/application/controllers/api/v2/file.php @@ -13,28 +13,28 @@ class file extends \controllers\api\api_controller { { parent::__construct(); - $this->load->model('mfile'); - $this->load->model('mmultipaste'); + $this->CI->load->model('mfile'); + $this->CI->load->model('mmultipaste'); } public function upload() { - $this->muser->require_access("basic"); + $this->CI->muser->require_access("basic"); $files = getNormalizedFILES(); if (empty($files)) { - throw new \exceptions\PublicApiException("file/no-file", "No file was uploaded or unknown error occurred."); + throw new \exceptions\UserInputException("file/no-file", "No file was uploaded or unknown error occurred."); } \service\files::verify_uploaded_files($files); - $limits = $this->muser->get_upload_id_limits(); - $userid = $this->muser->get_userid(); + $limits = $this->determine_id_limits(); + $userid = $this->CI->muser->get_userid(); $urls = array(); foreach ($files as $file) { - $id = $this->mfile->new_id($limits[0], $limits[1]); + $id = $this->CI->mfile->new_id($limits[0], $limits[1]); \service\files::add_uploaded_file($userid, $id, $file["tmp_name"], $file["name"]); $ids[] = $id; $urls[] = site_url($id).'/'; @@ -49,7 +49,7 @@ class file extends \controllers\api\api_controller { public function get_config() { return array( - "upload_max_size" => $this->config->item("upload_max_size"), + "upload_max_size" => $this->CI->config->item("upload_max_size"), "max_files_per_request" => intval(ini_get("max_file_uploads")), "max_input_vars" => intval(ini_get("max_input_vars")), "request_max_size" => return_bytes(ini_get("post_max_size")), @@ -58,8 +58,8 @@ class file extends \controllers\api\api_controller { public function history() { - $this->muser->require_access("apikey"); - $history = \service\files::history($this->muser->get_userid()); + $this->CI->muser->require_access("apikey"); + $history = \service\files::history($this->CI->muser->get_userid()); foreach ($history['multipaste_items'] as $key => $item) { foreach ($item['items'] as $inner_key => $item) { unset($history['multipaste_items'][$key]['items'][$inner_key]['sort_order']); @@ -73,8 +73,8 @@ class file extends \controllers\api\api_controller { public function delete() { - $this->muser->require_access("apikey"); - $ids = $this->input->post_array("ids"); + $this->CI->muser->require_access("apikey"); + $ids = $this->CI->input->post_array("ids"); $ret = \service\files::delete($ids); $ret = ensure_json_keys_contain_objects($ret, array("errors", "deleted")); @@ -84,13 +84,29 @@ class file extends \controllers\api\api_controller { public function create_multipaste() { - $this->muser->require_access("basic"); - $ids = $this->input->post_array("ids"); - $userid = $this->muser->get_userid(); - $limits = $this->muser->get_upload_id_limits(); + $this->CI->muser->require_access("basic"); + $ids = $this->CI->input->post_array("ids"); + $userid = $this->CI->muser->get_userid(); + $limits = $this->determine_id_limits(); return \service\files::create_multipaste($ids, $userid, $limits); } + + private function determine_id_limits() + { + $posted_minlength = $this->CI->input->post('minimum-id-length'); + if (is_null($posted_minlength)) { + $limits = $this->CI->muser->get_upload_id_limits(); + } else { + if ((!preg_match("/^\d+$/", $posted_minlength)) || intval($posted_minlength) <= 1 ) { + throw new \exceptions\UserInputException("file/bad-minimum-id-length", "Passed parameter 'minimum-id-length' is not a valid integer or too small (min value: 2)"); + } + + $limits = [$posted_minlength, null]; + } + + return $limits; + } } # vim: set noet: diff --git a/application/controllers/api/v2/user.php b/application/controllers/api/v2/user.php index 655dc62f3..677a870c4 100644 --- a/application/controllers/api/v2/user.php +++ b/application/controllers/api/v2/user.php @@ -13,31 +13,31 @@ class user extends \controllers\api\api_controller { { parent::__construct(); - $this->load->model('muser'); + $this->CI->load->model('muser'); } public function apikeys() { - $this->muser->require_access("full"); - return \service\user::apikeys($this->muser->get_userid()); + $this->CI->muser->require_access("full"); + return \service\user::apikeys($this->CI->muser->get_userid()); } public function create_apikey() { - $username = $this->input->post("username"); - $password = $this->input->post("password"); + $username = $this->CI->input->post("username"); + $password = $this->CI->input->post("password"); if ($username && $password) { - if (!$this->muser->login($username, $password)) { + if (!$this->CI->muser->login($username, $password)) { throw new \exceptions\NotAuthenticatedException("user/login-failed", "Login failed"); } } - $this->muser->require_access("full"); + $this->CI->muser->require_access("full"); - $userid = $this->muser->get_userid(); - $comment = $this->input->post("comment"); - $comment = $comment === false ? "" : $comment; - $access_level = $this->input->post("access_level"); + $userid = $this->CI->muser->get_userid(); + $comment = $this->CI->input->post("comment"); + $comment = $comment === null ? "" : $comment; + $access_level = $this->CI->input->post("access_level"); $key = \service\user::create_apikey($userid, $comment, $access_level); @@ -48,16 +48,16 @@ class user extends \controllers\api\api_controller { public function delete_apikey() { - $this->muser->require_access("full"); + $this->CI->muser->require_access("full"); - $userid = $this->muser->get_userid(); - $key = $this->input->post("delete_key"); + $userid = $this->CI->muser->get_userid(); + $key = $this->CI->input->post("delete_key"); - $this->db->where('user', $userid) + $this->CI->db->where('user', $userid) ->where('key', $key) ->delete('apikeys'); - $affected = $this->db->affected_rows(); + $affected = $this->CI->db->affected_rows(); assert($affected >= 0 && $affected <= 1); if ($affected == 1) { diff --git a/application/controllers/file/multipaste.php b/application/controllers/file/Multipaste.php index 50367697c..bc042e2f3 100644 --- a/application/controllers/file/multipaste.php +++ b/application/controllers/file/Multipaste.php @@ -20,7 +20,7 @@ class Multipaste extends MY_Controller { $this->muser->require_access("basic"); $ids = $this->input->post_array("ids"); - if ($ids === false) { + if ($ids === null) { $ids = []; } @@ -46,6 +46,7 @@ class Multipaste extends MY_Controller { $this->data['ids'] = $ids; $this->data['items'] = array_map(function($id) {return $this->_get_multipaste_item($id);}, $ids); + $this->data['items'] = array_filter($this->data['items'], function($item) {return $item !== false;}); $this->load->view('header', $this->data); $this->load->view('file/multipaste/queue', $this->data); @@ -58,7 +59,7 @@ class Multipaste extends MY_Controller { $ids = $this->input->post_array('ids'); $process = $this->input->post('process'); - if ($ids === false) { + if ($ids === null) { $ids = []; } @@ -89,7 +90,7 @@ class Multipaste extends MY_Controller { $this->muser->require_access("basic"); $ids = $this->input->post_array('ids'); - if ($ids === false) { + if ($ids === null) { $ids = []; } @@ -99,6 +100,10 @@ class Multipaste extends MY_Controller { private function _get_multipaste_item($id) { $filedata = $this->mfile->get_filedata($id); + if ($filedata === false) { + return false; + } + $item = []; $item['id'] = $filedata['id']; $item['tooltip'] = \service\files::tooltip($filedata); diff --git a/application/controllers/index.html b/application/controllers/index.html index c942a79ce..bcb7cae34 100644 --- a/application/controllers/index.html +++ b/application/controllers/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/core/MY_Controller.php b/application/core/MY_Controller.php index 47dd6a899..ce8e0e948 100644 --- a/application/core/MY_Controller.php +++ b/application/core/MY_Controller.php @@ -20,14 +20,13 @@ class MY_Controller extends CI_Controller { $this->load->library('customautoloader'); // check if DB is up to date - if (!($this->input->is_cli_request() && $this->uri->segment(1) === "tools")) { + if (!(is_cli() && $this->uri->segment(1) === "tools")) { $this->_ensure_database_schema_up_to_date(); } $old_path = getenv("PATH"); putenv("PATH=$old_path:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"); - mb_internal_encoding('UTF-8'); $this->load->helper(array('form', 'filebin')); if ($this->uri->segment(1) == "api") { @@ -54,8 +53,8 @@ class MY_Controller extends CI_Controller { protected function _require_cli_request() { - if (!$this->input->is_cli_request()) { - throw new \exceptions\PublicApiException("api/cli-only", "This function can only be accessed via the CLI interface"); + if (!is_cli()) { + throw new \exceptions\InsufficientPermissionsException("api/cli-only", "This function can only be accessed via the CLI interface"); } } @@ -79,7 +78,7 @@ class MY_Controller extends CI_Controller { private function _check_csrf_protection_required() { - if ($this->input->post("apikey") !== false || is_api_client()) { + if ($this->input->post("apikey") !== null || is_api_client()) { /* This relies on the authentication code always verifying the supplied * apikey. If the key is not verified/logged in an attacker could simply * add an empty "apikey" field to the CSRF form to circumvent the @@ -106,7 +105,7 @@ class MY_Controller extends CI_Controller { return false; } - if ($this->input->is_cli_request()) { + if (is_cli()) { return false; } @@ -118,7 +117,11 @@ class MY_Controller extends CI_Controller { // 2 functions for accessing config options, really? $this->config->set_item('csrf_protection', true); config_item("csrf_protection", true); - $this->security->__construct(); - $this->security->csrf_verify(); + + if ($this->uri->uri_string() == "file/multipaste/ajax_submit") { + $this->config->set_item('csrf_regenerate', false); + } + + $this->security->__construct('UTF-8'); } } diff --git a/application/core/MY_Input.php b/application/core/MY_Input.php index 4d43774c0..5a08ea4bb 100644 --- a/application/core/MY_Input.php +++ b/application/core/MY_Input.php @@ -26,8 +26,8 @@ class MY_Input extends CI_Input { public function post_array($key) { $ret = parent::post($key); - if ($ret === false) { - return false; + if ($ret === null) { + return null; } elseif (!is_array($ret)) { $data = [ "key" => $key, diff --git a/application/core/index.html b/application/core/index.html index c942a79ce..bcb7cae34 100644 --- a/application/core/index.html +++ b/application/core/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/errors/error_404.php b/application/errors/error_404.php deleted file mode 100644 index 2e69d7e00..000000000 --- a/application/errors/error_404.php +++ /dev/null @@ -1,3 +0,0 @@ -<?php -$title = "404 Page Not Found"; -include APPPATH."errors/error_general.php"; diff --git a/application/errors/error_db.php b/application/errors/error_db.php deleted file mode 100644 index 827d7cc31..000000000 --- a/application/errors/error_db.php +++ /dev/null @@ -1,3 +0,0 @@ -<?php -$title = "Database Error"; -include APPPATH."errors/error_general.php"; diff --git a/application/errors/error_general.php b/application/errors/error_general.php deleted file mode 100644 index 14e5e7a2e..000000000 --- a/application/errors/error_general.php +++ /dev/null @@ -1,104 +0,0 @@ -<?php - -// fancy error page only works if we can load helpers -if (class_exists("CI_Controller") && !isset($GLOBALS["is_error_page"]) && isset(get_instance()->load)) { - if (!isset($title)) { - $title = "Error"; - } - $GLOBALS["is_error_page"] = true; - - $CI =& get_instance(); - $CI->load->helper("filebin"); - $CI->load->helper("url"); - - if ($CI->input->is_cli_request()) { - $message = str_replace("</p>", "</p>\n", $message); - $message = strip_tags($message); - echo "$heading: $message\n"; - exit(); - } - - include APPPATH.'views/header.php'; - - ?> - <div class="error"> - <h1><?php echo $heading; ?></h1> - <?php echo $message; ?> - </div> - - <?php - include APPPATH.'views/footer.php'; -} elseif (php_sapi_name() === 'cli' OR defined('STDIN')) { - echo "# $heading\n"; - $msg = strip_tags(str_replace("<br>", "\n", $message)); - foreach (explode("\n", $msg) as $line) { - echo "# $line\n"; - } - exit(255); -} else { - // default CI error page -?> -<!DOCTYPE html> -<html lang="en"> -<head> -<title>Error</title> -<style type="text/css"> - -::selection{ background-color: #E13300; color: white; } -::moz-selection{ background-color: #E13300; color: white; } -::webkit-selection{ background-color: #E13300; color: white; } - -body { - background-color: #fff; - margin: 40px; - font: 13px/20px normal Helvetica, Arial, sans-serif; - color: #4F5155; -} - -a { - color: #003399; - background-color: transparent; - font-weight: normal; -} - -h1 { - color: #444; - background-color: transparent; - border-bottom: 1px solid #D0D0D0; - font-size: 19px; - font-weight: normal; - margin: 0 0 14px 0; - padding: 14px 15px 10px 15px; -} - -code { - font-family: Consolas, Monaco, Courier New, Courier, monospace; - font-size: 12px; - background-color: #f9f9f9; - border: 1px solid #D0D0D0; - color: #002166; - display: block; - margin: 14px 0 14px 0; - padding: 12px 10px 12px 10px; -} - -#container { - margin: 10px; - border: 1px solid #D0D0D0; - -webkit-box-shadow: 0 0 8px #D0D0D0; -} - -p, div { - margin: 12px 15px 12px 15px; -} -</style> -</head> -<body> - <div id="container"> - <h1><?php echo $heading; ?></h1> - <?php echo $message; ?> - </div> -</body> -</html> -<?php -} diff --git a/application/errors/error_php.php b/application/errors/error_php.php deleted file mode 100644 index 5f91e07a0..000000000 --- a/application/errors/error_php.php +++ /dev/null @@ -1,11 +0,0 @@ -<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;"> - -<h4>A PHP Error was encountered</h4> - -<p>Severity: <?php echo $severity; ?></p> -<p>Message: <?php echo $message; ?></p> -<p>Filename: <?php echo $filepath; ?></p> -<p>Line Number: <?php echo $line; ?></p> - -</div> -<?php exit(); diff --git a/application/helpers/filebin_helper.php b/application/helpers/filebin_helper.php index c1a6f4f96..0fa986225 100644 --- a/application/helpers/filebin_helper.php +++ b/application/helpers/filebin_helper.php @@ -1,5 +1,31 @@ <?php +function expiration_duration($duration) +{ + $total = $duration; + $days = floor($total / 86400); + $total -= $days * 86400; + $hours = floor($total / 3600); + $total -= $hours * 3600; + $minutes = floor($total / 60); + $seconds = $total - $minutes * 60; + $times = array($days, $hours, $minutes, $seconds); + $suffixes = array(' day', ' hour', ' minute', ' second'); + $expiration = array(); + + for ($i = 0; $i < count($suffixes); $i++) { + if ($times[$i] != 0) { + $duration = $times[$i].$suffixes[$i]; + if ($times[$i] > 1) { + $duration .= "s"; + } + array_push($expiration, $duration); + } + } + + return join(", ", $expiration); +} + function format_bytes($size) { $suffixes = array('B', 'KiB', 'MiB', 'GiB', 'TiB' , 'PiB' , 'EiB', 'ZiB', 'YiB'); @@ -20,70 +46,6 @@ function format_bytes($size) } } -function even_odd($reset = false) -{ - static $counter = 1; - - if ($reset) { - $counter = 1; - } - - if ($counter++%2 == 0) { - return 'even'; - } else { - return 'odd'; - } -} - -// Source: http://hu.php.net/manual/en/function.str-pad.php#71558 -// This is a multibyte enabled str_pad -function mb_str_pad($ps_input, $pn_pad_length, $ps_pad_string = " ", $pn_pad_type = STR_PAD_RIGHT, $ps_encoding = NULL) -{ - $ret = ""; - - if (is_null($ps_encoding)) - $ps_encoding = mb_internal_encoding(); - - $hn_length_of_padding = $pn_pad_length - mb_strlen($ps_input, $ps_encoding); - $hn_psLength = mb_strlen($ps_pad_string, $ps_encoding); // pad string length - - if ($hn_psLength <= 0 || $hn_length_of_padding <= 0) { - // Padding string equal to 0: - // - $ret = $ps_input; - } - else { - $hn_repeatCount = floor($hn_length_of_padding / $hn_psLength); // how many times repeat - - if ($pn_pad_type == STR_PAD_BOTH) { - $hs_lastStrLeft = ""; - $hs_lastStrRight = ""; - $hn_repeatCountLeft = $hn_repeatCountRight = ($hn_repeatCount - $hn_repeatCount % 2) / 2; - - $hs_lastStrLength = $hn_length_of_padding - 2 * $hn_repeatCountLeft * $hn_psLength; // the rest length to pad - $hs_lastStrLeftLength = $hs_lastStrRightLength = floor($hs_lastStrLength / 2); // the rest length divide to 2 parts - $hs_lastStrRightLength += $hs_lastStrLength % 2; // the last char add to right side - - $hs_lastStrLeft = mb_substr($ps_pad_string, 0, $hs_lastStrLeftLength, $ps_encoding); - $hs_lastStrRight = mb_substr($ps_pad_string, 0, $hs_lastStrRightLength, $ps_encoding); - - $ret = str_repeat($ps_pad_string, $hn_repeatCountLeft) . $hs_lastStrLeft; - $ret .= $ps_input; - $ret .= str_repeat($ps_pad_string, $hn_repeatCountRight) . $hs_lastStrRight; - } - else { - $hs_lastStr = mb_substr($ps_pad_string, 0, $hn_length_of_padding % $hn_psLength, $ps_encoding); // last part of pad string - - if ($pn_pad_type == STR_PAD_LEFT) - $ret = str_repeat($ps_pad_string, $hn_repeatCount) . $hs_lastStr . $ps_input; - else - $ret = $ps_input . str_repeat($ps_pad_string, $hn_repeatCount) . $hs_lastStr; - } - } - - return $ret; -} - function is_api_client($override = null) { static $is_api = null; @@ -152,28 +114,6 @@ function js_cache_buster() return $ret; } -function handle_etag($etag) -{ - $etag = strtolower($etag); - $modified = true; - - if(isset($_SERVER['HTTP_IF_NONE_MATCH'])) { - $oldtag = trim(strtolower($_SERVER['HTTP_IF_NONE_MATCH']), '"'); - if($oldtag == $etag) { - $modified = false; - } else { - $modified = true; - } - } - - header('Etag: "'.$etag.'"'); - - if (!$modified) { - header("HTTP/1.1 304 Not Modified"); - exit(); - } -} - // Reference: http://php.net/manual/en/features.file-upload.multiple.php#109437 // This is a little different because we don't care about the fieldname function getNormalizedFILES() @@ -217,34 +157,6 @@ function auth_driver_function_implemented($function) return $result[$function]; } -function send_json_reply($array, $status = "success") -{ - $reply = array(); - $reply["status"] = $status; - $reply["data"] = $array; - - $CI =& get_instance(); - $CI->output->set_content_type('application/json'); - $CI->output->set_output(json_encode($reply)); -} - -function send_json_error_reply($error_id, $message, $array = null, $status_code = 400) -{ - $reply = array(); - $reply["status"] = "error"; - $reply["error_id"] = $error_id; - $reply["message"] = $message; - - if ($array !== null) { - $reply["data"] = $array; - } - - $CI =& get_instance(); - $CI->output->set_status_header($status_code); - $CI->output->set_content_type('application/json'); - $CI->output->set_output(json_encode($reply)); -} - function static_storage($key, $value = null) { static $storage = array(); @@ -392,4 +304,22 @@ function ensure_json_keys_contain_objects($data, $keys) { return $data; } +function output_cli_usage() { + echo "php index.php <controller> <function> [arguments]\n"; + echo "\n"; + echo "Functions:\n"; + echo " file cron Cronjob\n"; + echo " file nuke_id <ID> Nukes all IDs sharing the same hash\n"; + echo " user cron Cronjob\n"; + echo " user add_user Add a user\n"; + echo " user delete_user Delete a user including all their data\n"; + echo " tools update_database Update/Initialise the database\n"; + echo "\n"; + echo "Functions that shouldn't have to be run:\n"; + echo " file clean_stale_files Remove files without database entries,\n"; + echo " database entries without files and multipaste\n"; + echo " tarballs that are no longer needed\n"; + echo " file update_file_metadata Update filesize and mimetype in database\n"; +} + # vim: set noet: diff --git a/application/helpers/index.html b/application/helpers/index.html index c942a79ce..bcb7cae34 100644 --- a/application/helpers/index.html +++ b/application/helpers/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/hooks/index.html b/application/hooks/index.html index c942a79ce..bcb7cae34 100644 --- a/application/hooks/index.html +++ b/application/hooks/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/index.html b/application/index.html index c942a79ce..bcb7cae34 100644 --- a/application/index.html +++ b/application/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/language/english/index.html b/application/language/english/index.html index c942a79ce..bcb7cae34 100644 --- a/application/language/english/index.html +++ b/application/language/english/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/language/index.html b/application/language/index.html index c942a79ce..bcb7cae34 100644 --- a/application/language/index.html +++ b/application/language/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/libraries/Customautoloader.php b/application/libraries/Customautoloader.php index 426364ee3..eb14c5624 100644 --- a/application/libraries/Customautoloader.php +++ b/application/libraries/Customautoloader.php @@ -8,7 +8,7 @@ */ // Original source: http://stackoverflow.com/a/9526005/953022 -class CustomAutoloader{ +class Customautoloader { public function __construct() { spl_autoload_register(array($this, 'loader')); diff --git a/application/libraries/Ddownload/Ddownload.php b/application/libraries/Ddownload/Ddownload.php index 808dfe776..3a98d4154 100644 --- a/application/libraries/Ddownload/Ddownload.php +++ b/application/libraries/Ddownload/Ddownload.php @@ -17,7 +17,7 @@ class Ddownload extends CI_Driver_Library { protected $_adapter = null; protected $valid_drivers = array( - 'ddownload_php', 'ddownload_nginx', 'ddownload_lighttpd' + 'php', 'nginx', 'lighttpd' ); function __construct() diff --git a/application/libraries/Ddownload/drivers/Ddownload_php.php b/application/libraries/Ddownload/drivers/Ddownload_php.php index 344db53f0..90c002b58 100644 --- a/application/libraries/Ddownload/drivers/Ddownload_php.php +++ b/application/libraries/Ddownload/drivers/Ddownload_php.php @@ -12,7 +12,7 @@ class Ddownload_php extends Ddownload_Driver { // Original source: http://www.phpfreaks.com/forums/index.php?topic=198274.msg895468#msg895468 public function serveFile($file, $filename, $type) { - $fp = @fopen($file, 'r'); + $fp = fopen($file, 'r'); $size = filesize($file); // File size $length = $size; // Content length @@ -54,7 +54,7 @@ class Ddownload_php extends Ddownload_Driver { // If the range starts with an '-' we start from the beginning // If not, we forward the file pointer // And make sure to get the end byte if spesified - if ($range{0} == '-') + if ($range[0] == '-') { // The n-number of the last bytes is requested $c_start = $size - substr($range, 1); diff --git a/application/libraries/Duser/Duser.php b/application/libraries/Duser/Duser.php index 8005a00bb..0007fabd8 100644 --- a/application/libraries/Duser/Duser.php +++ b/application/libraries/Duser/Duser.php @@ -50,7 +50,7 @@ class Duser extends CI_Driver_Library { protected $_adapter = null; protected $valid_drivers = array( - 'duser_db', 'duser_ldap', 'duser_fluxbb' + 'db', 'ldap', 'fluxbb' ); function __construct() diff --git a/application/libraries/Duser/drivers/Duser_db.php b/application/libraries/Duser/drivers/Duser_db.php index 062da9e54..e1df20f1f 100644 --- a/application/libraries/Duser/drivers/Duser_db.php +++ b/application/libraries/Duser/drivers/Duser_db.php @@ -24,6 +24,10 @@ class Duser_db extends Duser_Driver { { $CI =& get_instance(); + if ($username === null) { + return false; + } + $query = $CI->db->select('username, id, password') ->from('users') ->where('username', $username) @@ -48,6 +52,10 @@ class Duser_db extends Duser_Driver { { $CI =& get_instance(); + if ($username === null) { + return false; + } + $query = $CI->db->select('id') ->from('users') ->where('username', $username) @@ -64,6 +72,10 @@ class Duser_db extends Duser_Driver { { $CI =& get_instance(); + if ($userid === null) { + throw new \exceptions\ApiException("libraries/duser/db/get_email-failed", "User does not exist"); + } + $query = $CI->db->select('email') ->from('users') ->where('id', $userid) diff --git a/application/libraries/Duser/drivers/Duser_ldap.php b/application/libraries/Duser/drivers/Duser_ldap.php index b80385fe0..9481397d0 100644 --- a/application/libraries/Duser/drivers/Duser_ldap.php +++ b/application/libraries/Duser/drivers/Duser_ldap.php @@ -26,15 +26,26 @@ class Duser_ldap extends Duser_Driver { return false; } + if (isset($config['bind_rdn']) && isset($config['bind_password'])) { + ldap_bind($ds, $config['bind_rdn'], $config['bind_password']); + } + + if (isset($config['filter'])) { + $filter = sprintf($config['filter'], $username); + } else { + $filter = $config["username_field"].'='.$username; + } + + switch ($config["scope"]) { case "base": - $r = ldap_read($ds, $config['basedn'], $config["username_field"].'='.$username); + $r = ldap_read($ds, $config['basedn'], $filter); break; case "one": - $r = ldap_list($ds, $config['basedn'], $config["username_field"].'='.$username); + $r = ldap_list($ds, $config['basedn'], $filter); break; case "subtree": - $r = ldap_search($ds, $config['basedn'], $config["username_field"].'='.$username); + $r = ldap_search($ds, $config['basedn'], $filter); break; default: throw new \exceptions\ApiException("libraries/duser/ldap/invalid-ldap-scope", "Invalid LDAP scope"); diff --git a/application/libraries/ExceptionHandler.php b/application/libraries/ExceptionHandler.php index acfa97163..ed7f9b8c5 100644 --- a/application/libraries/ExceptionHandler.php +++ b/application/libraries/ExceptionHandler.php @@ -15,8 +15,6 @@ class ExceptionHandler { set_error_handler(array("\libraries\ExceptionHandler", "error_handler")); set_exception_handler(array("\libraries\ExceptionHandler", 'exception_handler')); register_shutdown_function(array("\libraries\ExceptionHandler", "check_for_fatal")); - assert_options(ASSERT_ACTIVE, true); - assert_options(ASSERT_CALLBACK, array("\libraries\ExceptionHandler", '_assert_failure')); } static function error_handler($errno, $errstr, $errfile, $errline) @@ -130,7 +128,7 @@ class ExceptionHandler { } $message = "$message"; - include APPPATH."/errors/error_general.php"; + include VIEWPATH."/errors/html/error_general.php"; } /** @@ -139,16 +137,10 @@ class ExceptionHandler { static public function check_for_fatal() { $error = error_get_last(); - if ($error["type"] == E_ERROR) { + if (isset($error) && $error["type"] == E_ERROR) { self::exception_handler(new \ErrorException( $error["message"], 0, $error["type"], $error["file"], $error["line"])); } } - static public function assert_failure($file, $line, $expr, $message = "") - { - self::exception_handler(new Exception("assert($expr): Assertion failed in $file at line $line".($message != "" ? " with message: '$message'" : ""))); - exit(1); - } - } diff --git a/application/libraries/Image/Drivers/GD.php b/application/libraries/Image/Drivers/GD.php index e2e0a99be..2aecd18ca 100644 --- a/application/libraries/Image/Drivers/GD.php +++ b/application/libraries/Image/Drivers/GD.php @@ -128,8 +128,8 @@ class GD implements \libraries\Image\ImageDriver { $this->resize($temp_width, $temp_height); - $x0 = ($temp_width - $target_width) / 2; - $y0 = ($temp_height - $target_height) / 2; + $x0 = floor(($temp_width - $target_width) / 2); + $y0 = floor(($temp_height - $target_height) / 2); $this->crop($x0, $y0, $target_width, $target_height); $this->apply_exif_orientation(); diff --git a/application/libraries/Image/Drivers/imagemagick.php b/application/libraries/Image/Drivers/imagemagick.php index 8295469eb..e65d05d3e 100644 --- a/application/libraries/Image/Drivers/imagemagick.php +++ b/application/libraries/Image/Drivers/imagemagick.php @@ -18,8 +18,7 @@ class imagemagick implements \libraries\Image\ImageDriver { $mimetype = $mimetype; $base = explode("/", $mimetype)[0]; - if ($base == "image" - || in_array($mimetype, array("application/pdf"))) { + if ($base == "image") { return 100; } @@ -81,14 +80,14 @@ class imagemagick implements \libraries\Image\ImageDriver { public function resize($width, $height) { $this->arguments[] = "-resize"; - $this->arguments[] = "${width}x${height}"; + $this->arguments[] = "{$width}x{$height}"; } public function crop($x, $y, $width, $height) { $this->arguments[] = "+repage"; $this->arguments[] = "-crop"; - $this->arguments[] = "${width}x${height}+${x}+${y}"; + $this->arguments[] = "{$width}x{$height}+{$x}+{$y}"; $this->arguments[] = "+repage"; } @@ -101,11 +100,11 @@ class imagemagick implements \libraries\Image\ImageDriver { $this->apply_exif_orientation(); $this->arguments[] = "-thumbnail"; - $this->arguments[] = "${target_width}x${target_height}^"; + $this->arguments[] = "{$target_width}x{$target_height}^"; $this->arguments[] = "-gravity"; $this->arguments[] = "center"; $this->arguments[] = "-extent"; - $this->arguments[] = "${target_width}x${target_height}^"; + $this->arguments[] = "{$target_width}x{$target_height}^"; } public function apply_exif_orientation() diff --git a/application/libraries/Pygments.php b/application/libraries/Pygments.php index e96b84258..4a771c08f 100644 --- a/application/libraries/Pygments.php +++ b/application/libraries/Pygments.php @@ -38,6 +38,9 @@ class Pygments { $last_desc = ""; foreach (self::get_pygments_info() as $lexer) { + if (empty($lexer['names'])) { + continue; + } $desc = $lexer['fullname']; $name = $lexer['names'][0]; if ($desc == $last_desc) { @@ -189,16 +192,20 @@ class Pygments { $extensionarray = array( 'awk' => 'awk', + 'cast' => 'asciinema', 'c' => 'c', 'coffee' => 'coffee-script', 'cpp' => 'cpp', + 'cr' => 'crystal', 'diff' => 'diff', + 'go' => 'go', 'haml' => 'haml', 'h' => 'c', 'hs' => 'haskell', 'html' => 'xml', 'java' => 'java', 'js' => 'js', + 'json' => 'json', 'lhs' => 'lhs', 'lua' => 'lua', 'mli' => 'ocaml', @@ -211,10 +218,12 @@ class Pygments { 'php' => 'php', 'pl' => 'perl', 'plpgsql' => 'plpgsql', + 'pm' => 'perl', 'postgresql' => 'postgresql', 'pp' => 'puppet', 'py' => 'python', 'rb' => 'ruby', + 'rs' => 'rust', 's' => 'asm', 'sh' => 'bash', 'sql' => 'sql', diff --git a/application/libraries/index.html b/application/libraries/index.html index c942a79ce..bcb7cae34 100644 --- a/application/libraries/index.html +++ b/application/libraries/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/logs/index.html b/application/logs/index.html index c942a79ce..bcb7cae34 100644 --- a/application/logs/index.html +++ b/application/logs/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/migrations/019_change_filesize_type.php b/application/migrations/019_change_filesize_type.php new file mode 100644 index 000000000..33abf89ed --- /dev/null +++ b/application/migrations/019_change_filesize_type.php @@ -0,0 +1,51 @@ +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + +class Migration_change_filesize_type extends CI_Migration { + + public function up() + { + $prefix = $this->db->dbprefix; + + if ($this->db->dbdriver == 'postgre') { + $this->db->query(' + ALTER TABLE "'.$prefix.'file_storage" + ALTER "filesize" TYPE bigint; + '); + } else { + $this->db->query(' + ALTER TABLE `'.$prefix.'file_storage` + MODIFY `filesize` bigint; + '); + } + + $chunk = 500; + + $this->db->where('filesize', 2147483647); + $total = $this->db->count_all_results("file_storage"); + + for ($limit = 0; $limit < $total; $limit += $chunk) { + $query = $this->db->select('hash, id') + ->from('file_storage') + ->where('filesize', 2147483647) + ->limit($chunk, $limit) + ->get()->result_array(); + + foreach ($query as $key => $item) { + $data_id = $item["hash"].'-'.$item['id']; + $filesize = filesize($this->mfile->file($data_id)); + + $this->db->where('id', $item['id']) + ->set(array( + 'filesize' => $filesize, + )) + ->update('file_storage'); + } + } + } + + public function down() + { + throw new \exceptions\ApiException("migration/downgrade-not-supported", "downgrade not supported"); + } +} diff --git a/application/migrations/020_update_session_table.php b/application/migrations/020_update_session_table.php new file mode 100644 index 000000000..94a240def --- /dev/null +++ b/application/migrations/020_update_session_table.php @@ -0,0 +1,45 @@ +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + +class Migration_update_session_table extends CI_Migration { + + public function up() + { + $prefix = $this->db->dbprefix; + + if ($this->db->dbdriver == 'postgre') { + $this->db->query(' + ALTER TABLE "'.$prefix.'ci_sessions" + DROP COLUMN "user_agent"; + '); + $this->db->query(' + ALTER TABLE "'.$prefix.'ci_sessions" + RENAME COLUMN "session_id" TO "id"; + '); + $this->db->query(' + ALTER TABLE "'.$prefix.'ci_sessions" + RENAME COLUMN "last_activity" TO "timestamp"; + '); + $this->db->query(' + ALTER TABLE "'.$prefix.'ci_sessions" + RENAME COLUMN "user_data" TO "data"; + '); + $this->db->query(' + ALTER TABLE "'.$prefix.'ci_sessions" ALTER COLUMN id SET DATA TYPE varchar(128); + '); + } else { + $this->db->query(' + ALTER TABLE `'.$prefix.'ci_sessions` + DROP `user_agent`, + CHANGE `session_id` `id` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + CHANGE `last_activity` `timestamp` INT(10) UNSIGNED NOT NULL DEFAULT 0, + CHANGE `user_data` `data` BLOB NOT NULL; + '); + } + } + + public function down() + { + throw new \exceptions\ApiException("migration/downgrade-not-supported", "downgrade not supported"); + } +} diff --git a/application/migrations/021_change_charset.php b/application/migrations/021_change_charset.php new file mode 100644 index 000000000..475732ed5 --- /dev/null +++ b/application/migrations/021_change_charset.php @@ -0,0 +1,28 @@ +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + +class Migration_change_charset extends CI_Migration { + + public function up() + { + $prefix = $this->db->dbprefix; + + if ($this->db->dbdriver == 'postgre') { + # nothing to do + } else { + $this->db->query('SET FOREIGN_KEY_CHECKS = 0'); + foreach ([ + ['apikeys', 'comment', 'VARCHAR(255)'], + ['files', 'filename', 'VARCHAR(256)'], + ] as $col) { + $this->db->query('ALTER TABLE `'.$prefix.$col[0].'` CHANGE `'.$col[1].'` `'.$col[1].'` '.$col[2].' CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;'); + } + $this->db->query('SET FOREIGN_KEY_CHECKS = 1'); + } + } + + public function down() + { + throw new \exceptions\ApiException("migration/downgrade-not-supported", "downgrade not supported"); + } +} diff --git a/application/models/mfile.php b/application/models/Mfile.php index 977240c89..b9bb67d3c 100644 --- a/application/models/mfile.php +++ b/application/models/Mfile.php @@ -10,10 +10,10 @@ class Mfile extends CI_Model { private $upload_path; + private $id_validation_config; function __construct() { - parent::__construct(); $this->load->model("muser"); $this->upload_path = $this->config->item('upload_path'); @@ -258,7 +258,7 @@ class Mfile extends CI_Model { rmdir($dir); } } - delete_cache("${data_id}_thumb_150"); + delete_cache("{$data_id}_thumb_150"); } public function get_owner($id) diff --git a/application/models/mmultipaste.php b/application/models/Mmultipaste.php index 52ea4dfb4..014dc4d61 100644 --- a/application/models/mmultipaste.php +++ b/application/models/Mmultipaste.php @@ -11,7 +11,6 @@ class Mmultipaste extends CI_Model { function __construct() { - parent::__construct(); $this->load->model("muser"); $this->load->model("mfile"); } diff --git a/application/models/muser.php b/application/models/Muser.php index 1ee6c259a..1d8e97d14 100644 --- a/application/models/muser.php +++ b/application/models/Muser.php @@ -19,8 +19,6 @@ class Muser extends CI_Model { function __construct() { - parent::__construct(); - $this->load->helper("filebin"); $this->load->driver("duser"); $this->hashalgo = $this->config->item('auth_db')['hashing_algorithm']; @@ -156,22 +154,21 @@ class Muser extends CI_Model { */ public function valid_email($email) { - $this->load->helper("email"); - return valid_email($email); + return $email === filter_var($email, FILTER_VALIDATE_EMAIL); } public function add_user($username, $password, $email, $referrer) { if (!$this->valid_username($username)) { - throw new \exceptions\PublicApiException("user/invalid-username", "Invalid username (only up to 32 chars of a-z0-9 are allowed)"); + throw new \exceptions\UserInputException("user/invalid-username", "Invalid username (only up to 32 chars of a-z0-9 are allowed)"); } else { if ($this->muser->username_exists($username)) { - throw new \exceptions\PublicApiException("user/username-already-exists", "Username already exists"); + throw new \exceptions\UserInputException("user/username-already-exists", "Username already exists"); } } if (!$this->valid_email($email)) { - throw new \exceptions\PublicApiException("user/invalid-email", "Invalid email"); + throw new \exceptions\UserInputException("user/invalid-email", "Invalid email"); } $this->db->set(array( @@ -195,35 +192,48 @@ class Muser extends CI_Model { $this->duser->require_implemented("can_delete_account"); if ($this->duser->test_login_credentials($username, $password)) { - $userid = $this->get_userid_by_name($username); - assert($userid !== null); - - $this->db->delete('profiles', array('user' => $userid)); - - $this->load->model("mfile"); - $this->load->model("mmultipaste"); - $this->mfile->delete_by_user($userid); - $this->mmultipaste->delete_by_user($userid); - - # null out user data to keep referer information traceable - # If referer information was relinked, one user could create many - # accounts, delete the account that was used to invite them and - # then cause trouble so that the account that invited him gets - # banned because the admin thinks that account invited abusers - $this->db->set(array( - 'username' => null, - 'password' => null, - 'email' => null, - )) - ->where(array('username' => $username)) - ->update('users'); - + $this->delete_user_real($username); return true; } return false; } + /** + * Delete a user + * + * @param username + * @return void + */ + public function delete_user_real($username) + { + $this->duser->require_implemented("can_delete_account"); + $userid = $this->get_userid_by_name($username); + if ($userid === null) { + throw new \exceptions\ApiException("user/delete", "User cannot be found", ["username" => $username]); + } + + $this->db->delete('profiles', array('user' => $userid)); + + $this->load->model("mfile"); + $this->load->model("mmultipaste"); + $this->mfile->delete_by_user($userid); + $this->mmultipaste->delete_by_user($userid); + + # null out user data to keep referer information traceable + # If referer information was relinked, one user could create many + # accounts, delete the account that was used to invite them and + # then cause trouble so that the account that invited him gets + # banned because the admin thinks that account invited abusers + $this->db->set(array( + 'username' => null, + 'password' => null, + 'email' => null, + )) + ->where(array('username' => $username)) + ->update('users'); + } + function get_userid() { if (!$this->logged_in()) { @@ -276,7 +286,7 @@ class Muser extends CI_Model { function require_access($wanted_level = "full") { - if ($this->input->post("apikey") !== false) { + if ($this->input->post("apikey") !== null) { $this->apilogin($this->input->post("apikey")); } @@ -324,6 +334,10 @@ class Muser extends CI_Model { ->where('user', $userid) ->get()->row_array(); + if ($query === null) { + $query = []; + } + $extra_fields = array( "username" => $this->get_username(), "email" => $this->get_email($userid), diff --git a/application/models/index.html b/application/models/index.html index c942a79ce..bcb7cae34 100644 --- a/application/models/index.html +++ b/application/models/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/service/files.php b/application/service/files.php index b45ac8e6f..576adb2ef 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -150,6 +150,7 @@ class files { $hash = md5_file($new_file); $storage_id = null; + $CI->db->trans_start(); $query = $CI->db->select('id, hash') ->from('file_storage') ->where('hash', $hash) @@ -165,6 +166,7 @@ class files { } } + $new_storage_id_created = false; if ($storage_id === null) { $filesize = filesize($new_file); $mimetype = mimetype($new_file); @@ -176,21 +178,33 @@ class files { "date" => time(), )); $storage_id = $CI->db->insert_id(); + $new_storage_id_created = true; + assert(!file_exists($CI->mfile->file($hash."-".$storage_id))); } $data_id = $hash."-".$storage_id; - // TODO: all this doesn't have to run if the file exists. updating the mtime would be enough - // that would also be better for COW filesystems $dir = $CI->mfile->folder($data_id); file_exists($dir) || mkdir ($dir); $new_path = $CI->mfile->file($data_id); - $dest = new \service\storage($new_path); - $tmpfile = $dest->begin(); - rename($new_file, $tmpfile); - $dest->commit(); + // Update mtime for cronjob + touch($new_path); + + // touch may create a new file if the cronjob cleaned up in between the db check and here. + // In that case the file will be empty so move in the data + if ($new_storage_id_created || filesize($new_path) === 0) { + $dest = new \service\storage($new_path); + $tmpfile = $dest->begin(); + + // $new_file may reside on a different file system so this call + // could perform a copy operation internally. $dest->commit() will + // ensure that it performs an atomic overwrite (rename). + rename($new_file, $tmpfile); + $dest->commit(); + } $CI->mfile->add_file($userid, $id, $filename, $storage_id); + $CI->db->trans_complete(); } static public function verify_uploaded_files($files) @@ -228,7 +242,7 @@ class files { } } - $filesize = filesize($file['tmp_name']); + $filesize = isset($file['tmp_name']) ? filesize($file['tmp_name']) : 0; if ($filesize > $CI->config->item('upload_max_size')) { $error_message = "File too big"; } @@ -425,17 +439,115 @@ class files { // likely unsupported filetype } - $tooltip = "${filedata["id"]} - $filesize<br>"; + $tooltip = "{$filedata["id"]} - $filesize<br>"; $tooltip .= "$upload_date<br>"; if ($height > 0 && $width > 0) { - $tooltip .= "${width}x${height} - ${filedata["mimetype"]}<br>"; + $tooltip .= "{$width}x{$height} - {$filedata["mimetype"]}<br>"; } else { - $tooltip .= "${filedata["mimetype"]}<br>"; + $tooltip .= "{$filedata["mimetype"]}<br>"; } return $tooltip; } + static public function clean_multipaste_tarballs() + { + $CI =& get_instance(); + + $tarball_dir = $CI->config->item("upload_path")."/special/multipaste-tarballs"; + if (is_dir($tarball_dir)) { + $tarball_cache_time = $CI->config->item("tarball_cache_time"); + $it = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($tarball_dir), \RecursiveIteratorIterator::SELF_FIRST); + + foreach ($it as $file) { + if ($file->isFile()) { + if ($file->getMTime() < time() - $tarball_cache_time) { + $lock = fopen($file, "r+"); + flock($lock, LOCK_EX); + unlink($file); + flock($lock, LOCK_UN); + } + } + } + } + } + + static public function remove_files_missing_in_db() + { + $CI =& get_instance(); + + $upload_path = $CI->config->item("upload_path"); + $outer_dh = opendir($upload_path); + + while (($dir = readdir($outer_dh)) !== false) { + if (!is_dir($upload_path."/".$dir) || $dir == ".." || $dir == "." || $dir == "special") { + continue; + } + + $dh = opendir($upload_path."/".$dir); + + $empty = true; + + while (($file = readdir($dh)) !== false) { + if ($file == ".." || $file == ".") { + continue; + } + + try { + list($hash, $storage_id) = explode("-", $file); + } catch (\ErrorException $e) { + unlink($upload_path."/".$dir."/".$file); + continue; + } + + $query = $CI->db->select('hash, id') + ->from('file_storage') + ->where('hash', $hash) + ->where('id', $storage_id) + ->limit(1) + ->get()->row_array(); + + if (empty($query)) { + $CI->mfile->delete_data_id($file); + } else { + $empty = false; + } + } + + closedir($dh); + + if ($empty && file_exists($upload_path."/".$dir)) { + rmdir($upload_path."/".$dir); + } + } + closedir($outer_dh); + } + + static public function remove_files_missing_on_disk() + { + $CI =& get_instance(); + + $chunk = 500; + $total = $CI->db->count_all("file_storage"); + + for ($limit = 0; $limit < $total; $limit += $chunk) { + $query = $CI->db->select('hash, id') + ->from('file_storage') + ->limit($chunk, $limit) + ->get()->result_array(); + + foreach ($query as $key => $item) { + $data_id = $item["hash"].'-'.$item['id']; + $file = $CI->mfile->file($data_id); + + if (!$CI->mfile->file_exists($file)) { + $CI->mfile->delete_data_id($data_id); + } + } + } + } + } diff --git a/application/service/multipaste_queue.php b/application/service/multipaste_queue.php index 453ea3429..ff202366c 100644 --- a/application/service/multipaste_queue.php +++ b/application/service/multipaste_queue.php @@ -11,6 +11,10 @@ namespace service; class multipaste_queue { + private $session; + private $mfile; + private $mmultipaste; + public function __construct($session = null, $mfile = null, $mmultipaste = null) { $CI =& get_instance(); @@ -73,7 +77,7 @@ class multipaste_queue { */ public function get() { $ids = $this->session->userdata("multipaste_queue"); - if ($ids === false) { + if ($ids === NULL) { $ids = []; } diff --git a/application/service/renderer.php b/application/service/renderer.php index 6f57e7458..325b4f1f7 100644 --- a/application/service/renderer.php +++ b/application/service/renderer.php @@ -10,6 +10,9 @@ namespace service; class renderer { + private $output_cache; + private $mfile; + private $data; /** * @param $output_cache output cache object @@ -158,23 +161,29 @@ class renderer { */ private function reformat_json($lexer, $linecount, $content) { - if ($lexer === "json" && $linecount === 1) { - $decoded_json = json_decode($content); - if ($decoded_json !== null && $decoded_json !== false) { - $pretty_json = json_encode($decoded_json, JSON_PRETTY_PRINT); - if ($pretty_json !== false) { - $content = $pretty_json; - $this->output_cache->render_now( - array( - "error_type" => "alert-info", - "error_message" => "<p>The file below has been reformated for readability. It may differ from the original.</p>" - ), - "file/fragments/alert-wide" - ); - } - } + if ($lexer !== "json" || $linecount !== 1) { + return $content; + } + + $decoded_json = json_decode($content); + if ($decoded_json === null || $decoded_json === false) { + return $content; } - return $content; + + $pretty_json = json_encode($decoded_json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + if ($pretty_json === false) { + return $content; + } + + $this->output_cache->render_now( + array( + "error_type" => "alert-info", + "error_message" => "<p>The file below has been reformated for readability. It may differ from the original.</p>" + ), + "file/fragments/alert-wide" + ); + + return $pretty_json; } diff --git a/application/service/user.php b/application/service/user.php index 1d922a102..1d678106a 100644 --- a/application/service/user.php +++ b/application/service/user.php @@ -77,4 +77,52 @@ class user { "apikeys" => $ret, ); } + + /** + * Create an invitation key for a user + * @param userid id of the user + * @return key the created invitation key + */ + static public function create_invitation_key($userid) { + $CI =& get_instance(); + + $invitations = $CI->db->select('user') + ->from('actions') + ->where('user', $userid) + ->where('action', 'invitation') + ->count_all_results(); + + if ($invitations + 1 > $CI->config->item('max_invitation_keys')) { + throw new \exceptions\InsufficientPermissionsException("user/invitation-limit", "You can't create more invitation keys at this time."); + } + + $key = random_alphanum(12, 16); + + $CI->db->set(array( + 'key' => $key, + 'user' => $userid, + 'date' => time(), + 'action' => 'invitation' + )) + ->insert('actions'); + + return $key; + } + + /** + * Remove an invitation key belonging to a user + * @param userid id of the user + * @param key key to remove + * @return number of removed keys + */ + static public function delete_invitation_key($userid, $key) { + $CI =& get_instance(); + + $CI->db + ->where('key', $key) + ->where('user', $userid) + ->delete('actions'); + + return $CI->db->affected_rows(); + } } diff --git a/application/test/tests/api_v2/test_api_permissions.php b/application/test/tests/api_v2/test_api_permissions.php index 6df612911..281457c45 100644 --- a/application/test/tests/api_v2/test_api_permissions.php +++ b/application/test/tests/api_v2/test_api_permissions.php @@ -99,7 +99,7 @@ class test_api_permissions extends common { $this->t->is_deeply(array( 'status' => "error", 'error_id' => "api/insufficient-permissions", - 'message' => "Access denied: Access level too low. Required: ${test['wanted_level']}; Have: ${test['have_level']}", + 'message' => "Access denied: Access level too low. Required: {$test['wanted_level']}; Have: {$test['have_level']}", ), $ret, "expected permission error"); } } diff --git a/application/test/tests/api_v2/test_file_create_multipaste.php b/application/test/tests/api_v2/test_file_create_multipaste.php index 8556616d1..2b6e9d8de 100644 --- a/application/test/tests/api_v2/test_file_create_multipaste.php +++ b/application/test/tests/api_v2/test_file_create_multipaste.php @@ -122,4 +122,27 @@ class test_file_create_multipaste extends common { $this->t->is($ret["data"]["total_count"], 1, "total_count correct"); $this->t->is($ret["data"]["deleted_count"], 1, "deleted_count correct"); } + + public function test_create_multipaste_minidlength() + { + $apikey = $this->createUserAndApikey("basic"); + $ret = $this->uploadFile($apikey, "data/tests/small-file"); + $id = $ret["data"]["ids"][0]; + + $ret = $this->uploadFile($apikey, "data/tests/small-file"); + $id2 = $ret["data"]["ids"][0]; + + $ret = $this->CallEndpoint("POST", "file/create_multipaste", array( + "apikey" => $apikey, + "ids[1]" => $id, + "ids[2]" => $id2, + "minimum-id-length" => 42, + )); + $this->expectSuccess("create multipaste", $ret); + + $this->t->isnt($ret["data"]["url_id"], "", "got a multipaste ID"); + $this->t->isnt($ret["data"]["url"], "", "got a multipaste URL"); + + $this->t->ok(strlen($ret["data"]["url_id"]) >= 42, "minimum url length upheld"); + } } diff --git a/application/test/tests/api_v2/test_file_upload.php b/application/test/tests/api_v2/test_file_upload.php index cb2f81b74..07769774f 100644 --- a/application/test/tests/api_v2/test_file_upload.php +++ b/application/test/tests/api_v2/test_file_upload.php @@ -50,8 +50,8 @@ class test_file_upload extends common { $data[] = $this->SendHTTPRequest("GET", $url, ''); } $this->t->ok($data[0] !== $data[1], 'Returned file contents should differ'); - $this->t->ok($data[0] === file_get_contents("data/tests/message1.bin"), "Returned correct data for file 1"); - $this->t->ok($data[1] === file_get_contents("data/tests/message2.bin"), "Returned correct data for file 2"); + $this->t->is($data[0], file_get_contents("data/tests/message1.bin"), "Returned correct data for file 1"); + $this->t->is($data[1], file_get_contents("data/tests/message2.bin"), "Returned correct data for file 2"); } public function test_upload_uploadNothing() @@ -68,4 +68,45 @@ class test_file_upload extends common { ), $ret, "expected reply"); } + public function test_upload_minidlength() + { + $apikey = $this->createUserAndApikey(); + $ret = $this->CallEndpoint("POST", "file/upload", array( + "apikey" => $apikey, + "file[1]" => curl_file_create("data/tests/small-file"), + "minimum-id-length" => 42, + )); + $this->expectSuccess("upload file", $ret); + + foreach ($ret["data"]["urls"] as $url) { + $matches = array(); + preg_match('/\/([^\/]+)\/$/', $url, $matches); + $this->t->ok(strlen($matches[1]) >= 42, "minimum url length upheld"); + } + } + + public function test_upload_bad_minidlength() + { + $apikey = $this->createUserAndApikey(); + + $combinations = [ + "non-numberic minimum-id-length" => "nonumber", + "negative minimum-id-length (-42)" => -42, + "minimum-id-length=0" => 0, + "minimum-id-length=1" => 1, + ]; + foreach ($combinations as $msg => $input) { + $ret = $this->CallEndpoint("POST", "file/upload", array( + "apikey" => $apikey, + "file[1]" => curl_file_create("data/tests/small-file"), + "minimum-id-length" => $input, + )); + $this->expectError("upload file with bad minimum-id-length. Test value: $msg", $ret); + $this->t->is_deeply(array( + 'status' => 'error', + 'error_id' => 'file/bad-minimum-id-length', + 'message' => "Passed parameter 'minimum-id-length' is not a valid integer or too small (min value: 2)", + ), $ret, "expected reply"); + } + } } diff --git a/application/test/tests/test_database_schema.php b/application/test/tests/test_database_schema.php new file mode 100644 index 000000000..02f188e1f --- /dev/null +++ b/application/test/tests/test_database_schema.php @@ -0,0 +1,38 @@ +<?php +/* + * Copyright 2017 Florian "Bluewind" Pritz <bluewind@server-speed.net> + * + * Licensed under AGPLv3 + * (see COPYING for full license text) + * + */ + +namespace test\tests; + +class test_database_schema extends \test\Test { + + public function __construct() + { + parent::__construct(); + } + + public function test_file_storage_bigint() { + $filesize = pow(2, 35) + 1; + + $CI =& get_instance(); + $CI->db->insert("file_storage", array( + "filesize" => $filesize, + "mimetype" => "text/plain", + "hash" => md5("test"), + "date" => time(), + )); + $id = $CI->db->insert_id(); + $db_value = $CI->db->select('filesize') + ->from('file_storage') + ->where('id', $id) + ->get()->result_array()[0]["filesize"]; + $this->t->is(intval($db_value), $filesize, "Large filesize is stored correctly in db"); + } + + +} diff --git a/application/test/tests/test_filebin_helper.php b/application/test/tests/test_filebin_helper.php index 2069f2953..a46d4bc3c 100644 --- a/application/test/tests/test_filebin_helper.php +++ b/application/test/tests/test_filebin_helper.php @@ -24,6 +24,51 @@ class test_filebin_helper extends \test\Test { { } + public function test_expiration_duration() + { + $this->t->is(expiration_duration(60*60*24*2), "2 days", "2 days"); + $this->t->is(expiration_duration(60*60*24), "1 day", "1 day"); + $this->t->is(expiration_duration(60*60*2), "2 hours", "2 hours"); + $this->t->is(expiration_duration(60*60), "1 hour", "1 hour"); + $this->t->is(expiration_duration(60*2), "2 minutes", "2 minutes"); + $this->t->is(expiration_duration(60), "1 minute", "1 minute"); + $this->t->is(expiration_duration(59), "59 seconds", "59 seconds"); + $this->t->is(expiration_duration(1), "1 second", "1 second"); + + $this->t->is(expiration_duration(60*60*24 + 60*60 + 60), "1 day, 1 hour, 1 minute", "1 day, 1 hour, 1 minute"); + $this->t->is(expiration_duration(60*60*24 + 60*60 + 120), "1 day, 1 hour, 2 minutes", "1 day, 1 hour, 2 minutes"); + $this->t->is(expiration_duration(60*60*24 + 60*60*2 + 60), "1 day, 2 hours, 1 minute", "1 day, 2 hours, 1 minute"); + $this->t->is(expiration_duration(60*60*24 + 60*60*2 + 120), "1 day, 2 hours, 2 minutes", "1 day, 2 hours, 2 minutes"); + $this->t->is(expiration_duration(60*60*24*2 + 60*60 + 60), "2 days, 1 hour, 1 minute", "2 days, 1 hour, 1 minute"); + $this->t->is(expiration_duration(60*60*24*2 + 60*60 + 120), "2 days, 1 hour, 2 minutes", "2 days, 1 hour, 2 minutes"); + $this->t->is(expiration_duration(60*60*24*2 + 60*60*2 + 60), "2 days, 2 hours, 1 minute", "2 days, 2 hours, 1 minute"); + $this->t->is(expiration_duration(60*60*24*2 + 60*60*2 + 120), "2 days, 2 hours, 2 minutes", "2 days, 2 hours, 2 minutes"); + + $this->t->is(expiration_duration(60*60*24 + 60*60), "1 day, 1 hour", "1 day, 1 hour"); + $this->t->is(expiration_duration(60*60*24 + 60*60*2), "1 day, 2 hours", "1 day, 2 hours"); + $this->t->is(expiration_duration(60*60*24*2 + 60*60), "2 days, 1 hour", "2 days, 1 hour"); + $this->t->is(expiration_duration(60*60*24*2 + 60*60*2), "2 days, 2 hours", "2 days, 2 hours"); + + $this->t->is(expiration_duration(60*60*24 + 60), "1 day, 1 minute", "1 day, 1 minute"); + $this->t->is(expiration_duration(60*60*24 + 120), "1 day, 2 minutes", "1 day, 2 minutes"); + $this->t->is(expiration_duration(60*60*24*2 + 60), "2 days, 1 minute", "2 days, 1 minute"); + $this->t->is(expiration_duration(60*60*2*24 + 120), "2 days, 2 minutes", "2 days, 2 minutes"); + + $this->t->is(expiration_duration(60*60 + 60), "1 hour, 1 minute", "1 hour, 1 minute"); + $this->t->is(expiration_duration(60*60 + 120), "1 hour, 2 minutes", "1 hour, 2 minutes"); + $this->t->is(expiration_duration(60*60*2 + 60), "2 hours, 1 minute", "2 hours, 1 minute"); + $this->t->is(expiration_duration(60*60*2 + 120), "2 hours, 2 minutes", "2 hours, 2 minutes"); + + $this->t->is(expiration_duration(61), "1 minute, 1 second", "1 minute, 1 second"); + $this->t->is(expiration_duration(62), "1 minute, 2 seconds", "1 minute, 2 seconds"); + $this->t->is(expiration_duration(121), "2 minutes, 1 second", "2 minutes, 1 second"); + $this->t->is(expiration_duration(122), "2 minutes, 2 seconds", "2 minutes, 2 seconds"); + + $this->t->is(expiration_duration(60*60*24 + 60*60*23 + 60*59), "1 day, 23 hours, 59 minutes", "1 day, 23 hours, 59 minutes"); + $this->t->is(expiration_duration(60*60*23 + 60*59), "23 hours, 59 minutes", "23 hours, 59 minutes"); + $this->t->is(expiration_duration(60*60*2 + 60*59), "2 hours, 59 minutes", "2 hours, 59 minutes"); + } + public function test_format_bytes() { $this->t->is(format_bytes(500), "500B", "500B"); @@ -35,20 +80,6 @@ class test_filebin_helper extends \test\Test { $this->t->is(format_bytes(1500*1024*1024*1024*1024*1024), "1500.00PiB", "1500.00PiB"); } - public function test_even_odd() - { - $this->t->is(even_odd(true), "odd", "odd after reset"); - $this->t->is(even_odd(), "even", "even"); - $this->t->is(even_odd(), "odd", "odd"); - $this->t->is(even_odd(true), "odd", "odd after reset"); - } - - public function test_mb_str_pad() - { - $this->t->is(mb_str_pad('test', 6), 'test ', 'Simple test with length=6'); - $this->t->is(mb_str_pad('絫ö', 6), '絫ö ', 'UTF8 test with length=6'); - } - public function test_files_are_equal() { $a1 = FCPATH.'/data/tests/message1.bin'; diff --git a/application/test/tests/test_libraries_image.php b/application/test/tests/test_libraries_image.php index 99a963dea..d6afc64df 100644 --- a/application/test/tests/test_libraries_image.php +++ b/application/test/tests/test_libraries_image.php @@ -28,8 +28,8 @@ class test_libraries_image extends \test\Test { { $this->t->is(\libraries\Image::type_supported('image/png'), true, 'image/png should be supported'); $this->t->is(\libraries\Image::type_supported('image/jpeg'), true, 'image/jpeg should be supported'); - $this->t->is(\libraries\Image::type_supported('application/pdf'), true, 'application/pdf should be supported'); + $this->t->is(\libraries\Image::type_supported('application/pdf'), false, 'application/pdf should not be supported'); $this->t->is(\libraries\Image::type_supported('application/octet-stream'), false, 'application/octet-stream should not be supported'); $this->t->is(\libraries\Image::type_supported('text/plain'), false, 'text/plain should not be supported'); } @@ -45,11 +45,21 @@ class test_libraries_image extends \test\Test { public function test_makeThumb_PDF() { - $img = new \libraries\Image(FCPATH."/data/tests/simple.pdf"); - $img->makeThumb(150, 150); - $thumb = $img->get(IMAGETYPE_JPEG); - - $this->t->ok($thumb !== "", "Got thumbnail"); + try { + $img = new \libraries\Image(FCPATH."/data/tests/simple.pdf"); + $this->t->fail("PDF should not be supported"); + $img->makeThumb(150, 150); + $thumb = $img->get(IMAGETYPE_JPEG); + $this->t->ok($thumb !== "", "Got thumbnail"); + } catch (\exceptions\PublicApiException $e) { + $correct_error = $e->get_error_id() == "libraries/Image/unsupported-image-type"; + $this->t->ok($correct_error, "Should get exception"); + if (!$correct_error) { + // @codeCoverageIgnoreStart + throw $e; + // @codeCoverageIgnoreEnd + } + } } public function test_makeThumb_binaryFile() diff --git a/application/test/tests/test_libraries_procrunner.php b/application/test/tests/test_libraries_procrunner.php index 4e6adf8dd..daac8a2bc 100644 --- a/application/test/tests/test_libraries_procrunner.php +++ b/application/test/tests/test_libraries_procrunner.php @@ -49,7 +49,11 @@ class test_libraries_procrunner extends \test\Test { $p = new \libraries\ProcRunner(['thisCommandDoesNotExist']); $ret = $p->exec(); - $this->t->is($ret['stderr'], "sh: thisCommandDoesNotExist: command not found\n", 'stderr should be empty'); + if (PHP_MAJOR_VERSION >= 8) { + $this->t->is($ret['stderr'], "sh: line 1: thisCommandDoesNotExist: command not found\n", 'stderr should be empty'); + } else { + $this->t->is($ret['stderr'], "sh: thisCommandDoesNotExist: command not found\n", 'stderr should be empty'); + } $this->t->is($ret['stdout'], '', 'stdout should be empty'); $this->t->is($ret['return_code'], 127, 'return code should be 127'); } @@ -95,7 +99,7 @@ class test_libraries_procrunner extends \test\Test { public function test_forbid_stderr() { - $p = new \libraries\ProcRunner(['python', 'thisDoesNotExist']); + $p = new \libraries\ProcRunner(['bash', '-c', 'echo "This is a test error message" >&2; exit 2;']); $p->forbid_stderr(); try { @@ -104,12 +108,12 @@ class test_libraries_procrunner extends \test\Test { } catch (\exceptions\ApiException $e) { $this->t->is($e->get_error_id(), 'procrunner/stderr', "correct exception triggered"); $this->t->is_deeply($e->get_data(), [ - "'python' 'thisDoesNotExist'", + "'bash' '-c' 'echo \"This is a test error message\" >&2; exit 2;'", null, [ 'return_code' => 2, 'stdout' => '', - 'stderr' => "python: can't open file 'thisDoesNotExist': [Errno 2] No such file or directory\n", + 'stderr' => "This is a test error message\n", ], ], "correct exception data"); } diff --git a/application/test/tests/test_service_multipaste_queue.php b/application/test/tests/test_service_multipaste_queue.php index 0427425a0..6bf078d97 100644 --- a/application/test/tests/test_service_multipaste_queue.php +++ b/application/test/tests/test_service_multipaste_queue.php @@ -11,6 +11,11 @@ namespace test\tests; class test_service_multipaste_queue extends \test\Test { + private $session; + private $mfile; + private $mmultipaste; + private $m; + public function __construct() { parent::__construct(); @@ -38,7 +43,7 @@ class test_service_multipaste_queue extends \test\Test { public function test_get() { - $this->session->shouldReceive('userdata')->with("multipaste_queue")->once()->andReturn(false); + $this->session->shouldReceive('userdata')->with("multipaste_queue")->once()->andReturn(null); $this->t->is_deeply($this->m->get(), [], "Fresh queue is empty"); } @@ -54,7 +59,7 @@ class test_service_multipaste_queue extends \test\Test { public function test_append() { - $this->session->shouldReceive('userdata')->with("multipaste_queue")->once()->andReturn(false); + $this->session->shouldReceive('userdata')->with("multipaste_queue")->once()->andReturn(null); $this->mfile->shouldReceive('valid_id')->with('abc')->times(2)->andReturn(true); $this->session->shouldReceive('set_userdata')->with("multipaste_queue", ['abc'])->once(); $this->t->is($this->m->append(['abc']), null, "append([abc]) should succeed"); diff --git a/application/test/tests/test_service_user.php b/application/test/tests/test_service_user.php new file mode 100644 index 000000000..d7e34a71b --- /dev/null +++ b/application/test/tests/test_service_user.php @@ -0,0 +1,65 @@ +<?php +/* + * Copyright 2018 Florian "Bluewind" Pritz <bluewind@server-speed.net> + * + * Licensed under AGPLv3 + * (see COPYING for full license text) + * + */ + +namespace test\tests; + +class test_service_user extends \test\Test { + + public function __construct() { + parent::__construct(); + } + + public function init() { + } + + public function cleanup() { + } + + public function test_invitation_key_delete() { + $CI =& get_instance(); + + $userid = 1; + + $result = $CI->db->select('user, key, action')->from('actions')->get()->result_array(); + $this->t->is_deeply([], $result, "database contains no actions"); + + $key = \service\user::create_invitation_key($userid); + + $result = $CI->db->select('user, key, action')->from('actions')->get()->result_array(); + $this->t->is_deeply([['user' => "".$userid, 'key' => $key, 'action' => 'invitation']], $result, "database contains new key"); + + $ret = \service\user::delete_invitation_key($userid+1, $key); + $this->t->is(0, $ret, "Should have removed no keys because incorrect user/key"); + $result = $CI->db->select('user, key, action')->from('actions')->get()->result_array(); + $this->t->is_deeply([['user' => "".$userid, 'key' => $key, 'action' => 'invitation']], $result, "database contains new key after incorrect deletion"); + + $ret = \service\user::delete_invitation_key($userid+1, "foobar-"); + $this->t->is(0, $ret, "Should have removed no keys because incorrect user/key"); + $result = $CI->db->select('user, key, action')->from('actions')->get()->result_array(); + $this->t->is_deeply([['user' => "".$userid, 'key' => $key, 'action' => 'invitation']], $result, "database contains new key after incorrect deletion"); + + $ret = \service\user::delete_invitation_key($userid+1, ""); + $this->t->is(0, $ret, "Should have removed no keys because incorrect user/key"); + $result = $CI->db->select('user, key, action')->from('actions')->get()->result_array(); + $this->t->is_deeply([['user' => "".$userid, 'key' => $key, 'action' => 'invitation']], $result, "database contains new key after incorrect deletion"); + + $ret = \service\user::delete_invitation_key($userid, ""); + $this->t->is(0, $ret, "Should have removed no keys because incorrect user/key"); + $result = $CI->db->select('user, key, action')->from('actions')->get()->result_array(); + $this->t->is_deeply([['user' => "".$userid, 'key' => $key, 'action' => 'invitation']], $result, "database contains new key"); + + $ret = \service\user::delete_invitation_key($userid, $key); + $this->t->is(1, $ret, "One key should be removed"); + $result = $CI->db->select('user, key, action')->from('actions')->get()->result_array(); + $this->t->is_deeply([], $result, "key has been deleted"); + + } + +} + diff --git a/application/third_party/index.html b/application/third_party/index.html index c942a79ce..bcb7cae34 100644 --- a/application/third_party/index.html +++ b/application/third_party/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/third_party/mockery b/application/third_party/mockery -Subproject d141c5b1b302d4d746e38ccc95ffe215129a855 +Subproject 20cab678faed06fac225193be281ea0fddb43b9 diff --git a/application/third_party/test-more-php/Test-More-OO.php b/application/third_party/test-more-php/Test-More-OO.php index 005c7dc01..6020288bd 100755 --- a/application/third_party/test-more-php/Test-More-OO.php +++ b/application/third_party/test-more-php/Test-More-OO.php @@ -87,6 +87,11 @@ class TestMore extends TestSimple { $ret = ob_get_clean(); $ret = preg_replace("/^[^\n]*\n/", "", $ret); $ret = preg_replace("/\n$/", "", $ret); + # replace unprintable characters with questionmarks + $old = ini_get("mbstring.substitute_character"); + ini_set("mbstring.substitute_character", "?"); + $ret = mb_convert_encoding($ret, 'UTF-8', 'UTF-8'); + ini_set("mbstring.substitute_character", $old); return $ret; } @@ -210,7 +215,7 @@ class TestMore extends TestSimple { if ( is_int($this->NumberOfTests) ) { $unrun = $this->NumberOfTests - (int)$this->TestsRun; $plural = $unrun == 1 ? '' : 's'; - $unrunmsg = "# Looks like ${unrun} planned test${plural} never ran.\n"; + $unrunmsg = "# Looks like {$unrun} planned test{$plural} never ran.\n"; } $gasp = $this->LastFail . "\n" @@ -263,7 +268,7 @@ class TestMore extends TestSimple { $error = " Syntax check for '$module' failed"; } } else { - $error = " Cannot find ${type}d file '$module'"; + $error = " Cannot find {$type}d file '$module'"; } $pass = !$retval && $done; diff --git a/application/third_party/test-more-php/Test-Simple-OO.php b/application/third_party/test-more-php/Test-Simple-OO.php index 9bbe4aada..a8302d208 100755 --- a/application/third_party/test-more-php/Test-Simple-OO.php +++ b/application/third_party/test-more-php/Test-Simple-OO.php @@ -73,6 +73,7 @@ class TestSimple { protected $NumberOfTests; protected $CurrentTestNumber; protected $Filter; + protected $LastFail; protected $notes; @@ -103,7 +104,7 @@ class TestSimple { $skipinfo = ''; if ($this->NumberOfTests === 'skip_all') $skipinfo = ' # '.$this->SkipAllReason; - echo "1..${NumberOfTests}${skipinfo}\n"; + echo "1..{$NumberOfTests}{$skipinfo}\n"; $this->NumberOfTests = $NumberOfTests; return; diff --git a/application/views/errors/cli/error_404.php b/application/views/errors/cli/error_404.php new file mode 100644 index 000000000..6984b61e9 --- /dev/null +++ b/application/views/errors/cli/error_404.php @@ -0,0 +1,8 @@ +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + +echo "\nERROR: ", + $heading, + "\n\n", + $message, + "\n\n";
\ No newline at end of file diff --git a/application/views/errors/cli/error_db.php b/application/views/errors/cli/error_db.php new file mode 100644 index 000000000..2ff43ffc7 --- /dev/null +++ b/application/views/errors/cli/error_db.php @@ -0,0 +1,8 @@ +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + +echo "\nDatabase error: ", + $heading, + "\n\n", + $message, + "\n\n";
\ No newline at end of file diff --git a/application/views/errors/cli/error_exception.php b/application/views/errors/cli/error_exception.php new file mode 100644 index 000000000..efa6a66d1 --- /dev/null +++ b/application/views/errors/cli/error_exception.php @@ -0,0 +1,21 @@ +<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?> + +An uncaught Exception was encountered + +Type: <?php echo get_class($exception), "\n"; ?> +Message: <?php echo $message, "\n"; ?> +Filename: <?php echo $exception->getFile(), "\n"; ?> +Line Number: <?php echo $exception->getLine(); ?> + +<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?> + +Backtrace: +<?php foreach ($exception->getTrace() as $error): ?> +<?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?> + File: <?php echo $error['file'], "\n"; ?> + Line: <?php echo $error['line'], "\n"; ?> + Function: <?php echo $error['function'], "\n\n"; ?> +<?php endif ?> +<?php endforeach ?> + +<?php endif ?> diff --git a/application/views/errors/cli/error_general.php b/application/views/errors/cli/error_general.php new file mode 100644 index 000000000..6984b61e9 --- /dev/null +++ b/application/views/errors/cli/error_general.php @@ -0,0 +1,8 @@ +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + +echo "\nERROR: ", + $heading, + "\n\n", + $message, + "\n\n";
\ No newline at end of file diff --git a/application/views/errors/cli/error_php.php b/application/views/errors/cli/error_php.php new file mode 100644 index 000000000..8a24b6491 --- /dev/null +++ b/application/views/errors/cli/error_php.php @@ -0,0 +1,21 @@ +<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?> + +A PHP Error was encountered + +Severity: <?php echo $severity, "\n"; ?> +Message: <?php echo $message, "\n"; ?> +Filename: <?php echo $filepath, "\n"; ?> +Line Number: <?php echo $line; ?> + +<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?> + +Backtrace: +<?php foreach (debug_backtrace() as $error): ?> +<?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?> + File: <?php echo $error['file'], "\n"; ?> + Line: <?php echo $error['line'], "\n"; ?> + Function: <?php echo $error['function'], "\n\n"; ?> +<?php endif ?> +<?php endforeach ?> + +<?php endif ?> diff --git a/application/errors/index.html b/application/views/errors/cli/index.html index c942a79ce..bcb7cae34 100644 --- a/application/errors/index.html +++ b/application/views/errors/cli/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/views/errors/html/error_404.php b/application/views/errors/html/error_404.php new file mode 100644 index 000000000..b71da106d --- /dev/null +++ b/application/views/errors/html/error_404.php @@ -0,0 +1,3 @@ +<?php +$title = "404 Page Not Found"; +include VIEWPATH."errors/html/error_general.php"; diff --git a/application/views/errors/html/error_db.php b/application/views/errors/html/error_db.php new file mode 100644 index 000000000..adff63559 --- /dev/null +++ b/application/views/errors/html/error_db.php @@ -0,0 +1,3 @@ +<?php +$title = "Database Error"; +include VIEWPATH."errors/html/error_general.php"; diff --git a/application/views/errors/html/error_exception.php b/application/views/errors/html/error_exception.php new file mode 100644 index 000000000..befa12955 --- /dev/null +++ b/application/views/errors/html/error_exception.php @@ -0,0 +1,32 @@ +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); +?> + +<div style="border:1px solid #dd4814;padding-left:20px;margin:10px 0;"> + + <h4>An uncaught Exception was encountered</h4> + + <p>Type: <?php echo get_class($exception); ?></p> + <p>Message: <?php echo $message; ?></p> + <p>Filename: <?php echo $exception->getFile(); ?></p> + <p>Line Number: <?php echo $exception->getLine(); ?></p> + + <?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?> + + <p>Backtrace:</p> + <?php foreach ($exception->getTrace() as $error): ?> + + <?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?> + + <p style="margin-left:10px"> + File: <?php echo $error['file']; ?><br /> + Line: <?php echo $error['line']; ?><br /> + Function: <?php echo $error['function']; ?> + </p> + <?php endif ?> + + <?php endforeach ?> + + <?php endif ?> + +</div> diff --git a/application/views/errors/html/error_general.php b/application/views/errors/html/error_general.php new file mode 100644 index 000000000..637a1fd35 --- /dev/null +++ b/application/views/errors/html/error_general.php @@ -0,0 +1,127 @@ +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); + +// fancy error page only works if we can load helpers +if (class_exists("CI_Controller") && !isset($GLOBALS["is_error_page"]) && isset(get_instance()->load)) { + if (!isset($title)) { + $title = "Error"; + } + $GLOBALS["is_error_page"] = true; + + $CI =& get_instance(); + $CI->load->helper("filebin"); + $CI->load->helper("url"); + + if (is_cli()) { + $message = str_replace("</p>", "</p>\n", $message); + $message = strip_tags($message); + echo "$heading: $message\n"; + exit(); + } + + include APPPATH.'views/header.php'; + + ?> + <div class="error"> + <h1><?php echo $heading; ?></h1> + <?php echo $message; ?> + </div> + + <?php + include APPPATH.'views/footer.php'; +} elseif (php_sapi_name() === 'cli' OR defined('STDIN')) { + echo "# $heading\n"; + $msg = strip_tags(str_replace("<br>", "\n", $message)); + foreach (explode("\n", $msg) as $line) { + echo "# $line\n"; + } + exit(255); +} else { + // default CI error page +?><!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Error</title> + <style type="text/css"> + + ::selection { background-color: #f07746; color: #fff; } + ::-moz-selection { background-color: #f07746; color: #fff; } + + body { + background-color: #fff; + margin: 40px auto; + max-width: 1024px; + font: 16px/24px normal "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #808080; + } + + a { + color: #dd4814; + background-color: transparent; + font-weight: normal; + text-decoration: none; + } + + a:hover { + color: #97310e; + } + + h1 { + color: #fff; + background-color: #dd4814; + border-bottom: 1px solid #d0d0d0; + font-size: 22px; + font-weight: bold; + margin: 0 0 14px 0; + padding: 5px 15px; + line-height: 40px; + } + + h2 { + color:#404040; + margin:0; + padding:0 0 10px 0; + } + + code { + font-family: Consolas, Monaco, Courier New, Courier, monospace; + font-size: 13px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + color: #002166; + display: block; + margin: 14px 0 14px 0; + padding: 12px 10px 12px 10px; + } + + #container { + margin: 10px; + border: 1px solid #d0d0d0; + box-shadow: 0 0 8px #d0d0d0; + border-radius: 4px; + } + + p { + margin: 0 0 10px; + padding:0; + } + + #body { + margin: 0 15px 0 15px; + min-height: 96px; + } + </style> +</head> +<body> + <div id="container"> + <h1><?php echo $heading; ?></h1> + <div id="body"> + <?php echo $message; ?> + </div> + </div> +</body> +</html> +<?php +} diff --git a/application/views/errors/html/error_php.php b/application/views/errors/html/error_php.php new file mode 100644 index 000000000..8b445ef39 --- /dev/null +++ b/application/views/errors/html/error_php.php @@ -0,0 +1,33 @@ +<?php +defined('BASEPATH') OR exit('No direct script access allowed'); +?> + +<div style="border:1px solid #dd4814;padding-left:20px;margin:10px 0;"> + + <h4>A PHP Error was encountered</h4> + + <p>Severity: <?php echo $severity; ?></p> + <p>Message: <?php echo $message; ?></p> + <p>Filename: <?php echo $filepath; ?></p> + <p>Line Number: <?php echo $line; ?></p> + + <?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?> + + <p>Backtrace:</p> + <?php foreach (debug_backtrace() as $error): ?> + + <?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?> + + <p style="margin-left:10px"> + File: <?php echo $error['file'] ?><br /> + Line: <?php echo $error['line'] ?><br /> + Function: <?php echo $error['function'] ?> + </p> + + <?php endif ?> + + <?php endforeach ?> + + <?php endif ?> + +</div> diff --git a/application/views/errors/html/index.html b/application/views/errors/html/index.html new file mode 100644 index 000000000..bcb7cae34 --- /dev/null +++ b/application/views/errors/html/index.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <title>403 Forbidden</title> +</head> +<body> + +<p>Directory access is forbidden.</p> + +</body> +</html> diff --git a/application/views/errors/index.html b/application/views/errors/index.html new file mode 100644 index 000000000..bcb7cae34 --- /dev/null +++ b/application/views/errors/index.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <title>403 Forbidden</title> +</head> +<body> + +<p>Directory access is forbidden.</p> + +</body> +</html> diff --git a/application/views/file/deleted.php b/application/views/file/deleted.php index 8a5818f2d..741824e58 100644 --- a/application/views/file/deleted.php +++ b/application/views/file/deleted.php @@ -2,7 +2,7 @@ <?php if (!empty($errors)) { echo "<p>"; foreach ($errors as $error) { - echo "${error["id"]}: ${error["reason"]}<br>\n"; + echo "{$error["id"]}: {$error["reason"]}<br>\n"; } echo "</p>"; } ?> diff --git a/application/views/file/upload_form.php b/application/views/file/upload_form.php index b7d6fbabd..a466e6640 100644 --- a/application/views/file/upload_form.php +++ b/application/views/file/upload_form.php @@ -14,7 +14,7 @@ <div class="tab-pane active" id="text-upload-tab-1"> <div class="panel panel-default"> <div class="panel-heading"> - <input type="text" name="filename[1]" class="form-control" placeholder="Filename/title (default: stdin)"> + <input type="text" name="filename[1]" class="form-control" placeholder="Filename/title (default: stdin)" value="<?php if (isset($textarea_filename)) { echo htmlspecialchars($textarea_filename); } ?>"> </div> <textarea name="content[1]" class="form-control text-upload" placeholder="Paste content"><?php if (isset($textarea_content)) { @@ -53,7 +53,7 @@ <p><button type="submit" id="upload_button" class="btn btn-primary">Upload/Paste it!</button></p> <p> Uploads/pastes are <?php if ($upload_max_age > 0) { - echo "deleted after ".$upload_max_age." days"; + echo "deleted after ".expiration_duration($upload_max_age); if ($small_upload_size > 0) { echo " unless they are smaller than ".format_bytes($small_upload_size); } @@ -119,7 +119,7 @@ <h3>Special filenames:</h3> <dl class="dl-horizontal"> - <dt>*.asciinema.json</dt><dd>treat the file as an <a href="https://asciinema.org/">asciinema screencast</a> and display a videoplayer for it</dd> + <dt>*.asciinema.json<br>or *.cast</dt><dd>treat the file as an <a href="https://asciinema.org/">asciinema screencast</a> and display a videoplayer for it</dd> </dl> </div> @@ -155,14 +155,20 @@ <p> Arch Linux: <code>pacman -S fb-client</code><br /> - Gentoo: Add <a href="https://git.holgersson.xyz/holgersson-overlay/tree/README">this overlay</a> and run <code>emerge -a fb-client</code><br /> + Gentoo: Add <a href="https://git.holgersson.xyz/foss/holgersson-overlay/src/branch/master/README.rst">this overlay</a> and run <code>emerge -a fb-client</code><br /> FreeBSD: <code>pkg install fb</code><br /> + OpenSUSE: <a href="https://build.opensuse.org/package/show/home:mwilhelmy/fb-client">home:mwilhelmy / fb-client</a> </p> <h4>Android</h4> <p> + Development: <a href="https://git.myservermanager.com/varakh/fbmobile">v4rakh/fbmobile @ git.myservermanager.com</a><br> + Google Play: <a href="https://play.google.com/store/apps/details?id=de.varakh.fbmobile">FileBin @ Google Play</a><br> + </p> + + <p> + Unmaintained Legacy Client:<br> Development: <a href="https://github.com/sebastianrakel/fb-client-android">sebastianrakel/fb-client-android @ Github</a><br> - Google Playstore: <a href="https://play.google.com/store/apps/details?id=eu.devunit.fb_client">fb-client Android @ Google Play</a><br> F-Droid Store: <a href="https://f-droid.org/repository/browse/?fdid=eu.devunit.fb_client">fb-client Android @ F-Droid</a><br> </p> </div> diff --git a/application/views/index.html b/application/views/index.html index c942a79ce..bcb7cae34 100644 --- a/application/views/index.html +++ b/application/views/index.html @@ -1,4 +1,5 @@ -<html> +<!DOCTYPE html> +<html lang="en"> <head> <title>403 Forbidden</title> </head> @@ -7,4 +8,4 @@ <p>Directory access is forbidden.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/application/views/user/invite.php b/application/views/user/invite.php index d3e2fb7a6..042ba0b61 100644 --- a/application/views/user/invite.php +++ b/application/views/user/invite.php @@ -26,6 +26,12 @@ <td><?php echo $i++; ?></td> <td><?php echo anchor("user/register/".$item["key"], $item["key"]) ?></td> <td><?php echo date("Y/m/d H:i", $item["date"]) ?></td> + <td> + <?php echo form_open('user/delete_invitation_key'); ?> + <input class="btn btn-danger btn-xs" type="submit" value="Delete" name="delete" /> + <input type="hidden" name="key" value="<?php echo $item["key"]; ?>" /> + </form> + </td> </tr> <?php endforeach; ?> </tbody> diff --git a/application/views/user/register.php b/application/views/user/register.php index af4558ff9..0f03a2f00 100644 --- a/application/views/user/register.php +++ b/application/views/user/register.php @@ -9,6 +9,7 @@ <label class="control-label col-lg-2 col-md-2" for="inputUsername">Username</label> <div class="col-lg-5 col-md-5"> <input type="text" id="inputUsername" name="username" placeholder="Username" value="<?php echo $values["username"]; ?>" class="form-control"> + <span class="help-block">The username may contain up to 32 chars of a-z0-9 (only lowercase characters).</span> </div> </div> </div> |