", '','','','',' ','','','', '','','','','','','','', '','','','','','','','', '','','' ); $With = array( ''','"','<','>', '€','‚','ƒ','„','…','†','‡','ˆ', '‰','Š','‹','Œ','Ž','‘','’','“', '”','•','–','—','˜','™','š','›', 'œ','ž','Ÿ' ); $Str = str_replace($Replace, $With, $Str); } return $Str; } /** * Send a message to an IRC bot listening on SOCKET_LISTEN_PORT * * @param string $Raw An IRC protocol snippet to send. */ function send_irc($Channels = null, $Message = '') { $ENV = ENV::go(); // Check if IRC is enabled if (!$ENV->FEATURE_IRC || !$Channels) { return false; } # The fn takes an array or string $Dest = []; # Quick missed connection fix if (is_string($Channels)) { $Channels = explode(' ', $Channels); } # Strip leading #channel hash foreach ($Channels as $c) { array_push($Dest, preg_replace('/^#/', '', $c)); } # Specific to AB's kana bot # https://github.com/anniemaybytes/kana $Command = implode('-', $Dest) . '|%|' . html_entity_decode( display_str($Message), ENT_QUOTES ); # Original input sanitization $Command = str_replace(array("\n", "\r"), '', $Command); # Send the raw echo $IRCSocket = fsockopen(SOCKET_LISTEN_ADDRESS, SOCKET_LISTEN_PORT); fwrite($IRCSocket, $Command); fclose($IRCSocket); } /** * notify() * Formerly in sections/error/index.php */ function notify($Channel, $Message) { $ENV = ENV::go(); global $LoggedUser; # Redirect dev messages to debug channel if ($ENV->DEV) { $Channel = $ENV->DEBUG_CHAN; } # send_irc( $Channel, $Message . " error by " . (!empty($LoggedUser['ID']) ? site_url() . "user.php?id=".$LoggedUser['ID'] . " (" . $LoggedUser['Username'] . ")" : $_SERVER['REMOTE_ADDR'] . " (" . ")") . " accessing https://" . SITE_DOMAIN . "" . $_SERVER['REQUEST_URI'] . (!empty($_SERVER['HTTP_REFERER']) ? " from " . $_SERVER['HTTP_REFERER'] : '') ); } /** * Advanced error handling * * Displays an HTTP status code with description and triggers an error. * If you use your own string for $Error, it becomes the error description. * * @param int|string $Error Error type * The available HTTP status codes are * - Client: [ 400, 403, 404, 405, 408, 413, 429 ] * - Server: [ 500, 502, 504 ] * - Gazelle: [ -1, 0, !! ] * * @param boolean $NoHTML If true, the header/footer won't be shown, just the error. * @param string $Log If true, the user is given a link to search $Log in the site log. * @param boolean $Debug If true, print bug reporting instructions and a stack trace. * @param boolean $JSON If true, print the error as a JSON response. */ function error($Error = 1, $NoHTML = false, $Log = false, $Debug = true) # , $JSON = false) { $ENV = ENV::go(); # Error out on erroneous $Error (!$Error || $Error === null) ?? trigger_error('No $Error.', E_USER_ERROR); (!is_int($Error) || !is_string($Error)) ?? trigger_error('$Error must be int or string.', E_USER_ERROR); # Formerly in sections/error/index.php if (!empty($_GET['e']) && is_int($_GET['e'])) { # Request error, i.e., /nonexistent_page.php $Error = $_GET['e']; } # https://en.wikipedia.org/wiki/List_of_HTTP_status_codes switch ($Error) { /** * Client errors */ case 400: case 1: # Probably the user's fault $Title = '400 Bad Request'; $Message = 'The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, size too large, invalid request message framing, or deceptive request routing).'; break; case 403: $Title = '403 Forbidden'; $Message = 'The request contained valid data and was understood by the server, but the server is refusing action. This may be due to the user not having the necessary permissions for a resource or needing an account of some sort, or attempting a prohibited action (e.g., creating a duplicate record where only one is allowed). The request should not be repeated.'; if (substr($_SERVER['REQUEST_URI'], 0, 9) !== '/static/') { notify($ENV->DEBUG_CHAN, $Title); } break; case 404: $Title = '404 Not Found'; $Message = 'The requested resource could not be found but may be available in the future. Subsequent requests by the client are permissible.'; // Hide alerts for missing images and static requests if (!preg_match( "/\.(ico|jpg|jpeg|gif|png)$/", $_SERVER['REQUEST_URI'] ) && substr($_SERVER['REQUEST_URI'], 0, 9) !== '/static/') { notify($ENV->DEBUG_CHAN, $Title); } break; case 405: $Title = '405 Method Not Allowed'; $Message = 'A request method is not supported for the requested resource; for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource.'; notify($ENV->DEBUG_CHAN, $Title); break; case 408: $Title = '408 Request Timeout'; $Message = 'The server timed out waiting for the request. According to HTTP specifications: "The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."'; break; case 413: $Title = '413 Payload Too Large'; $Message = 'The request is larger than the server is willing or able to process.'; notify($ENV->DEBUG_CHAN, $Title); break; case 429: $Title = '429 Too Many Requests'; $Message = 'The user has sent too many requests in a given amount of time.'; notify($ENV->DEBUG_CHAN, $Title); break; /** * Server errors */ case 500: $Title = '500 Internal Server Error'; $Message = 'A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.'; break; case 502: $Title = '502 Bad Gateway'; $Message = 'The server was acting as a gateway or proxy and received an invalid response from the upstream server.'; notify($ENV->DEBUG_CHAN, $Title); break; case 504: $Title = '504 Gateway Timeout'; $Message = 'The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.'; notify($ENV->DEBUG_CHAN, $Title); break; /** * Gazelle errors */ case -1: #case 0: # Matches custom error strings $Title = 'Invalid Input'; $Message = 'Something was wrong with the input provided with your request, and the server is refusing to fulfill it.'; notify($ENV->DEBUG_CHAN, 'PHP-0'); break; case '!!': $Title = 'Unexpected Error'; $Message = 'You have encountered an unexpected error.'; notify($ENV->DEBUG_CHAN, 'unexpected'); break; default: $Title = 'Other Error'; $Message = "A function supplied its own error message: $Error"; notify($ENV->DEBUG_CHAN, $Message); } # Normalize whitespace before adding features $Message = preg_replace('/\s{2,}/', ' ', $Message); /** * JSON error output */ /* if ($JSON) { print json_encode( array( 'status' => 'error', 'response' => $Message ) ); } */ /** * Append $Log * Formerly in sections/error/index.php */ if ($Log ?? false) { $Message .= " Search Log"; } /** * Append $Debug */ if ($Debug ?? false) { $DateTime = strftime('%c', $_SERVER['REQUEST_TIME']); $BackTrace = debug_string_backtrace(); $Message .= ($NoHTML) ? $BackTrace : <<
``` $DateTime {$_SERVER['SERVER_PROTOCOL']} {$_SERVER['REQUEST_METHOD']} $Title {$_SERVER['SCRIPT_FILENAME']} {$_SERVER['REQUEST_URI']} $BackTrace ```HTML; } /** * Display HTML * Formerly in sections/error/index.php */ if (empty($NoHTML)) { View::show_header($Title); echo $HTML = <<
$Message