diff options
| author | Mark Newnham <mark@newnhams.com> | 2022-08-21 17:12:56 -0600 |
|---|---|---|
| committer | Damien Regad <dregad@mantisbt.org> | 2022-09-03 18:28:10 +0200 |
| commit | 00914513d0ca193fa45ff3d2ff398a5166e01294 (patch) | |
| tree | 5416c231d2d1cb6359210310008a4bb242eef339 /adodb-lib.inc.php | |
| parent | badb5db4485299a48576fb6e9dcc135132a8b488 (diff) | |
| download | adodb-00914513d0ca193fa45ff3d2ff398a5166e01294.tar.gz adodb-00914513d0ca193fa45ff3d2ff398a5166e01294.tar.bz2 adodb-00914513d0ca193fa45ff3d2ff398a5166e01294.zip | |
Prevent str_repeat error in adodb_backtrace see #852
This fix eliminates the error in str_repeat when the number of repeats hits zero In addition, the function is refactored with improved variable names and docblocks
Diffstat (limited to 'adodb-lib.inc.php')
| -rw-r--r-- | adodb-lib.inc.php | 231 |
1 files changed, 187 insertions, 44 deletions
diff --git a/adodb-lib.inc.php b/adodb-lib.inc.php index 1a7f3d43..13dba89c 100644 --- a/adodb-lib.inc.php +++ b/adodb-lib.inc.php @@ -1152,10 +1152,21 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, } - -function _adodb_debug_execute($zthis, $sql, $inputarr) +/** +* Replaces standard _execute when debug is enabled +* +* @param obj $zthis An ADOConnection object +* @param string $sql A string or array of SQL statements +* @param string[]|null $inputarr An optional array of bind parameters +* +* @return handle|void A handle to the executed query +*/ + function _adodb_debug_execute($zthis, $sql, $inputarr) { $ss = ''; + /* + * Unpack the bind parameters + */ if ($inputarr) { foreach($inputarr as $kk=>$vv) { if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...'; @@ -1173,6 +1184,16 @@ function _adodb_debug_execute($zthis, $sql, $inputarr) $ss = "[ $ss ]"; } $sqlTxt = is_array($sql) ? $sql[0] : $sql; + + /* + * Remove newlines and tabs + */ + $sqlTxt = str_replace(array("\r","\n","\t"),' ',$sqlTxt); + + /* + * Compress repeating spaces + */ + $sqlText = preg_replace('/\s+/',' ',$sqlTxt); /*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql); $sqlTxt = str_replace(',',', ',$sqlTxt); $sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt); @@ -1180,22 +1201,50 @@ function _adodb_debug_execute($zthis, $sql, $inputarr) // check if running from browser or command-line $inBrowser = isset($_SERVER['HTTP_USER_AGENT']); - $dbt = $zthis->databaseType; - if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType; - if ($inBrowser) { + $myDatabaseType = $zthis->databaseType; + + if (isset($zthis->dsnType)) + /* + * Append the PDO driver name + */ + $myDatabaseType .= '-'.$zthis->dsnType; + + if ($inBrowser) + { if ($ss) { - $ss = '<code>'.htmlspecialchars($ss).'</code>'; + /* + * Default formatting for passed parameter + */ + $ss = sprintf('<code class="adodb-debug">%s</code>',htmlspecialchars($ss)); } if ($zthis->debug === -1) - ADOConnection::outp( "<br>\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<br>\n",false); + { + $outString = "<br class='adodb-debug'>(%s): %s %s<br class='adodb-debug'>"; + ADOConnection::outp(sprintf($outString,$myDatabaseType,htmlspecialchars($sqlTxt),$ss),false); + } else if ($zthis->debug !== -99) - ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<hr>\n",false); - } else { - $ss = "\n ".$ss; + { + $outString = "<hr class='adodb-debug'>(%s): %s %s<hr class='adodb-debug'>"; + ADOConnection::outp(sprintf($outString, $myDatabaseType,htmlspecialchars($sqlTxt),$ss),false); + } + } + else + { + /* + * CLI output + */ if ($zthis->debug !== -99) - ADOConnection::outp("-----<hr>\n($dbt): ".$sqlTxt." $ss\n-----<hr>\n",false); + { + $outString = sprintf("%s\n%s\n %s \n%s\n",str_repeat('-',78),$myDatabaseType,$sqlTxt,$ss,str_repeat('-',78)); + ADOConnection::outp($outString,false); + } } + + /* + * Now execute the query + */ + $qID = $zthis->_query($sql,$inputarr); /* @@ -1208,64 +1257,156 @@ function _adodb_debug_execute($zthis, $sql, $inputarr) if($emsg = $zthis->ErrorMsg()) { if ($err = $zthis->ErrorNo()) { if ($zthis->debug === -99) - ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<hr>\n",false); + + ADOConnection::outp( "<hr>\n($myDatabaseType): ".htmlspecialchars($sqlTxt)." $ss\n<hr>\n",false); ADOConnection::outp($err.': '.$emsg); } } - } else if (!$qID) { - + } + else if (!$qID) { + /* + * Statement execution has failed + */ if ($zthis->debug === -99) - if ($inBrowser) ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n<hr>\n",false); - else ADOConnection::outp("-----<hr>\n($dbt): ".$sqlTxt."$ss\n-----<hr>\n",false); - + { + if ($inBrowser) + { + $outString = "<hr class='adodb-debug'>(%s): %s %s<hr class='adodb-debug'>"; + ADOConnection::outp(sprintf($outString, $myDatabaseType,htmlspecialchars($sqlTxt),$ss),false); + } + else + { + $outString = sprintf("%s\n%s\n %s\n%s\n",str_repeat('-',78),$myDatabaseType,$sqlTxt,$ss,str_repeat('-',78)); + ADOConnection::outp($outString,false); + } + } + + /* + * Send last error to output + */ ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg()); } - if ($zthis->debug === 99) _adodb_backtrace(true,9999,2); + if ($zthis->debug === 99) + { + _adodb_backtrace(true,9999,2); + } return $qID; } -# pretty print the debug_backtrace function -function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0,$ishtml=null) +/** + * pretty print the debug_backtrace function + * + * @param string[]|bool $printOrArr Whether to print the result directly or return the result + * @param int $maximumDepth The maximum depth of the array to traverse + * @param int $elementsToIgnore The backtrace array indexes to ignore + * @param null|bool $ishtml Are we in a CLI or CGI environment + * + * @return void + */ +function _adodb_backtrace($printOrArr=true,$maximumDepth=9999,$elementsToIgnore=0,$ishtml=null) { - if (!function_exists('debug_backtrace')) return ''; + if (!function_exists('debug_backtrace')) + return ''; - if ($ishtml === null) $html = (isset($_SERVER['HTTP_USER_AGENT'])); - else $html = $ishtml; + if ($ishtml === null) + /* + Auto determine if we in a CGI enviroment + */ + $html = (isset($_SERVER['HTTP_USER_AGENT'])); + else + $html = $ishtml; - $fmt = ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s"; + $cgiString = "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>"; + $cliString = "%% line %4d, file: %s"; + $fmt = ($html) ? $cgiString : $cliString; $MAXSTRLEN = 128; $s = ($html) ? '<pre align=left>' : ''; + + + if (is_array($printOrArr)) + $traceArr = $printOrArr; + else + $traceArr = debug_backtrace(); + - if (is_array($printOrArr)) $traceArr = $printOrArr; - else $traceArr = debug_backtrace(); + /* + * Remove first 2 elements that just show calls to adodb_backtrace + */ array_shift($traceArr); array_shift($traceArr); - $tabs = sizeof($traceArr)-2; - foreach ($traceArr as $arr) { - if ($skippy) {$skippy -= 1; continue;} - $levels -= 1; - if ($levels < 0) break; + /* + * We want last element to have no indent + */ + $tabs = sizeof($traceArr) - 1; + + + foreach ($traceArr as $arr) + { + if ($elementsToIgnore) + { + /* + * Ignore array element at start of array + */ + $elementsToIgnore--; + continue; + } + $maximumDepth--; + if ($maximumDepth < 0) + break; $args = array(); - $s .= str_repeat($html ? ' ' : "\t", $tabs); - $tabs -= 1; - if ($html) $s .= '<font face="Courier New,Courier">'; - if (isset($arr['class'])) $s .= $arr['class'].'.'; + + if ($tabs) + { + $s .= str_repeat($html ? ' ' : "\t", $tabs); + $tabs --; + } + if ($html) + $s .= '<font face="Courier New,Courier">'; + + if (isset($arr['class'])) + $s .= $arr['class'].'.'; + if (isset($arr['args'])) - foreach($arr['args'] as $v) { - if (is_null($v)) $args[] = 'null'; - else if (is_array($v)) $args[] = 'Array['.sizeof($v).']'; - else if (is_object($v)) $args[] = 'Object:'.get_class($v); - else if (is_bool($v)) $args[] = $v ? 'true' : 'false'; + foreach($arr['args'] as $v) + { + if (is_null($v)) + $args[] = 'null'; + else if (is_array($v)) + $args[] = 'Array['.sizeof($v).']'; + else if (is_object($v)) + $args[] = 'Object:'.get_class($v); + else if (is_bool($v)) + $args[] = $v ? 'true' : 'false'; else { $v = (string) @$v; - $str = htmlspecialchars(str_replace(array("\r","\n"),' ',substr($v,0,$MAXSTRLEN))); - if (strlen($v) > $MAXSTRLEN) $str .= '...'; + /* + * Truncate + */ + $v = substr($v,0,$MAXSTRLEN); + /* + * Remove newlines and tabs + */ + $v = str_replace(array("\r","\n","\t"),' ',$v); + + /* + * Compress repeating spaces + */ + $v = preg_replace('/\s+/',' ',$v); + + /* + * Convert htmlchars (not sure why we do this in CLI) + */ + $str = htmlspecialchars($v); + + if (strlen($v) > $MAXSTRLEN) + $str .= '...'; + $args[] = $str; } } @@ -1275,8 +1416,10 @@ function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0,$ishtml=null) $s .= "\n"; } - if ($html) $s .= '</pre>'; - if ($printOrArr) print $s; + if ($html) + $s .= '</pre>'; + if ($printOrArr) + print $s; return $s; } |
