summaryrefslogtreecommitdiff
path: root/adodb-lib.inc.php
diff options
context:
space:
mode:
authorMark Newnham <mark@newnhams.com>2022-08-21 17:12:56 -0600
committerDamien Regad <dregad@mantisbt.org>2022-09-03 18:28:10 +0200
commit00914513d0ca193fa45ff3d2ff398a5166e01294 (patch)
tree5416c231d2d1cb6359210310008a4bb242eef339 /adodb-lib.inc.php
parentbadb5db4485299a48576fb6e9dcc135132a8b488 (diff)
downloadadodb-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.php231
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)." &nbsp; $ss\n<br>\n",false);
+ {
+ $outString = "<br class='adodb-debug'>(%s): %s &nbsp; %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)." &nbsp; $ss\n<hr>\n",false);
- } else {
- $ss = "\n ".$ss;
+ {
+ $outString = "<hr class='adodb-debug'>(%s): %s &nbsp; %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)." &nbsp; $ss\n<hr>\n",false);
+
+ ADOConnection::outp( "<hr>\n($myDatabaseType): ".htmlspecialchars($sqlTxt)." &nbsp; $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)." &nbsp; $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 &nbsp; %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 ? ' &nbsp; ' : "\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 ? ' &nbsp; ' : "\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;
}