diff options
Diffstat (limited to 'it.class')
-rw-r--r-- | it.class | 28 |
1 files changed, 18 insertions, 10 deletions
@@ -155,17 +155,20 @@ static function timerlog($label = '') * |graceperiod|timewindow|------> * id x x x m x x x x */ -static function error($p = array()) +static function error($p = array(), $extra = null) { $p = $origp = (array)$p; $p['title'] = $p[0] ?: $p['title']; # handle 'it_error' => "oops" that was cast to array on the way $p['title'] = grapheme_substr($p['title'], 0, 2000); + if ($extra) + it::error('extraneous params passed to it::error'); + foreach (array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10), 1) as $level) if ($level["class"] . $level["type"] . $level["function"] == "it::error") return null; # prevent recursion - if (!error_reporting() || $p[0] === false || $p['title'] === false) # called with @ or suppressed + if (error_reporting() == @error_reporting() || $p[0] === false || $p['title'] === false) # called with @ or suppressed return $p['fatal'] ? self::_exit($p) : null; if ($_SERVER['REMOTE_ADDR']) @@ -260,9 +263,9 @@ static function error($p = array()) ($p['omitdebuginfo'] >= 2 ? "" : ($url && !$toscreen? "Title: {$p['title']}\nUrl: $url\n" : "") . ($trace ? ($sendmail ? "" : " ") . "Trace: $trace\n" : "")) . (!$sendmail || $p['omitdebuginfo'] >= 2 ? "" : "Host: " . getenv('HOSTNAME') . " at " . date("Y-m-d H:i:s") . (($t = time() - $_SERVER['REQUEST_TIME']) ? " (invoked {$t}s before)" : "") . "\n") . # no it::date() due to time- debug param - self::$error_context . + ($sendmail ? self::$error_context : "") . ($p['id'] ? "Filter: timewindow=" . $p['graceperiod'] . "-" . ($p['graceperiod'] + $p['timewindow']) . " (previous err: " . it::date('', $errstamp) . ")\n" : "") . - (!$origp['blockmail'] || $p['omitdebuginfo'] ? "" : "Block-resend: " . $origp['blockmail'] . " seconds\n") . + (!$origp['blockmail'] || $p['omitdebuginfo'] || $toscreen ? "" : "Block-resend: " . $origp['blockmail'] . " seconds\n") . ($p['body'] ? ($p['omitdebuginfo'] ? "" : "Body:\n") . trim($p['body'])."\n\n" : ""); if ($sendmail) # we're mailing: send maximum info @@ -275,10 +278,13 @@ static function error($p = array()) if ($level >= $p['backtraceskip'] && $tracesize < 100000 && ($tracesize += strlen(print_r($stackframe, true))) < 100000) # save mem $stackframes[] = $stackframe; + $rawpost = $_SERVER['REQUEST_METHOD'] == "POST" && !it::match('application/x-www-form-urlencoded|multipart/form-data', $_SERVER['CONTENT_TYPE']) ? it::file_get_contents("php://input") : ""; + $body .= ($trace and $t = it::exec('grep -h {0} `ls /tmp/alertdata/alertlog-*|tail -3` /dev/null 2>/dev/null | grep ^2 | cut -d : -f 1-2 | sort | uniq -c | tail -10', $trace)) ? "Histogram: (last 10 affected minutes in 3 days)\n$t" : ""; $body .= "\n"; $body .= $_GET ? "\$_GET: " . var_export($_GET, true) . "\n\n" : ""; $body .= $_POST ? "\$_POST: " . var_export($_POST, true) . "\n\n" : ""; + $body .= $rawpost ? "\$rawpost: " . var_export($rawpost, true) . "\n\n" : ""; $body .= $_COOKIE ? "\$_COOKIE: " . var_export($_COOKIE, true) . "\n\n" : ""; $body .= $_SERVER['REMOTE_ADDR'] ? "" : "Pstree:\n" . it::exec("pstree -als " . getmypid() . " | head -n -3") . "\n"; $body .= $_SERVER ? "\$_SERVER: " . var_export($_SERVER, true) . "\n\n" : ""; @@ -547,7 +553,7 @@ static function any2utf8($value, $errprefix = "") if (grapheme_strlen($value) === null) list($value, $error) = array(utf8_encode($value), utf8_encode("incorrect utf8-encoding. input=$value")); if (preg_match('/\xc3[\x82\x83]\xc2[\x82\x83\xbc\xa9\xa4\xb6\xa8\xa2\xa0\xb4\xaa\xa7\x84\xab\xae\x9c\xaf\x96\xb2\xbb\xb9\x9f]/', $value)) - list($value, $error) = array(it::any2utf8(preg_replace_callback('/\xc3[\x82\x83]\xc2[\x82\x83\xbc\xa9\xa4\xb6\xa8\xa2\xa0\xb4\xaa\xa7\x84\xab\xae\x9c\xaf\x96\xb2\xbb\xb9\x9f]/', function($m) {return utf8_decode($m[0]);}, $value)), $errprefix ? "$errprefix: double utf8-encoding. input=$value" : ""); + list($value, $error) = array(it::any2utf8(preg_replace_callback('/\xc3[\x82\x83]\xc2[\x82\x83\xbc\xa9\xa4\xb6\xa8\xa2\xa0\xb4\xaa\xa7\x84\xab\xae\x9c\xaf\x96\xb2\xbb\xb9\x9f]/', function($m) {return utf8_decode($m[0]);}, $value)), $errprefix ? "double utf8-encoding. input=$value" : ""); if (preg_match('/\xef\xb7[\x90-\xaf]|\xef\xbf[\xbe\xbf]/', $value)) list($value, $error) = array(preg_replace('/\xef\xb7[\x90-\xaf]|\xef\xbf[\xbe\xbf]/', " ", $value), "forbidden utf-8 character. input=$value"); $value = preg_replace('/\xc2\xad/', '', $value); # Kill invisible soft hyphens @@ -797,7 +803,7 @@ static function imageconvert($p) $ultratimeout = file_exists("/opt/ultra/bin/ultratimeout") ? "/opt/ultra/bin/ultratimeout 30 " : ""; if (in_array($type, explode(',', $p['types']))) # Valid type? - $cmdoutput = it::exec('( ' . $ultratimeout . 'gm convert 2>&1 {-opts} {in} {type}:{out} || echo "SHELL ERROR $?" ) | grep -v " iCCP: "', $p); + $cmdoutput = it::exec('( ' . $ultratimeout . 'gm convert -limit threads 2 2>&1 {-opts} {in} {type}:{out} || echo "SHELL ERROR $?" ) | grep -Ev "( iCCP: | Invalid SOS parameters for sequential JPEG | profile matches .* but writing .* instead | inconsistent chromacities )"', $p); if ($p['pngcrush'] && $p['type'] == "png") it::exec('pngcrush.sh 2>/dev/null {out} {out}.tmp && mv {out}.tmp {out} || rm {out}.tmp', $p); @@ -925,11 +931,10 @@ static function getopt($usage, $p = array()) $noopts = true; } - if (!$optionalargs && $result['args']) - it::error("Optional arguments passed to script without optional args in usage"); # FIXME 2020-10 NG merge with normal usage errors below - if ($err || $eat || $result['h'] || $result['help'] || $mandatoryargs) + if ($err || $eat || $result['h'] || $result['help'] || $mandatoryargs || (!$optionalargs && $result['args'])) { - fputs(($result['h'] || $result['help'] ? STDOUT : STDERR), trim($usage) . "\n"); + if (is_resource($out = $result['h'] || $result['help'] ? STDOUT : STDERR)) + fputs($out, trim($usage) . "\n"); return $p['noexit'] ? false : exit(1); } @@ -1029,6 +1034,9 @@ static function date($format = "", $stamp = null) # Internal: Convert expression or funcname or function literal to callable static function createfunc($code) { + if ($code instanceof Closure && (new ReflectionFunction($code))->getNumberOfRequiredParameters() == 1) + $code = function($dummy, $v) use ($code) {return $code($v);}; + if (is_string($code) && it::match('^[\w:]+$', $code) && is_callable($code)) $code .= '($v)'; |