summaryrefslogtreecommitdiffstats
path: root/application
diff options
context:
space:
mode:
Diffstat (limited to 'application')
-rw-r--r--application/.htaccess7
-rw-r--r--application/cache/.htaccess1
-rw-r--r--application/cache/index.html5
-rw-r--r--application/config/autoload.php67
-rw-r--r--application/config/config.php317
-rw-r--r--application/config/constants.php78
-rw-r--r--application/config/doctypes.php35
-rw-r--r--application/config/example/config-local.php3
-rw-r--r--application/config/example/database.php86
-rw-r--r--application/config/foreign_chars.php122
-rw-r--r--application/config/hooks.php11
-rw-r--r--application/config/index.html5
-rw-r--r--application/config/memcached.php19
-rw-r--r--application/config/migration.php64
-rw-r--r--application/config/mimes.php278
-rw-r--r--application/config/profiler.php11
-rw-r--r--application/config/routes.php42
-rw-r--r--application/config/smileys.php66
-rw-r--r--application/config/user_agents.php357
-rw-r--r--application/controllers/Api.php (renamed from application/controllers/api.php)47
-rw-r--r--application/controllers/Main.php (renamed from application/controllers/file/file_default.php)169
-rw-r--r--application/controllers/Tools.php (renamed from application/controllers/tools.php)27
-rw-r--r--application/controllers/User.php (renamed from application/controllers/user.php)90
-rw-r--r--application/controllers/api/api_controller.php7
-rw-r--r--application/controllers/api/v2/api_info.php2
-rw-r--r--application/controllers/api/v2/file.php48
-rw-r--r--application/controllers/api/v2/user.php32
-rw-r--r--application/controllers/file/Multipaste.php (renamed from application/controllers/file/multipaste.php)11
-rw-r--r--application/controllers/index.html5
-rw-r--r--application/core/MY_Controller.php19
-rw-r--r--application/core/MY_Input.php4
-rw-r--r--application/core/index.html5
-rw-r--r--application/errors/error_404.php3
-rw-r--r--application/errors/error_db.php3
-rw-r--r--application/errors/error_general.php104
-rw-r--r--application/errors/error_php.php11
-rw-r--r--application/helpers/filebin_helper.php158
-rw-r--r--application/helpers/index.html5
-rw-r--r--application/hooks/index.html5
-rw-r--r--application/index.html5
-rw-r--r--application/language/english/index.html5
-rw-r--r--application/language/index.html5
-rw-r--r--application/libraries/Customautoloader.php2
-rw-r--r--application/libraries/Ddownload/Ddownload.php2
-rw-r--r--application/libraries/Ddownload/drivers/Ddownload_php.php4
-rw-r--r--application/libraries/Duser/Duser.php2
-rw-r--r--application/libraries/Duser/drivers/Duser_db.php12
-rw-r--r--application/libraries/Duser/drivers/Duser_ldap.php17
-rw-r--r--application/libraries/ExceptionHandler.php12
-rw-r--r--application/libraries/Image/Drivers/GD.php4
-rw-r--r--application/libraries/Image/Drivers/imagemagick.php11
-rw-r--r--application/libraries/Pygments.php9
-rw-r--r--application/libraries/index.html5
-rw-r--r--application/logs/index.html5
-rw-r--r--application/migrations/019_change_filesize_type.php51
-rw-r--r--application/migrations/020_update_session_table.php45
-rw-r--r--application/migrations/021_change_charset.php28
-rw-r--r--application/models/Mfile.php (renamed from application/models/mfile.php)4
-rw-r--r--application/models/Mmultipaste.php (renamed from application/models/mmultipaste.php)1
-rw-r--r--application/models/Muser.php (renamed from application/models/muser.php)76
-rw-r--r--application/models/index.html5
-rw-r--r--application/service/files.php132
-rw-r--r--application/service/multipaste_queue.php6
-rw-r--r--application/service/renderer.php41
-rw-r--r--application/service/user.php48
-rw-r--r--application/test/tests/api_v2/test_api_permissions.php2
-rw-r--r--application/test/tests/api_v2/test_file_create_multipaste.php23
-rw-r--r--application/test/tests/api_v2/test_file_upload.php45
-rw-r--r--application/test/tests/test_database_schema.php38
-rw-r--r--application/test/tests/test_filebin_helper.php59
-rw-r--r--application/test/tests/test_libraries_image.php22
-rw-r--r--application/test/tests/test_libraries_procrunner.php12
-rw-r--r--application/test/tests/test_service_multipaste_queue.php9
-rw-r--r--application/test/tests/test_service_user.php65
-rw-r--r--application/third_party/index.html5
m---------application/third_party/mockery0
-rwxr-xr-xapplication/third_party/test-more-php/Test-More-OO.php9
-rwxr-xr-xapplication/third_party/test-more-php/Test-Simple-OO.php3
-rw-r--r--application/views/errors/cli/error_404.php8
-rw-r--r--application/views/errors/cli/error_db.php8
-rw-r--r--application/views/errors/cli/error_exception.php21
-rw-r--r--application/views/errors/cli/error_general.php8
-rw-r--r--application/views/errors/cli/error_php.php21
-rw-r--r--application/views/errors/cli/index.html (renamed from application/errors/index.html)5
-rw-r--r--application/views/errors/html/error_404.php3
-rw-r--r--application/views/errors/html/error_db.php3
-rw-r--r--application/views/errors/html/error_exception.php32
-rw-r--r--application/views/errors/html/error_general.php127
-rw-r--r--application/views/errors/html/error_php.php33
-rw-r--r--application/views/errors/html/index.html11
-rw-r--r--application/views/errors/index.html11
-rw-r--r--application/views/file/deleted.php2
-rw-r--r--application/views/file/upload_form.php16
-rw-r--r--application/views/index.html5
-rw-r--r--application/views/user/invite.php6
-rw-r--r--application/views/user/register.php1
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>