From 4cb67f3858f9bc33b74f9182285e5ee7ad004aaa Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Sun, 17 Dec 2023 09:56:01 +0200 Subject: [PATCH 1/8] strlen parameter can not be null --- lib/Cake/Network/Email/AbstractTransport.php | 2 +- lib/Cake/Network/Email/CakeEmail.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Cake/Network/Email/AbstractTransport.php b/lib/Cake/Network/Email/AbstractTransport.php index 453b74361..cd91b5d22 100644 --- a/lib/Cake/Network/Email/AbstractTransport.php +++ b/lib/Cake/Network/Email/AbstractTransport.php @@ -67,7 +67,7 @@ protected function _headersToString($headers, $eol = "\r\n") { $out .= $key . ': ' . $value . $eol; } if (!empty($out)) { - $out = substr($out, 0, -1 * strlen($eol)); + $out = substr($out, 0, -1 * strlen($eol ?? '')); } return $out; } diff --git a/lib/Cake/Network/Email/CakeEmail.php b/lib/Cake/Network/Email/CakeEmail.php index ee4da73d9..524c2061a 100644 --- a/lib/Cake/Network/Email/CakeEmail.php +++ b/lib/Cake/Network/Email/CakeEmail.php @@ -1375,7 +1375,7 @@ protected function _encodeString($text, $charset) { * @return array Wrapped message */ protected function _wrap($message, $wrapLength = CakeEmail::LINE_LENGTH_MUST) { - if (strlen($message) === 0) { + if (strlen($message ?? '') === 0) { return array(''); } $message = str_replace(array("\r\n", "\r"), "\n", $message); @@ -1388,7 +1388,7 @@ protected function _wrap($message, $wrapLength = CakeEmail::LINE_LENGTH_MUST) { $formatted[] = ''; continue; } - if (strlen($line) < $wrapLength) { + if (strlen($line ?? '') < $wrapLength) { $formatted[] = $line; continue; } @@ -1403,12 +1403,12 @@ protected function _wrap($message, $wrapLength = CakeEmail::LINE_LENGTH_MUST) { $tagOpen = false; $tmpLine = $tag = ''; $tmpLineLength = 0; - for ($i = 0, $count = strlen($line); $i < $count; $i++) { + for ($i = 0, $count = strlen($line ?? ''); $i < $count; $i++) { $char = $line[$i]; if ($tagOpen) { $tag .= $char; if ($char === '>') { - $tagLength = strlen($tag); + $tagLength = strlen($tag ?? ''); if ($tagLength + $tmpLineLength < $wrapLength) { $tmpLine .= $tag; $tmpLineLength += $tagLength; @@ -1462,7 +1462,7 @@ protected function _wrap($message, $wrapLength = CakeEmail::LINE_LENGTH_MUST) { $formatted[] = trim(substr($tmpLine, 0, $lastSpace)); $tmpLine = substr($tmpLine, $lastSpace + 1); - $tmpLineLength = strlen($tmpLine); + $tmpLineLength = strlen($tmpLine ?? ''); } } } From 1ed6da7fb4ad049911c1e6602aa0927b7a2ba7bf Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Sun, 17 Dec 2023 09:56:46 +0200 Subject: [PATCH 2/8] cake function does not all additional_params to be null --- lib/Cake/Network/Email/MailTransport.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/lib/Cake/Network/Email/MailTransport.php b/lib/Cake/Network/Email/MailTransport.php index 36782b2f1..7eed88afc 100644 --- a/lib/Cake/Network/Email/MailTransport.php +++ b/lib/Cake/Network/Email/MailTransport.php @@ -48,7 +48,7 @@ public function send(CakeEmail $email) { $message = implode($eol, $email->message()); - $params = isset($this->_config['additionalParameters']) ? $this->_config['additionalParameters'] : null; + $params = isset($this->_config['additionalParameters']) ? $this->_config['additionalParameters'] : ''; $this->_mail($to, $subject, $message, $headers, $params); $headers .= $eol . 'Subject: ' . $subject; @@ -63,19 +63,12 @@ public function send(CakeEmail $email) { * @param string $subject email's subject * @param string $message email's body * @param string $headers email's custom headers - * @param string $params additional params for sending email, will be ignored when in safe_mode + * @param string $params additional params for sending email * @throws SocketException if mail could not be sent * @return void */ - protected function _mail($to, $subject, $message, $headers, $params = null) { - if (ini_get('safe_mode')) { - //@codingStandardsIgnoreStart - if (!@mail($to, $subject, $message, $headers)) { - $error = error_get_last(); - $msg = 'Could not send email: ' . (isset($error['message']) ? $error['message'] : 'unknown'); - throw new SocketException($msg); - } - } elseif (!@mail($to, $subject, $message, $headers, $params)) { + protected function _mail($to, $subject, $message, $headers, $params = '') { + if (!@mail($to, $subject, $message, $headers, $params)) { $error = error_get_last(); $msg = 'Could not send email: ' . (isset($error['message']) ? $error['message'] : 'unknown'); //@codingStandardsIgnoreEnd From 394f3457e9d36ab6a2a9408a66bd73286c842a75 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Sun, 17 Dec 2023 10:04:39 +0200 Subject: [PATCH 3/8] reuired parameters should not preced optional ones --- app/Model/Behavior/ProvisionerBehavior.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Model/Behavior/ProvisionerBehavior.php b/app/Model/Behavior/ProvisionerBehavior.php index cfa125145..c6a8ca677 100644 --- a/app/Model/Behavior/ProvisionerBehavior.php +++ b/app/Model/Behavior/ProvisionerBehavior.php @@ -913,7 +913,7 @@ private function invokePlugins($model, $provisioningData, $action, $actorCoPerso public function manualProvision(Model $model, $coProvisioningTargetId=null, - $coPersonId, + $coPersonId = null, $coGroupId=null, $provisioningAction=ProvisioningActionEnum::CoPersonReprovisionRequested, $coEmailListId=null, From 7c5e32384f15c89563fd8feca2fb5dc742092557 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Sun, 17 Dec 2023 10:40:58 +0200 Subject: [PATCH 4/8] preg_match $subject param can not be null --- app/Console/Command/JobShell.php | 2 +- app/Controller/AppController.php | 2 +- app/Controller/CoLocalizationsController.php | 2 +- app/Controller/CoPetitionsController.php | 4 ++-- app/Controller/Component/ApiComponent.php | 4 ++-- app/Model/AppModel.php | 12 ++++++------ app/Model/CoEnrollmentAttribute.php | 4 ++-- app/Model/CoGroupOisMapping.php | 2 +- app/Model/CoPetition.php | 6 +++--- app/View/Standard/json/index.ctp | 2 +- app/View/Standard/json/view.ctp | 2 +- app/View/Standard/xml/index.ctp | 2 +- app/View/Standard/xml/view.ctp | 2 +- lib/Cake/Network/Email/CakeEmail.php | 6 +++--- lib/Cake/Network/Email/SmtpTransport.php | 2 +- 15 files changed, 27 insertions(+), 27 deletions(-) diff --git a/app/Console/Command/JobShell.php b/app/Console/Command/JobShell.php index 608a6518c..15054c1f4 100644 --- a/app/Console/Command/JobShell.php +++ b/app/Console/Command/JobShell.php @@ -201,7 +201,7 @@ protected function validateParameters($format, $args) { // For attributes of type int, is the value an integer? if($format[$attr]['type'] == 'int') { - if(!preg_match('/^[0-9.+-]*$/', $val)) { + if(!preg_match('/^[0-9.+-]*$/', $val ?? '')) { throw new InvalidArgumentException("Value for " . $attr . " is not an integer"); // XXX I18n } } diff --git a/app/Controller/AppController.php b/app/Controller/AppController.php index e55d9ca3b..694e1cebf 100644 --- a/app/Controller/AppController.php +++ b/app/Controller/AppController.php @@ -223,7 +223,7 @@ static function ($route) use ($rparams) { // Perform the IP Address check $ipregex = $this->Session->read('Auth.User.remote_ip'); - if(!empty($ipregex) && !preg_match($ipregex, $_SERVER['REMOTE_ADDR'])) { + if(!empty($ipregex) && !preg_match($ipregex, $_SERVER['REMOTE_ADDR'] ?? '')) { $this->Api->restResultHeader(401, "Unauthorized"); // We force an exit here to prevent any views from rendering, but also // to prevent Cake from dumping the default layout diff --git a/app/Controller/CoLocalizationsController.php b/app/Controller/CoLocalizationsController.php index f563ec145..ae532c5fc 100644 --- a/app/Controller/CoLocalizationsController.php +++ b/app/Controller/CoLocalizationsController.php @@ -66,7 +66,7 @@ function beforeRender() { foreach(array_keys($cm_texts_orig[$cm_lang]) as $k) { if(!is_array($cm_texts_orig[$cm_lang][$k]) // Also skip strings that can already be dynamically changed - && !preg_match('/^em\./', $k)) { + && !preg_match('/^em\./', $k ?? '')) { $texts[$k] = $cm_texts_orig[$cm_lang][$k]; } } diff --git a/app/Controller/CoPetitionsController.php b/app/Controller/CoPetitionsController.php index 23cc817da..7e0d3f75b 100644 --- a/app/Controller/CoPetitionsController.php +++ b/app/Controller/CoPetitionsController.php @@ -1816,7 +1816,7 @@ protected function execute_redirectOnConfirm($id) { $found = false; foreach(preg_split('/\R/', $allowList) as $u) { - if(preg_match($u, $targetUrl)) { + if(preg_match($u, $targetUrl ?? '')) { $found = true; break; } @@ -1874,7 +1874,7 @@ protected function execute_redirectOnFinalize($id) { $found = false; foreach(preg_split('/\R/', $allowList) as $u) { - if(preg_match($u, $targetUrl)) { + if(preg_match($u, $targetUrl ?? '')) { $found = true; break; } diff --git a/app/Controller/Component/ApiComponent.php b/app/Controller/Component/ApiComponent.php index 9be289b09..797354290 100644 --- a/app/Controller/Component/ApiComponent.php +++ b/app/Controller/Component/ApiComponent.php @@ -88,7 +88,7 @@ public function checkRestPost($coId) { } foreach(array_keys($this->reqModel->validate) as $field) { - if(preg_match('/_id$/', $field)) { + if(preg_match('/_id$/', $field ?? '')) { // Add additional validation rules for foreign keys. These checks are // handled differently in v5, as application rules. @@ -231,7 +231,7 @@ public function convertRestResponse($res) { $rr[$m][Inflector::camelize($k)] = $r[$m][$k]; } } - } elseif(preg_match('/Co[0-9]+PersonExtendedAttribute/', $m)) { + } elseif(preg_match('/Co[0-9]+PersonExtendedAttribute/', $m ?? '')) { // Extended Attributes need to be handled specially. Currently, extended // attributes are NOT inflected to keep them consistent with their // database definitions. diff --git a/app/Model/AppModel.php b/app/Model/AppModel.php index eb4c4c4fb..b08d86621 100644 --- a/app/Model/AppModel.php +++ b/app/Model/AppModel.php @@ -323,16 +323,16 @@ protected function changesForModel($model, $newdata, $olddata, $coId, $attrs) { continue; } - if(preg_match('/.*_id$/', $attr)) { + if(preg_match('/.*_id$/', $attr ?? '')) { // Foreign keys need to be handled specially. Start by figuring out the model. - if(preg_match('/.*_co_person_id$/', $attr)) { + if(preg_match('/.*_co_person_id$/', $attr ?? '')) { // This is a foreign key to a CO Person (eg: sponsor_co_person) // Chop off _co_person_id $afield = substr($attr, 0, strlen($attr)-13); $amodel = "CoPerson"; - } elseif(preg_match('/.*_co_group_id$/', $attr)) { + } elseif(preg_match('/.*_co_group_id$/', $attr ?? '')) { // This is a foreign key to a CO Group (eg: admins_co_group) // Chop off _co_group_id @@ -886,7 +886,7 @@ public function filterRelatedModels($data) { $ret['hasOne'][$k] = $data[$k]; } elseif(isset($this->hasMany[$k])) { $ret['hasMany'][$k] = $data[$k]; - } elseif(preg_match('/Co[0-9]+PersonExtendedAttribute/', $k)) { + } elseif(preg_match('/Co[0-9]+PersonExtendedAttribute/', $k ?? '')) { $ret['extended'][$k] = $data[$k]; } } @@ -1144,7 +1144,7 @@ public function findCoForRecord($id) { if(!empty($srvr['Server']['co_id'])) { return $srvr['Server']['co_id']; } - } elseif(preg_match('/Co[0-9]+PersonExtendedAttribute/', $this->alias)) { + } elseif(preg_match('/Co[0-9]+PersonExtendedAttribute/', $this->alias ?? '')) { // Extended attributes need to be handled specially, as usual, since there // are no explicit validation rules. Find the CO via the CO Person Role ID. // (ie: We don't trust the Model name in order to follow the general pattern @@ -1802,7 +1802,7 @@ public function validateInput($a, $d) { } // We require at least one non-whitespace character (CO-1551) - if(!preg_match('/\S/', $v)) { + if(!preg_match('/\S/', $v ?? '')) { return _txt('er.input.blank'); } diff --git a/app/Model/CoEnrollmentAttribute.php b/app/Model/CoEnrollmentAttribute.php index 27603a761..30f305dcc 100644 --- a/app/Model/CoEnrollmentAttribute.php +++ b/app/Model/CoEnrollmentAttribute.php @@ -455,7 +455,7 @@ public function enrollmentFlowAttributes($coef, $defaultValues=array(), $archive // For date types, convert to an actual date if(preg_match("/^[0-2][0-9]\-[0-9]{2}$/", - $efAttr['CoEnrollmentAttributeDefault'][0]['value'])) { + $efAttr['CoEnrollmentAttributeDefault'][0]['value'] ?? '')) { // MM-DD indicates next MM-DD. Rather than muck around with PHP date parsing, // we'll see if {THISYEAR}-MM-DD is before now(). If it is, we'll increment // the year. @@ -469,7 +469,7 @@ public function enrollmentFlowAttributes($coef, $defaultValues=array(), $archive $attr['default'] = $curyear . "-" . $efAttr['CoEnrollmentAttributeDefault'][0]['value']; } elseif(preg_match("/^\+[0-9]+$/", - $efAttr['CoEnrollmentAttributeDefault'][0]['value'])) { + $efAttr['CoEnrollmentAttributeDefault'][0]['value'] ?? '')) { // Format +## indicates days from today $attr['default'] = strftime("%F", diff --git a/app/Model/CoGroupOisMapping.php b/app/Model/CoGroupOisMapping.php index e080bc40c..51b0aa274 100644 --- a/app/Model/CoGroupOisMapping.php +++ b/app/Model/CoGroupOisMapping.php @@ -126,7 +126,7 @@ protected function compare($value, $comparison, $pattern) { return (strcasecmp($value, $pattern) !== 0); break; case ComparisonEnum::Regex: - return (preg_match($pattern, $value)); + return (preg_match($pattern, $value ?? '')); break; default: // Ignore anything unexpected diff --git a/app/Model/CoPetition.php b/app/Model/CoPetition.php index 4fb644237..aabf5233e 100644 --- a/app/Model/CoPetition.php +++ b/app/Model/CoPetition.php @@ -1026,7 +1026,7 @@ protected function flattenAttributes($enrollmentFlowID, $coPetitionID, $orgData, ); } } - } elseif(preg_match('/Co[0-9]+PersonExtendedAttribute/', $m)) { + } elseif(preg_match('/Co[0-9]+PersonExtendedAttribute/', $m ?? '')) { // Extended Attribute foreach(array_keys($coRoleData[$m]) as $a) { @@ -3756,7 +3756,7 @@ private function validateRelated($primaryModel, $requestData, $validatedData, $e } } - if(preg_match('/.*CoPersonRole$/', $primaryModel)) { + if(preg_match('/.*CoPersonRole$/', $primaryModel ?? '')) { // Handle Extended Attributes specially, as usual. To find them, we have to walk // the configured attributes. @@ -3764,7 +3764,7 @@ private function validateRelated($primaryModel, $requestData, $validatedData, $e $m = explode('.', $efAttr['model'], 3); if(count($m) == 2 - && preg_match('/Co[0-9]+PersonExtendedAttribute/', $m[1])) { + && preg_match('/Co[0-9]+PersonExtendedAttribute/', $m[1] ?? '')) { $model = $m[1]; // First, dynamically bind the extended attribute to the model if we haven't already. diff --git a/app/View/Standard/json/index.ctp b/app/View/Standard/json/index.ctp index 46d53bb55..515802a23 100644 --- a/app/View/Standard/json/index.ctp +++ b/app/View/Standard/json/index.ctp @@ -99,7 +99,7 @@ foreach(array_keys($m) as $ak) { - if(preg_match('/Co[0-9]+PersonExtendedAttribute/', $ak)) + if(preg_match('/Co[0-9]+PersonExtendedAttribute/', $ak ?? '')) { foreach(array_keys($m[$ak]) as $ea) if(!in_array($ea, array('Id', 'CoPersonRoleId', 'Created', 'Modified')) diff --git a/app/View/Standard/json/view.ctp b/app/View/Standard/json/view.ctp index bfeadb532..9f6509d17 100644 --- a/app/View/Standard/json/view.ctp +++ b/app/View/Standard/json/view.ctp @@ -84,7 +84,7 @@ // For CO Person Roles, we need to check for extended attributes. foreach(array_keys($m) as $ak) { - if(preg_match('/Co[0-9]+PersonExtendedAttribute/', $ak)) { + if(preg_match('/Co[0-9]+PersonExtendedAttribute/', $ak ?? '')) { foreach(array_keys($m[$ak]) as $ea) { $a['ExtendedAttributes'][$ea] = $m[$ak][$ea]; } diff --git a/app/View/Standard/xml/index.ctp b/app/View/Standard/xml/index.ctp index 2a1bbef6a..0a24b3407 100644 --- a/app/View/Standard/xml/index.ctp +++ b/app/View/Standard/xml/index.ctp @@ -97,7 +97,7 @@ foreach(array_keys($m) as $ak) { - if(preg_match('/Co[0-9]+PersonExtendedAttribute/', $ak)) + if(preg_match('/Co[0-9]+PersonExtendedAttribute/', $ak ?? '')) { foreach(array_keys($m[$ak]) as $ea) if(!in_array($ea, array('Id', 'CoPersonRoleId', 'Created', 'Modified')) diff --git a/app/View/Standard/xml/view.ctp b/app/View/Standard/xml/view.ctp index 24ae716f4..6f7b2b6f9 100644 --- a/app/View/Standard/xml/view.ctp +++ b/app/View/Standard/xml/view.ctp @@ -86,7 +86,7 @@ // For CO Person Roles, we need to check for extended attributes. foreach(array_keys($m) as $ak) { - if(preg_match('/Co[0-9]+PersonExtendedAttribute/', $ak)) { + if(preg_match('/Co[0-9]+PersonExtendedAttribute/', $ak ?? '')) { foreach(array_keys($m[$ak]) as $ea) { $a['ExtendedAttributes'][$ea] = $m[$ak][$ea]; } diff --git a/lib/Cake/Network/Email/CakeEmail.php b/lib/Cake/Network/Email/CakeEmail.php index 524c2061a..c6c9ea88a 100644 --- a/lib/Cake/Network/Email/CakeEmail.php +++ b/lib/Cake/Network/Email/CakeEmail.php @@ -621,7 +621,7 @@ protected function _validateEmail($email, $context) { if (filter_var($email, FILTER_VALIDATE_EMAIL)) { return; } - } elseif (preg_match($this->_emailPattern, $email)) { + } elseif (preg_match($this->_emailPattern, $email ?? '')) { return; } if ($email == '') { @@ -835,7 +835,7 @@ protected function _formatAddress($address) { } else { $encoded = $this->_encode($alias); if ( - $encoded === $alias && preg_match('/[^a-z0-9 ]/i', $encoded) || + $encoded === $alias && preg_match('/[^a-z0-9 ]/i', $encoded ?? '') || strpos($encoded, ',') !== false ) { $encoded = '"' . str_replace('"', '\"', $encoded) . '"'; @@ -992,7 +992,7 @@ public function messageId($message = null) { if (is_bool($message)) { $this->_messageId = $message; } else { - if (!preg_match('/^\<.+@.+\>$/', $message)) { + if (!preg_match('/^\<.+@.+\>$/', $message ?? '')) { throw new SocketException(__d('cake_dev', 'Invalid format for Message-ID. The text should be something like ""')); } $this->_messageId = $message; diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index d69fa3903..a245c5fb4 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -125,7 +125,7 @@ public function config($config = null) { protected function _bufferResponseLines(array $responseLines) { $response = array(); foreach ($responseLines as $responseLine) { - if (preg_match('/^(\d{3})(?:[ -]+(.*))?$/', $responseLine, $match)) { + if (preg_match('/^(\d{3})(?:[ -]+(.*))?$/', $responseLine ?? '', $match)) { $response[] = array( 'code' => $match[1], 'message' => isset($match[2]) ? $match[2] : null From de89109b1ed1ce335f14377ed25fa34e527c1313 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Sun, 17 Dec 2023 11:22:10 +0200 Subject: [PATCH 5/8] adodb hotfix 5.22.x --- app/Vendor/adodb5/adodb-csvlib.inc.php | 2 +- app/Vendor/adodb5/adodb-datadict.inc.php | 6 + app/Vendor/adodb5/adodb-errorhandler.inc.php | 9 +- app/Vendor/adodb5/adodb-errorpear.inc.php | 10 +- app/Vendor/adodb5/adodb-exceptions.inc.php | 19 +- app/Vendor/adodb5/adodb-lib.inc.php | 60 ++- app/Vendor/adodb5/adodb-loadbalancer.inc.php | 12 +- app/Vendor/adodb5/adodb-perf.inc.php | 9 +- app/Vendor/adodb5/adodb-time.inc.php | 2 + app/Vendor/adodb5/adodb-xmlschema.inc.php | 19 +- app/Vendor/adodb5/adodb-xmlschema03.inc.php | 24 +- app/Vendor/adodb5/adodb.inc.php | 157 +++++-- app/Vendor/adodb5/docs/changelog.md | 104 ++++- app/Vendor/adodb5/drivers/adodb-ado.inc.php | 6 +- app/Vendor/adodb5/drivers/adodb-ado5.inc.php | 7 +- app/Vendor/adodb5/drivers/adodb-ads.inc.php | 5 +- app/Vendor/adodb5/drivers/adodb-csv.inc.php | 2 +- app/Vendor/adodb5/drivers/adodb-db2.inc.php | 48 +- app/Vendor/adodb5/drivers/adodb-fbsql.inc.php | 1 - .../adodb5/drivers/adodb-firebird.inc.php | 20 +- app/Vendor/adodb5/drivers/adodb-ibase.inc.php | 22 +- .../adodb5/drivers/adodb-informix72.inc.php | 10 +- app/Vendor/adodb5/drivers/adodb-ldap.inc.php | 1 - app/Vendor/adodb5/drivers/adodb-mssql.inc.php | 2 - .../adodb5/drivers/adodb-mssqlnative.inc.php | 1 - .../adodb5/drivers/adodb-mysqli.inc.php | 48 +- app/Vendor/adodb5/drivers/adodb-oci8.inc.php | 87 ++-- .../adodb5/drivers/adodb-oci8po.inc.php | 11 +- app/Vendor/adodb5/drivers/adodb-odbc.inc.php | 17 +- .../adodb5/drivers/adodb-odbc_mssql.inc.php | 8 +- .../drivers/adodb-odbc_mssql2012.inc.php | 9 +- app/Vendor/adodb5/drivers/adodb-odbtp.inc.php | 10 +- .../adodb5/drivers/adodb-oracle.inc.php | 1 - app/Vendor/adodb5/drivers/adodb-pdo.inc.php | 25 +- .../adodb5/drivers/adodb-pdo_firebird.inc.php | 14 - .../adodb5/drivers/adodb-pdo_mysql.inc.php | 5 +- .../adodb5/drivers/adodb-pdo_sqlsrv.inc.php | 26 +- .../adodb5/drivers/adodb-postgres64.inc.php | 17 +- .../adodb5/drivers/adodb-postgres8.inc.php | 20 +- .../adodb5/drivers/adodb-sqlanywhere.inc.php | 2 +- .../adodb5/drivers/adodb-sqlite.inc.php | 1 - .../adodb5/drivers/adodb-sqlite3.inc.php | 1 - .../adodb5/drivers/adodb-sybase.inc.php | 6 +- app/Vendor/adodb5/drivers/adodb-text.inc.php | 23 +- app/Vendor/adodb5/perf/perf-oci8.inc.php | 2 +- app/Vendor/adodb5/session/adodb-session2.php | 423 +++++++++++------- app/Vendor/adodb5/tests/test.php | 2 +- app/Vendor/adodb5/tohtml.inc.php | 8 +- 48 files changed, 869 insertions(+), 455 deletions(-) diff --git a/app/Vendor/adodb5/adodb-csvlib.inc.php b/app/Vendor/adodb5/adodb-csvlib.inc.php index 8273a17ac..87efd9406 100644 --- a/app/Vendor/adodb5/adodb-csvlib.inc.php +++ b/app/Vendor/adodb5/adodb-csvlib.inc.php @@ -76,10 +76,10 @@ function _rs2serialize(&$rs,$conn=false,$sql='') $savefetch = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode; $class = $rs->connection->arrayClass; + /** @var ADORecordSet $rs2 */ $rs2 = new $class(ADORecordSet::DUMMY_QUERY_ID); $rs2->timeCreated = $rs->timeCreated; # memcache fix $rs2->sql = $rs->sql; - $rs2->oldProvider = $rs->dataProvider; $rs2->InitArrayFields($rows,$flds); $rs2->fetchMode = $savefetch; return $line.serialize($rs2); diff --git a/app/Vendor/adodb5/adodb-datadict.inc.php b/app/Vendor/adodb5/adodb-datadict.inc.php index 33fa0cfed..2120c0124 100644 --- a/app/Vendor/adodb5/adodb-datadict.inc.php +++ b/app/Vendor/adodb5/adodb-datadict.inc.php @@ -202,6 +202,12 @@ class ADODB_DataDict { */ public $blobAllowsDefaultValue; + + /** + * @var string String to use to quote identifiers and names + */ + public $quote; + function getCommentSQL($table,$col) { return false; diff --git a/app/Vendor/adodb5/adodb-errorhandler.inc.php b/app/Vendor/adodb5/adodb-errorhandler.inc.php index 0cd3f218b..1d3b9e9e5 100644 --- a/app/Vendor/adodb5/adodb-errorhandler.inc.php +++ b/app/Vendor/adodb5/adodb-errorhandler.inc.php @@ -37,7 +37,14 @@ */ function ADODB_Error_Handler($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) { - if (error_reporting() == 0) return; // obey @ protocol + // Do not throw if errors are suppressed by @ operator + // error_reporting() value for suppressed errors changed in PHP 8.0.0 + $suppressed = version_compare(PHP_VERSION, '8.0.0', '<') + ? 0 + : E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE; + if (error_reporting() == $suppressed) { + return; + } switch($fn) { case 'EXECUTE': $sql = $p1; diff --git a/app/Vendor/adodb5/adodb-errorpear.inc.php b/app/Vendor/adodb5/adodb-errorpear.inc.php index 2bb15947e..7b173da84 100644 --- a/app/Vendor/adodb5/adodb-errorpear.inc.php +++ b/app/Vendor/adodb5/adodb-errorpear.inc.php @@ -52,7 +52,15 @@ function ADODB_Error_PEAR($dbms, $fn, $errno, $errmsg, $p1=false, $p2=false) { global $ADODB_Last_PEAR_Error; - if (error_reporting() == 0) return; // obey @ protocol + // Do not throw if errors are suppressed by @ operator + // error_reporting() value for suppressed errors changed in PHP 8.0.0 + $suppressed = version_compare(PHP_VERSION, '8.0.0', '<') + ? 0 + : E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE; + if (error_reporting() == $suppressed) { + return; + } + switch($fn) { case 'EXECUTE': $sql = $p1; diff --git a/app/Vendor/adodb5/adodb-exceptions.inc.php b/app/Vendor/adodb5/adodb-exceptions.inc.php index 560286a18..e4fae817e 100644 --- a/app/Vendor/adodb5/adodb-exceptions.inc.php +++ b/app/Vendor/adodb5/adodb-exceptions.inc.php @@ -30,6 +30,9 @@ class ADODB_Exception extends Exception { var $host = ''; var $database = ''; + /** @var string A message text. */ + var $msg = ''; + function __construct($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection) { switch($fn) { @@ -78,10 +81,18 @@ function __construct($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection) function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection) { -global $ADODB_EXCEPTION; + global $ADODB_EXCEPTION; + + // Do not throw if errors are suppressed by @ operator + // error_reporting() value for suppressed errors changed in PHP 8.0.0 + $suppressed = version_compare(PHP_VERSION, '8.0.0', '<') + ? 0 + : E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE; + if (error_reporting() == $suppressed) { + return; + } + + $errfn = is_string($ADODB_EXCEPTION) ? $ADODB_EXCEPTION : 'ADODB_EXCEPTION'; - if (error_reporting() == 0) return; // obey @ protocol - if (is_string($ADODB_EXCEPTION)) $errfn = $ADODB_EXCEPTION; - else $errfn = 'ADODB_EXCEPTION'; throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection); } diff --git a/app/Vendor/adodb5/adodb-lib.inc.php b/app/Vendor/adodb5/adodb-lib.inc.php index d6150f1b5..801762bfd 100644 --- a/app/Vendor/adodb5/adodb-lib.inc.php +++ b/app/Vendor/adodb5/adodb-lib.inc.php @@ -508,32 +508,38 @@ function _adodb_getcount($zthis, $sql,$inputarr=false,$secs2cache=0) return $qryRecs; } -/* - Code originally from "Cornel G" - - This code might not work with SQL that has UNION in it - - Also if you are using CachePageExecute(), there is a strong possibility that - data will get out of synch. use CachePageExecute() only with tables that - rarely change. -*/ -function _adodb_pageexecute_all_rows($zthis, $sql, $nrows, $page, - $inputarr=false, $secs2cache=0) +/** + * Execute query with pagination including record count. + * + * This code might not work with SQL that has UNION in it. + * Also if you are using cachePageExecute(), there is a strong possibility that + * data will get out of sync. cachePageExecute() should only be used with + * tables that rarely change. + * + * @param ADOConnection $zthis Connection + * @param string $sql Query to execute + * @param int $nrows Number of rows per page + * @param int $page Page number to retrieve (1-based) + * @param array $inputarr Array of bind variables + * @param int $secs2cache Time-to-live of the cache (in seconds), 0 to force query execution + * + * @return ADORecordSet|bool + * + * @author Cornel G + */ +function _adodb_pageexecute_all_rows($zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) { $atfirstpage = false; $atlastpage = false; - // If an invalid nrows is supplied, - // we assume a default value of 10 rows per page + // If an invalid nrows is supplied, assume a default value of 10 rows per page if (!isset($nrows) || $nrows <= 0) $nrows = 10; $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache); $lastpageno = (int) ceil($qryRecs / $nrows); - $zthis->_maxRecordCount = $qryRecs; - // ***** Here we check whether $page is the last page or - // whether we are trying to retrieve - // a page number greater than the last page number. + // Check whether $page is the last page or if we are trying to retrieve + // a page number greater than the last one. if ($page >= $lastpageno) { $page = $lastpageno; $atlastpage = true; @@ -565,7 +571,25 @@ function _adodb_pageexecute_all_rows($zthis, $sql, $nrows, $page, return $rsreturn; } -// Iván Oliva version +/** + * Execute query with pagination without last page information. + * + * This code might not work with SQL that has UNION in it. + * Also if you are using cachePageExecute(), there is a strong possibility that + * data will get out of sync. cachePageExecute() should only be used with + * tables that rarely change. + * + * @param ADOConnection $zthis Connection + * @param string $sql Query to execute + * @param int $nrows Number of rows per page + * @param int $page Page number to retrieve (1-based) + * @param array $inputarr Array of bind variables + * @param int $secs2cache Time-to-live of the cache (in seconds), 0 to force query execution + * + * @return ADORecordSet|bool + * + * @author Iván Oliva + */ function _adodb_pageexecute_no_last_page($zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) { $atfirstpage = false; diff --git a/app/Vendor/adodb5/adodb-loadbalancer.inc.php b/app/Vendor/adodb5/adodb-loadbalancer.inc.php index 88f5d0fdc..de067805b 100644 --- a/app/Vendor/adodb5/adodb-loadbalancer.inc.php +++ b/app/Vendor/adodb5/adodb-loadbalancer.inc.php @@ -38,17 +38,17 @@ class ADOdbLoadBalancer /** * @var bool|array All connections to each database. */ - protected $connections = false; + protected $connections = []; /** * @var bool|array Just connections to the write capable database. */ - protected $connections_write = false; + protected $connections_write = []; /** * @var bool|array Just connections to the readonly database. */ - protected $connections_readonly = false; + protected $connections_readonly = []; /** * @var array Counts of all connections and their types. @@ -73,12 +73,12 @@ class ADOdbLoadBalancer /** * @var bool Session variables that must be maintained across all connections, ie: SET TIME ZONE. */ - protected $session_variables = false; + protected $session_variables = []; /** * @var bool Called immediately after connecting to any DB. */ - protected $user_defined_session_init_sql = false; + protected $user_defined_session_init_sql = []; /** @@ -403,7 +403,7 @@ public function setSessionVariable($name, $value, $execute_immediately = true) */ private function executeSessionVariables($adodb_obj = false) { - if (is_array($this->session_variables)) { + if (is_array($this->session_variables) && count($this->session_variables) > 0) { $sql = ''; foreach ($this->session_variables as $name => $value) { // $sql .= 'SET SESSION '. $name .' '. $value; diff --git a/app/Vendor/adodb5/adodb-perf.inc.php b/app/Vendor/adodb5/adodb-perf.inc.php index d9d8a9937..916105365 100644 --- a/app/Vendor/adodb5/adodb-perf.inc.php +++ b/app/Vendor/adodb5/adodb-perf.inc.php @@ -237,6 +237,9 @@ class adodb_perf { var $createTableSQL = false; var $maxLength = 2000; + /** @var array Settings data. */ + var $settings = []; + // Sets the tablename to be used static function table($newtable = false) { @@ -1014,7 +1017,7 @@ function SplitSQL($sql) * ADODB_OPT_LOW for CPU-less optimization * Default is LOW ADODB_OPT_LOW * @author Markus Staab - * @return Returns true on success and false on error + * @return bool true on success, false on error */ function OptimizeTables() { @@ -1045,7 +1048,7 @@ function OptimizeTables() * ADODB_OPT_LOW for CPU-less optimization * Default is LOW ADODB_OPT_LOW * @author Markus Staab - * @return Returns true on success and false on error + * @return bool true on success, false on error */ function OptimizeTable( $table, $mode = ADODB_OPT_LOW) { @@ -1059,7 +1062,7 @@ function OptimizeTable( $table, $mode = ADODB_OPT_LOW) * optimize each using optmizeTable() * * @author Markus Staab - * @return Returns true on success and false on error + * @return bool true on success, false on error */ function optimizeDatabase() { diff --git a/app/Vendor/adodb5/adodb-time.inc.php b/app/Vendor/adodb5/adodb-time.inc.php index cfbdc6a5c..0c3dd11de 100644 --- a/app/Vendor/adodb5/adodb-time.inc.php +++ b/app/Vendor/adodb5/adodb-time.inc.php @@ -2,6 +2,8 @@ /** * ADOdb Date Library. * + * @deprecated 5.22.6 Use 64-bit PHP native functions instead. + * * PHP native date functions use integer timestamps for computations. * Because of this, dates are restricted to the years 1901-2038 on Unix * and 1970-2038 on Windows due to integer overflow for dates beyond diff --git a/app/Vendor/adodb5/adodb-xmlschema.inc.php b/app/Vendor/adodb5/adodb-xmlschema.inc.php index 32b8afa1e..662e2aaec 100644 --- a/app/Vendor/adodb5/adodb-xmlschema.inc.php +++ b/app/Vendor/adodb5/adodb-xmlschema.inc.php @@ -235,6 +235,15 @@ class dbTable extends dbObject { */ var $drop_field = array(); + /** + * @var array Platform-specific options + * @access private + */ + var $currentPlatform = true; + + /** @var dbData Stores information about table data. */ + var $data; + /** * Iniitializes a new table object. * @@ -403,7 +412,7 @@ function addData( $attributes ) { * @param string $type ADODB datadict field type. * @param string $size Field size * @param array $opts Field options array - * @return array Field specifier array + * @return void */ function addField( $name, $type, $size = NULL, $opts = NULL ) { $field_id = $this->FieldID( $name ); @@ -437,7 +446,7 @@ function addField( $name, $type, $size = NULL, $opts = NULL ) { * @param string $field Field name * @param string $opt ADOdb field option * @param mixed $value Field option value - * @return array Field specifier array + * @return void */ function addFieldOpt( $field, $opt, $value = NULL ) { if( !isset( $value ) ) { @@ -773,6 +782,9 @@ class dbData extends dbObject { var $row; + /** @var string Field name */ + var $current_field; + /** * Initializes the new dbIndex object. * @@ -1282,6 +1294,9 @@ class adoSchema { */ var $continueOnError; + /** @var dbTable A table object. */ + var $obj; + /** * Creates an adoSchema object * diff --git a/app/Vendor/adodb5/adodb-xmlschema03.inc.php b/app/Vendor/adodb5/adodb-xmlschema03.inc.php index a03386b3c..3c8bce5d4 100644 --- a/app/Vendor/adodb5/adodb-xmlschema03.inc.php +++ b/app/Vendor/adodb5/adodb-xmlschema03.inc.php @@ -259,6 +259,8 @@ class dbTable extends dbObject { */ var $currentPlatform = true; + /** @var dbData Stores information about table data. */ + var $data; /** * Iniitializes a new table object. @@ -448,7 +450,7 @@ function addData( $attributes ) { * @param string $type ADODB datadict field type. * @param string $size Field size * @param array $opts Field options array - * @return array Field specifier array + * @return void */ function addField( $name, $type, $size = NULL, $opts = NULL ) { $field_id = $this->fieldID( $name ); @@ -484,7 +486,7 @@ function addField( $name, $type, $size = NULL, $opts = NULL ) { * @param string $field Field name * @param string $opt ADOdb field option * @param mixed $value Field option value - * @return array Field specifier array + * @return void */ function addFieldOpt( $field, $opt, $value = NULL ) { if( $this->currentPlatform ) { @@ -764,7 +766,7 @@ function _tag_close( $parser, $tag ) { * Adds a field to the index * * @param string $name Field name - * @return string Field list + * @return string[] Field list */ function addField( $name ) { $this->columns[$this->fieldID( $name )] = $name; @@ -777,7 +779,7 @@ function addField( $name ) { * Adds options to the index * * @param string $opt Comma-separated list of index options. - * @return string Option list + * @return string[] Option list */ function addIndexOpt( $opt ) { $this->opts[] = $opt; @@ -830,6 +832,9 @@ class dbData extends dbObject { var $row; + /** @var string Field name */ + var $current_field; + /** * Initializes the new dbData object. * @@ -924,10 +929,10 @@ function addField( $attributes ) { } /** - * Adds options to the index + * Adds data. * - * @param string $opt Comma-separated list of index options. - * @return string Option list + * @param string $cdata Data to add + * @return void */ function addData( $cdata ) { // check we're in a valid field @@ -1401,6 +1406,9 @@ class adoSchema { */ var $existingData; + /** @var dbTable A table object. */ + var $obj; + /** * Creates an adoSchema object * @@ -1774,7 +1782,7 @@ function saveSQL( $filename = './schema.sql' ) { $sqlArray = $this->sqlArray; } if( !isset( $sqlArray ) ) { - return FALSE; + return false; } $fp = fopen( $filename, "w" ); diff --git a/app/Vendor/adodb5/adodb.inc.php b/app/Vendor/adodb5/adodb.inc.php index c0c94cedc..5bb8b23a0 100644 --- a/app/Vendor/adodb5/adodb.inc.php +++ b/app/Vendor/adodb5/adodb.inc.php @@ -198,7 +198,7 @@ function ADODB_Setup() { /** * ADODB version as a string. */ - $ADODB_vers = 'v5.22.5-dev Unreleased'; + $ADODB_vers = 'v5.22.7 2023-11-04'; /** * Determines whether recordset->RecordCount() is used. @@ -221,8 +221,12 @@ function ADODB_Setup() { // CLASS ADOFieldObject //============================================================================================== /** - * Helper class for FetchFields -- holds info on a column + * Helper class for FetchFields -- holds info on a column. + * + * Note: Dynamic properties are required here, as some drivers may require + * the object to hold database-specific field metadata. */ + #[\AllowDynamicProperties] class ADOFieldObject { var $name = ''; var $max_length=0; @@ -387,10 +391,7 @@ function flushcache($f, $debug=false) { */ function getdirname($hash) { global $ADODB_CACHE_DIR; - if (!isset($this->notSafeMode)) { - $this->notSafeMode = !ini_get('safe_mode'); - } - return ($this->notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($hash,0,2) : $ADODB_CACHE_DIR; + return $ADODB_CACHE_DIR . '/' . substr($hash, 0, 2); } /** @@ -405,7 +406,7 @@ function createdir($hash, $debug) { global $ADODB_CACHE_PERMS; $dir = $this->getdirname($hash); - if ($this->notSafeMode && !file_exists($dir)) { + if (!file_exists($dir)) { $oldu = umask(0); if (!@mkdir($dir, empty($ADODB_CACHE_PERMS) ? 0771 : $ADODB_CACHE_PERMS)) { if(!is_dir($dir) && $debug) { @@ -458,7 +459,14 @@ abstract class ADOConnection { // var $dataProvider = 'native'; var $databaseType = ''; /// RDBMS currently in use, eg. odbc, mysql, mssql - var $database = ''; /// Name of database to be used. + + /** + * @var string Current database name. + * + * This used to be stored in the $databaseName property, which was marked + * as deprecated in 4.66 and removed in 5.22.5. + */ + public $database = ''; /** * @var string If the driver is PDO, then the dsnType is e.g. sqlsrv, otherwise empty @@ -485,8 +493,33 @@ abstract class ADOConnection { var $leftBracket = '['; /// left square bracked for t-sql styled column names var $rightBracket = ']'; /// right square bracked for t-sql styled column names var $charSet=false; /// character set to use - only for interbase, postgres and oci8 + + /** @var string SQL statement to get databases */ var $metaDatabasesSQL = ''; + + /** @var string SQL statement to get database tables */ var $metaTablesSQL = ''; + + /** @var string SQL statement to get table columns. */ + var $metaColumnsSQL; + + /** + * SQL statement to get the last IDENTITY value inserted into an IDENTITY + * column in the same scope. + * @see https://learn.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql + * @var string + */ + var $identitySQL; + + /** @var string SQL statement to create a Sequence . */ + var $_genSeqSQL; + + /** @var string SQL statement to drop a Sequence. */ + var $_dropSeqSQL; + + /** @var string SQL statement to generate a Sequence ID. */ + var $_genIDSQL; + var $uniqueOrderBy = false; /// All order by columns have to be unique var $emptyDate = ' '; var $emptyTimeStamp = ' '; @@ -584,6 +617,10 @@ abstract class ADOConnection { var $null2null = 'null'; // in autoexecute/getinsertsql/getupdatesql, this value will be converted to a null var $bulkBind = false; // enable 2D Execute array + + /** @var string SQL statement executed by some drivers after successful connection. */ + public $connectStmt = ''; + // // PRIVATE VARS // @@ -591,14 +628,34 @@ abstract class ADOConnection { var $_transOK = null; /** @var resource Identifier for the native database connection */ var $_connectionID = false; - var $_errorMsg = false; /// A variable which was used to keep the returned last error message. The value will - /// then returned by the errorMsg() function - var $_errorCode = false; /// Last error code, not guaranteed to be used - only by oci8 + + /** + * Stores the last returned error message. + * @see ADOConnection::errorMsg() + * @var string|false + */ + var $_errorMsg = false; + + /** + * Stores the last returned error code. + * Not guaranteed to be used. Only some drivers actually populate it. + * @var int|false + */ + var $_errorCode = false; + var $_queryID = false; /// This variable keeps the last created result link identifier var $_isPersistentConnection = false; /// A boolean variable to state whether its a persistent connection or normal connection. */ var $_bindInputArray = false; /// set to true if ADOConnection.Execute() permits binding of array parameters. - var $_evalAll = false; + + /** + * Eval string used to filter data. + * Only used in the deprecated Text driver. + * @see https://adodb.org/dokuwiki/doku.php?id=v5:database:text#workaround + * @var string + */ + var $evalAll = false; + var $_affected = false; var $_logsql = false; var $_transmode = ''; // transaction mode @@ -633,6 +690,12 @@ abstract class ADOConnection { */ public $customMetaTypes = array(); + /** @var ADORecordSet Recordset used to retrieve MetaType information */ + var $_metars; + + /** @var string a specified locale. */ + var $locale; + /** * Default Constructor. @@ -1403,7 +1466,7 @@ function HasFailedTrans() { * @param array|bool $inputarr holds the input data to bind to. * Null elements will be set to null. * - * @return ADORecordSet|bool + * @return ADORecordSet|false */ public function Execute($sql, $inputarr = false) { if ($this->fnExecute) { @@ -1606,6 +1669,18 @@ function _Execute($sql,$inputarr=false) { return $rs; } + /** + * Execute a query. + * + * @param string|array $sql Query to execute. + * @param array $inputarr An optional array of parameters. + * + * @return mixed|bool Query identifier or true if execution successful, false if failed. + */ + function _query($sql, $inputarr = false) { + return false; + } + function CreateSequence($seqname='adodbseq',$startID=1) { if (empty($this->_genSeqSQL)) { return false; @@ -2421,7 +2496,7 @@ function CacheFlush($sql=false,$inputarr=false) { * - userid * - setFetchMode (adodb 4.23) * - * When not in safe mode, we create 256 sub-directories in the cache directory ($ADODB_CACHE_DIR). + * We create 256 sub-directories in the cache directory ($ADODB_CACHE_DIR). * Assuming that we can have 50,000 files per directory with good performance, * then we can scale to 12.8 million unique cached recordsets. Wow! */ @@ -3494,20 +3569,21 @@ function qStr($s, $magic_quotes=false) { /** - * Will select the supplied $page number from a recordset, given that it is paginated in pages of - * $nrows rows per page. It also saves two boolean values saying if the given page is the first - * and/or last one of the recordset. Added by Iván Oliva to provide recordset pagination. + * Execute query with pagination. * - * See docs-adodb.htm#ex8 for an example of usage. - * NOTE: phpLens uses a different algorithm and does not use PageExecute(). + * Will select the supplied $page number from a recordset, divided in + * pages of $nrows rows each. It also saves two boolean values saying + * if the given page is the first and/or last one of the recordset. * - * @param string $sql - * @param int $nrows Number of rows per page to get - * @param int $page Page number to get (1-based) - * @param mixed[]|bool $inputarr Array of bind variables - * @param int $secs2cache Private parameter only used by jlim + * @param string $sql Query to execute + * @param int $nrows Number of rows per page + * @param int $page Page number to retrieve (1-based) + * @param array|bool $inputarr Array of bind variables + * @param int $secs2cache Time-to-live of the cache (in seconds), 0 to force query execution * - * @return mixed the recordset ($rs->databaseType == 'array') + * @return ADORecordSet|bool the recordset ($rs->databaseType == 'array') + * + * @author Iván Oliva */ function PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) { global $ADODB_INCLUDED_LIB; @@ -3683,6 +3759,7 @@ protected function getChangedErrorMsg($old = null) { /** * Internal placeholder for record objects. Used by ADORecordSet->FetchObj(). */ + #[\AllowDynamicProperties] class ADOFetchObj { }; @@ -3882,6 +3959,12 @@ class ADORecordSet implements IteratorAggregate { * public variables */ var $dataProvider = "native"; + + /** + * @var string Table name (used in _adodb_getupdatesql() and _adodb_getinsertsql())- + */ + public $tableName = ''; + /** @var bool|array */ var $fields = false; /// holds the current row data var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob @@ -3916,16 +3999,27 @@ class ADORecordSet implements IteratorAggregate { var $_obj; /** Used by FetchObj */ var $_names; /** Used by FetchObj */ - var $_currentPage = -1; /** Added by Iván Oliva to implement recordset pagination */ - var $_atFirstPage = false; /** Added by Iván Oliva to implement recordset pagination */ - var $_atLastPage = false; /** Added by Iván Oliva to implement recordset pagination */ + // Recordset pagination + /** @var int Number of rows per page */ + var $rowsPerPage; + /** @var int Current page number */ + var $_currentPage = -1; + /** @var bool True if current page is the first page */ + var $_atFirstPage = false; + /** @var bool True if current page is the last page */ + var $_atLastPage = false; + /** @var int Last page number */ var $_lastPageNo = -1; + /** @var int Total number of rows in recordset */ var $_maxRecordCount = 0; + var $datetime = false; public $customActualTypes; public $customMetaTypes; + /** @var int Only used in _adodb_getinsertsql() */ + public $insertSig; /** * @var ADOFieldObject[] Field metadata cache @@ -3933,6 +4027,12 @@ class ADORecordSet implements IteratorAggregate { */ protected $fieldObjectsCache; + /** + * @var int Defines the Fetch Mode for a recordset + * See the ADODB_FETCH_* constants + */ + public $adodbFetchMode; + /** * Constructor * @@ -5746,6 +5846,7 @@ function newDataDictionary(&$conn, $drivername='') { } include_once($path); $class = "ADODB2_$drivername"; + /** @var ADODB_DataDict $dict */ $dict = new $class(); $dict->dataProvider = $conn->dataProvider; $dict->connection = $conn; diff --git a/app/Vendor/adodb5/docs/changelog.md b/app/Vendor/adodb5/docs/changelog.md index acabcbf97..aa068e102 100644 --- a/app/Vendor/adodb5/docs/changelog.md +++ b/app/Vendor/adodb5/docs/changelog.md @@ -14,19 +14,109 @@ Older changelogs: -------------------------------------------------------------------------------- -## [5.22.5] - Unreleased +## [5.22.7] - 2023-11-04 + +### Fixed + +- Respect @ operator in all error handlers on PHP 8 + [#981](https://github.com/ADOdb/ADOdb/issues/981) +- db2: Declaration of ADODB_db2::_query incompatible with parent + [#987](https://github.com/ADOdb/ADOdb/issues/987) +- mysqli: bulkBind reset after one call + [#1000](https://github.com/ADOdb/ADOdb/issues/1000) +- oci8: deprecation warning in selectLimit() on PHP 8.1 + [#992](https://github.com/ADOdb/ADOdb/issues/992) +- oci8: Fix Automatic conversion of false to array + [#998](https://github.com/ADOdb/ADOdb/issues/998) +- oci8: Prevent str_replace NULL error in qstr() methods on PHP 8.1 + [#999](https://github.com/ADOdb/ADOdb/issues/999) + + +## [5.22.6] - 2023-06-11 + +### Deprecated + +- Date/Time Library + [#970](https://github.com/ADOdb/ADOdb/issues/970) + +### Fixed + +- Creation of dynamic property deprecated warning with PHP 8.2 + [#954](https://github.com/ADOdb/ADOdb/issues/954) + [#975](https://github.com/ADOdb/ADOdb/issues/975) +- Remove unused oldProvider property in _rs2serialize() + [#957](https://github.com/ADOdb/ADOdb/issues/957) +- Fix ADOConnection::execute() documentation of return type + [#964](https://github.com/ADOdb/ADOdb/issues/964) +- Define _query() method in ADOConnection base class + [#966](https://github.com/ADOdb/ADOdb/issues/966) +- Restore rs2html() $htmlspecialchars param behavior + [#968](https://github.com/ADOdb/ADOdb/issues/968) +- adodb_throw() does not respect @ operator on PHP 8 + [#981](https://github.com/ADOdb/ADOdb/issues/981) +- loadbalancer: PHP 8.2 warnings + [#951](https://github.com/ADOdb/ADOdb/issues/951) +- mysql: Fail connection if native driver (mysqlnd) is not available + [#967](https://github.com/ADOdb/ADOdb/issues/967) +- pgsql: Fix PHP 8.1 deprecated warning + [#956](https://github.com/ADOdb/ADOdb/issues/956) +- pgsql: avoid Insert_ID() failing when lastval() is not set + [#978](https://github.com/ADOdb/ADOdb/issues/978) + + +## [5.22.5] - 2023-04-03 + +### Removed + +- Obsolete ADOConnection::$databaseName property + [#932](https://github.com/ADOdb/ADOdb/issues/932) +- Dead code related to safe_mode + [#934](https://github.com/ADOdb/ADOdb/issues/934) +- pdo: remove unnecessary methods _init() and _affectedrows() + [#935](https://github.com/ADOdb/ADOdb/issues/935) ### Fixed - ADODB_FETCH_DEFAULT should be treated as ASSOC in getAssoc() [#886](https://github.com/ADOdb/ADOdb/issues/886) +- Allow dynamic properties for ADOFieldObject class + [#906](https://github.com/ADOdb/ADOdb/issues/906) - Fix autoExecute() $where parameter type [#915](https://github.com/ADOdb/ADOdb/issues/915) -- pgsql: fix "column already exists" error when adding a new column - [#897](https://github.com/ADOdb/ADOdb/issues/897) - Creation of dynamic property deprecated warning in PHP 8.2 + [#904](https://github.com/ADOdb/ADOdb/issues/904) + [#907](https://github.com/ADOdb/ADOdb/issues/907) + [#908](https://github.com/ADOdb/ADOdb/issues/908) + [#909](https://github.com/ADOdb/ADOdb/issues/909) + [#911](https://github.com/ADOdb/ADOdb/issues/911) + [#912](https://github.com/ADOdb/ADOdb/issues/912) [#913](https://github.com/ADOdb/ADOdb/issues/913) [#917](https://github.com/ADOdb/ADOdb/issues/917) + [#926](https://github.com/ADOdb/ADOdb/issues/926) + [#933](https://github.com/ADOdb/ADOdb/issues/933) + [#935](https://github.com/ADOdb/ADOdb/issues/935) +- Partially-supported callable deprecated warning in PHP 8.2 + [#928](https://github.com/ADOdb/ADOdb/issues/928) +- Passing null to non-nullable parameter is deprecated in PHP 8.1 + [#938](https://github.com/ADOdb/ADOdb/issues/938) +- Define adodbFetchMode property in base ADORecordSet class + [#923](https://github.com/ADOdb/ADOdb/issues/923) +- mysql: uncaught exception calling execute() with empty SQL on PHP 8 + [#945](https://github.com/ADOdb/ADOdb/issues/945) +- oci8: Replace obsolete oci_free_cursor() function alias + [#937](https://github.com/ADOdb/ADOdb/issues/937) +- pdo: Move setTransactionMode() to ADODB_pdo_sqlsrv class + [#939](https://github.com/ADOdb/ADOdb/issues/939) +- pgsql: fix "column already exists" error when adding a new column + [#897](https://github.com/ADOdb/ADOdb/issues/897) +- pgsql: undefined array key in metaIndexes() when column is an expression + [#940](https://github.com/ADOdb/ADOdb/issues/940) +- pgsql: revert non-functional "Noblob optimization" + [#112](https://github.com/ADOdb/ADOdb/issues/112) +- session: full table scan when accessing sessions table on MySQL + [#941](https://github.com/ADOdb/ADOdb/issues/941) +- session: inconsistent DB provider check + [#943](https://github.com/ADOdb/ADOdb/issues/943) ## [5.22.4] - 2022-10-28 @@ -613,9 +703,9 @@ Includes all fixes from 5.20.19. ## [5.20.16] - 2020-01-12 --### Fixed +### Fixed - mssql: queries are not correctly closed +- mssql: queries are not correctly closed [#590](https://github.com/ADOdb/ADOdb/issues/590) @@ -1344,7 +1434,9 @@ Released together with [v4.95](changelog_v4.x.md#495---17-may-2007) - Adodb5 version,more error checking code now will use exceptions if available. -[5.22.5]: https://github.com/adodb/adodb/compare/v5.22.4...hotfix/5.22 +[5.22.7]: https://github.com/adodb/adodb/compare/v5.22.6...v5.22.7 +[5.22.6]: https://github.com/adodb/adodb/compare/v5.22.5...v5.22.6 +[5.22.5]: https://github.com/adodb/adodb/compare/v5.22.4...v5.22.5 [5.22.4]: https://github.com/adodb/adodb/compare/v5.22.3...v5.22.4 [5.22.3]: https://github.com/adodb/adodb/compare/v5.22.2...v5.22.3 [5.22.2]: https://github.com/adodb/adodb/compare/v5.22.1...v5.22.2 diff --git a/app/Vendor/adodb5/drivers/adodb-ado.inc.php b/app/Vendor/adodb5/drivers/adodb-ado.inc.php index fc000cecb..df95c6901 100644 --- a/app/Vendor/adodb5/drivers/adodb-ado.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-ado.inc.php @@ -208,10 +208,6 @@ function MetaColumns($table, $normalize=true) return empty($arr) ? $false : $arr; } - - - - /* returns queryID or false */ function _query($sql,$inputarr=false) { @@ -504,7 +500,7 @@ function MetaType($t,$len=-1,$fieldobj=false) $t = $fieldobj->type; $len = $fieldobj->max_length; } - + if (array_key_exists($t,$this->connection->customActualTypes)) return $this->connection->customActualTypes[$t]; diff --git a/app/Vendor/adodb5/drivers/adodb-ado5.inc.php b/app/Vendor/adodb5/drivers/adodb-ado5.inc.php index 36f9c3b8d..04b45abf6 100644 --- a/app/Vendor/adodb5/drivers/adodb-ado5.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-ado5.inc.php @@ -233,7 +233,6 @@ function MetaColumns($table, $normalize=true) return $arr; } - /* returns queryID or false */ function _query($sql,$inputarr=false) { try { // In PHP5, all COM errors are exceptions, so to maintain old behaviour... @@ -545,13 +544,13 @@ function MetaType($t,$len=-1,$fieldobj=false) $t = $fieldobj->type; $len = $fieldobj->max_length; } - + $t = strtoupper($t); - + if (array_key_exists($t,$this->connection->customActualTypes)) return $this->connection->customActualTypes[$t]; - if (!is_numeric($t)) + if (!is_numeric($t)) return $t; switch ($t) { diff --git a/app/Vendor/adodb5/drivers/adodb-ads.inc.php b/app/Vendor/adodb5/drivers/adodb-ads.inc.php index b9d4adb52..16eec9766 100644 --- a/app/Vendor/adodb5/drivers/adodb-ads.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-ads.inc.php @@ -97,7 +97,7 @@ function _connect($argDSN, $argUsername, $argPassword, $argDatabasename) $this->_connectionID = ads_connect($argDSN, $argUsername, $argPassword, $this->curmode); } $this->_errorMsg = $this->getChangedErrorMsg($last_php_error); - if (isset($this->connectStmt)) { + if ($this->connectStmt) { $this->Execute($this->connectStmt); } @@ -127,7 +127,7 @@ function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename) if ($this->_connectionID && $this->autoRollback) { @ads_rollback($this->_connectionID); } - if (isset($this->connectStmt)) { + if ($this->connectStmt) { $this->Execute($this->connectStmt); } @@ -564,7 +564,6 @@ function Prepare($sql) return array($sql, $stmt, false); } - /* returns queryID or false */ function _query($sql, $inputarr = false) { $last_php_error = $this->resetLastError(); diff --git a/app/Vendor/adodb5/drivers/adodb-csv.inc.php b/app/Vendor/adodb5/drivers/adodb-csv.inc.php index 8a59626e1..e6694d9ad 100644 --- a/app/Vendor/adodb5/drivers/adodb-csv.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-csv.inc.php @@ -199,7 +199,7 @@ function _close() } } // class -class ADORecordset_csv extends ADORecordset { +class ADORecordset_csv extends ADORecordSet { function _close() { diff --git a/app/Vendor/adodb5/drivers/adodb-db2.inc.php b/app/Vendor/adodb5/drivers/adodb-db2.inc.php index 16c4054f1..7c773849d 100644 --- a/app/Vendor/adodb5/drivers/adodb-db2.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-db2.inc.php @@ -77,16 +77,6 @@ class ADODB_db2 extends ADOConnection { */ public $nameQuote = '"'; - /* - * Executed after successful connection - */ - public $connectStmt = ''; - - /* - * Holds the current database name - */ - private $databaseName = ''; - /* * Holds information about the stored procedure request * currently being built @@ -113,7 +103,7 @@ public function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename) private function doDB2Connect($argDSN, $argUsername, $argPassword, $argDatabasename, $persistent=false) { - + if (!function_exists('db2_connect')) { ADOConnection::outp("DB2 extension not installed."); return null; @@ -184,7 +174,7 @@ private function doDB2Connect($argDSN, $argUsername, $argPassword, $argDatabasen null, $db2Options); - + $this->_errorMsg = @db2_conn_errormsg(); if ($this->_connectionID && $this->connectStmt) @@ -207,7 +197,7 @@ private function doDB2Connect($argDSN, $argUsername, $argPassword, $argDatabasen private function unpackParameters($argDSN, $argUsername, $argPassword, $argDatabasename) { - + $connectionParameters = array('dsn'=>'', 'uid'=>'', 'pwd'=>'', @@ -257,7 +247,7 @@ private function unpackParameters($argDSN, $argUsername, $argPassword, $argDatab $errorMessage = 'Supply uncatalogued connection parameters '; $errorMessage.= 'in either the database or DSN arguments, '; $errorMessage.= 'but not both'; - + if ($this->debug) ADOConnection::outp($errorMessage); return null; @@ -282,7 +272,7 @@ private function unpackParameters($argDSN, $argUsername, $argPassword, $argDatab { $errorMessage = 'For uncatalogued connections, provide '; $errorMessage.= 'both UID and PWD in the connection string'; - + if ($this->debug) ADOConnection::outp($errorMessage); return null; @@ -307,7 +297,7 @@ private function unpackParameters($argDSN, $argUsername, $argPassword, $argDatab } elseif ($argDatabasename) { - $this->databaseName = $argDatabasename; + $this->database = $argDatabasename; $argDSN .= ';database=' . $argDatabasename; $argDatabasename = ''; $useCataloguedConnection = false; @@ -317,7 +307,7 @@ private function unpackParameters($argDSN, $argUsername, $argPassword, $argDatab { $errorMessage = 'Uncatalogued connection parameters '; $errorMessage.= 'must contain a database= argument'; - + if ($this->debug) ADOConnection::outp($errorMessage); return null; @@ -347,9 +337,9 @@ private function unpackParameters($argDSN, $argUsername, $argPassword, $argDatab } if ($argDatabasename) - $this->databaseName = $argDatabasename; - elseif (!$this->databaseName) - $this->databaseName = $this->getDatabasenameFromDsn($argDSN); + $this->database = $argDatabasename; + elseif (!$this->database) + $this->database = $this->getDatabasenameFromDsn($argDSN); $connectionParameters = array('dsn'=>$argDSN, @@ -1003,7 +993,7 @@ public function metaProcedures($procedureNamePattern = null, $catalog = null, $ */ public function metaDatabases(){ - $dbName = $this->getMetaCasedValue($this->databaseName); + $dbName = $this->getMetaCasedValue($this->database); return (array)$dbName; @@ -1578,11 +1568,8 @@ function prepare($sql) * * @return mixed either the queryID or false */ - function _query(&$sql,$inputarr=false) + function _query($sql, $inputarr = false) { - - $this->_error = ''; - $db2Options = array(); /* * Use DB2 Internal case handling for best speed @@ -1618,10 +1605,10 @@ function _query(&$sql,$inputarr=false) { $this->_errorMsg = @db2_stmt_errormsg(); $this->_errorCode = @db2_stmt_error(); - + if ($this->debug) ADOConnection::outp($this->_errorMsg); - + return false; } } @@ -1995,14 +1982,13 @@ function _close() $ok = @db2_free_result($this->_queryID); if (!$ok) { - $this->_errorMsg = @db2_stmt_errormsg($this->_queryId); - $this->_errorCode = @db2_stmt_error(); + $this->connection->_errorMsg = @db2_stmt_errormsg($this->_queryID); + $this->connection->_errorCode = @db2_stmt_error(); if ($this->debug) - ADOConnection::outp($this->_errorMsg); + ADOConnection::outp($this->connection->_errorMsg); return false; } - } } diff --git a/app/Vendor/adodb5/drivers/adodb-fbsql.inc.php b/app/Vendor/adodb5/drivers/adodb-fbsql.inc.php index a4255eb97..64913bc24 100644 --- a/app/Vendor/adodb5/drivers/adodb-fbsql.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-fbsql.inc.php @@ -134,7 +134,6 @@ function SelectDB($dbName) } - // returns queryID or false function _query($sql,$inputarr=false) { return fbsql_query("$sql;",$this->_connectionID); diff --git a/app/Vendor/adodb5/drivers/adodb-firebird.inc.php b/app/Vendor/adodb5/drivers/adodb-firebird.inc.php index 133d9f43c..db3cca5d6 100644 --- a/app/Vendor/adodb5/drivers/adodb-firebird.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-firebird.inc.php @@ -483,14 +483,14 @@ public function prepare($sql) } /** - * Return the query id. - * - * @param string|array $sql - * @param array $iarr - * - * @return bool|object - */ - function _query($sql, $iarr = false) + * Execute a query. + * + * @param string|array $sql Query to execute. + * @param array $inputarr An optional array of parameters. + * + * @return object|bool Query identifier or true if execution successful, false if failed. + */ + function _query($sql, $inputarr = false) { if (!$this->isConnected()) { return false; @@ -512,8 +512,8 @@ function _query($sql, $iarr = false) $fn = 'fbird_query'; $args = [$conn, $sql]; } - if (is_array($iarr)) { - $args = array_merge($args, $iarr); + if (is_array($inputarr)) { + $args = array_merge($args, $inputarr); } $ret = call_user_func_array($fn, $args); diff --git a/app/Vendor/adodb5/drivers/adodb-ibase.inc.php b/app/Vendor/adodb5/drivers/adodb-ibase.inc.php index 25a9c3e86..8159c512d 100644 --- a/app/Vendor/adodb5/drivers/adodb-ibase.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-ibase.inc.php @@ -256,7 +256,7 @@ function MetaIndexes ($table, $primary = FALSE, $owner=false) // See http://community.borland.com/article/0,1410,25844,00.html - function RowLock($tables,$where,$col=false) + function rowLock($table, $where, $col = false) { if ($this->autoCommit) { $this->BeginTrans(); @@ -332,7 +332,7 @@ function Prepare($sql) // returns query ID if successful, otherwise false // there have been reports of problems with nested queries - the code is probably not re-entrant? - function _query($sql,$iarr=false) + function _query($sql, $inputarr = false) { if (!$this->autoCommit && $this->_transactionID) { $conn = $this->_transactionID; @@ -344,11 +344,11 @@ function _query($sql,$iarr=false) if (is_array($sql)) { $fn = 'ibase_execute'; $sql = $sql[1]; - if (is_array($iarr)) { - if (!isset($iarr[0])) { - $iarr[0] = ''; // PHP5 compat hack + if (is_array($inputarr)) { + if (!isset($inputarr[0])) { + $inputarr[0] = ''; // PHP5 compat hack } - $fnarr = array_merge(array($sql), $iarr); + $fnarr = array_merge(array($sql), $inputarr); $ret = call_user_func_array($fn, $fnarr); } else { $ret = $fn($sql); @@ -356,11 +356,11 @@ function _query($sql,$iarr=false) } else { $fn = 'ibase_query'; - if (is_array($iarr)) { - if (sizeof($iarr) == 0) { - $iarr[0] = ''; // PHP5 compat hack + if (is_array($inputarr)) { + if (sizeof($inputarr) == 0) { + $inputarr[0] = ''; // PHP5 compat hack } - $fnarr = array_merge(array($conn, $sql), $iarr); + $fnarr = array_merge(array($conn, $sql), $inputarr); $ret = call_user_func_array($fn, $fnarr); } else { $ret = $fn($conn, $sql); @@ -734,7 +734,7 @@ function SQLDate($fmt, $col=false) Class Name: Recordset --------------------------------------------------------------------------------------*/ -class ADORecordset_ibase extends ADORecordSet +class ADORecordSet_ibase extends ADORecordSet { var $databaseType = "ibase"; diff --git a/app/Vendor/adodb5/drivers/adodb-informix72.inc.php b/app/Vendor/adodb5/drivers/adodb-informix72.inc.php index 79e5138a9..6fddde3d6 100644 --- a/app/Vendor/adodb5/drivers/adodb-informix72.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-informix72.inc.php @@ -80,12 +80,9 @@ function __construct() function ServerInfo() { - if (isset($this->version)) return $this->version; - - $arr['description'] = $this->GetOne("select DBINFO('version','full') from systables where tabid = 1"); - $arr['version'] = $this->GetOne("select DBINFO('version','major') || DBINFO('version','minor') from systables where tabid = 1"); - $this->version = $arr; - return $arr; + $arr['description'] = $this->GetOne("select DBINFO('version','full') from systables where tabid = 1"); + $arr['version'] = $this->GetOne("select DBINFO('version','major') || DBINFO('version','minor') from systables where tabid = 1"); + return $arr; } @@ -337,7 +334,6 @@ function Prepare($sql) else return array($sql,$stmt); } */ - // returns query ID if successful, otherwise false function _query($sql,$inputarr=false) { global $ADODB_COUNTRECS; diff --git a/app/Vendor/adodb5/drivers/adodb-ldap.inc.php b/app/Vendor/adodb5/drivers/adodb-ldap.inc.php index 323b35856..305f6a7ff 100644 --- a/app/Vendor/adodb5/drivers/adodb-ldap.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-ldap.inc.php @@ -157,7 +157,6 @@ function _inject_bind_options( $options ) { } } - /* returns _queryID or false */ function _query($sql,$inputarr=false) { $rs = @ldap_search( $this->_connectionID, $this->database, $sql ); diff --git a/app/Vendor/adodb5/drivers/adodb-mssql.inc.php b/app/Vendor/adodb5/drivers/adodb-mssql.inc.php index 8fb92249c..c0b714ede 100644 --- a/app/Vendor/adodb5/drivers/adodb-mssql.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-mssql.inc.php @@ -541,7 +541,6 @@ function MetaTables($ttype=false,$showSchema=false,$mask=false) function SelectDB($dbName) { $this->database = $dbName; - $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions if ($this->_connectionID) { return @mssql_select_db($dbName); } @@ -726,7 +725,6 @@ function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') return $this->Execute($sql) != false; } - // returns query ID if successful, otherwise false function _query($sql,$inputarr=false) { $this->_errorMsg = false; diff --git a/app/Vendor/adodb5/drivers/adodb-mssqlnative.inc.php b/app/Vendor/adodb5/drivers/adodb-mssqlnative.inc.php index 41bb7e3e8..f7e1bcc16 100644 --- a/app/Vendor/adodb5/drivers/adodb-mssqlnative.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-mssqlnative.inc.php @@ -440,7 +440,6 @@ function RowLock($tables,$where,$col='1 as adodbignore') function SelectDB($dbName) { $this->database = $dbName; - $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions if ($this->_connectionID) { $rs = $this->Execute('USE '.$dbName); if($rs) { diff --git a/app/Vendor/adodb5/drivers/adodb-mysqli.inc.php b/app/Vendor/adodb5/drivers/adodb-mysqli.inc.php index 4948f1851..7ec8962d4 100644 --- a/app/Vendor/adodb5/drivers/adodb-mysqli.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-mysqli.inc.php @@ -167,6 +167,14 @@ function _connect($argHostname = null, if(!extension_loaded("mysqli")) { return null; } + // Check for a function that only exists in mysqlnd + if (!function_exists('mysqli_stmt_get_result')) { + // @TODO This will be treated as if the mysqli extension were not available + // This could be misleading, so we output an additional error message. + // We should probably throw a specific exception instead. + $this->outp("MySQL Native Driver (msqlnd) required"); + return null; + } $this->_connectionID = @mysqli_init(); if (is_null($this->_connectionID)) { @@ -932,7 +940,7 @@ function MetaColumns($table, $normalize = true) $SQL = "SELECT column_name, column_type FROM information_schema.columns - WHERE table_schema='{$this->databaseName}' + WHERE table_schema='{$this->database}' AND table_name='$table'"; $schemaArray = $this->getAssoc($SQL); @@ -1017,7 +1025,6 @@ function SelectDB($dbName) { // $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID); $this->database = $dbName; - $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions if ($this->_connectionID) { $result = @mysqli_select_db($this->_connectionID, $dbName); @@ -1092,16 +1099,6 @@ function Prepare($sql) return array($sql,$stmt); } - /** - * Execute SQL - * - * @param string $sql SQL statement to execute, or possibly an array - * holding prepared statement ($sql[0] will hold sql text) - * @param array|bool $inputarr holds the input data to bind to. - * Null elements will be set to null. - * - * @return ADORecordSet|bool - */ public function execute($sql, $inputarr = false) { if ($this->fnExecute) { @@ -1147,8 +1144,10 @@ public function execute($sql, $inputarr = false) } $bulkTypeArray[] = $typeArray; } + $currentBulkBind = $this->bulkBind; $this->bulkBind = false; $ret = $this->_execute($sql, $bulkTypeArray); + $this->bulkBind = $currentBulkBind; } else { $typeArray = $this->getBindParamWithType($inputarr); $ret = $this->_execute($sql, $typeArray); @@ -1190,14 +1189,14 @@ private function getBindParamWithType($inputArr): array } /** - * Return the query id. - * - * @param string|array $sql - * @param array $inputarr - * - * @return bool|mysqli_result + * Execute a query. + * + * @param string|array $sql Query to execute. + * @param array $inputarr An optional array of parameters. + * + * @return mysqli_result|bool */ - function _query($sql, $inputarr) + function _query($sql, $inputarr = false) { global $ADODB_COUNTRECS; // Move to the next recordset, or return false if there is none. In a stored proc @@ -1207,6 +1206,14 @@ function _query($sql, $inputarr) // Commented out for reasons of performance. You should retrieve every recordset yourself. // if (!mysqli_next_result($this->connection->_connectionID)) return false; + // When SQL is empty, mysqli_query() throws exception on PHP 8 (#945) + if (!$sql) { + if ($this->debug) { + ADOConnection::outp("Empty query"); + } + return false; + } + if (is_array($sql)) { // Prepare() not supported because mysqli_stmt_execute does not return a recordset, but @@ -1459,6 +1466,9 @@ function getCharSet() return $this->charSet ?: false; } + /** + * @deprecated 5.21.0 Use {@see setConnectionParameter()} instead + */ function setCharSet($charset) { if (!$this->_connectionID || !method_exists($this->_connectionID,'set_charset')) { diff --git a/app/Vendor/adodb5/drivers/adodb-oci8.inc.php b/app/Vendor/adodb5/drivers/adodb-oci8.inc.php index c1f4e5020..965c1621c 100644 --- a/app/Vendor/adodb5/drivers/adodb-oci8.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-oci8.inc.php @@ -92,7 +92,7 @@ class ADODB_oci8 extends ADOConnection { var $random = "abs(mod(DBMS_RANDOM.RANDOM,10000001)/10000000)"; var $noNullStrings = false; var $connectSID = false; - var $_bind = false; + var $_bind = array(); var $_nestedSQL = true; var $_getarray = false; // currently not working var $leftOuter = ''; // oracle wierdness, $col = $value (+) for LEFT OUTER, $col (+)= $value for RIGHT OUTER @@ -321,10 +321,6 @@ function IfNull( $field, $ifNull ) protected function _insertID($table = '', $column = '') { - - if (!$this->seqField) - return false; - if ($this->schema) { $t = strpos($table,'.'); @@ -785,6 +781,11 @@ function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) $hint = ''; } + // If non-bound statement, $inputarr is false + if (!$inputarr) { + $inputarr = array(); + } + if ($offset == -1 || ($offset < $this->selectOffsetAlg1 && 0 < $nrows && $nrows < 1000)) { if ($nrows > 0) { if ($offset > 0) { @@ -792,10 +793,6 @@ function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) } $sql = "select * from (".$sql.") where rownum <= :adodb_offset"; - // If non-bound statement, $inputarr is false - if (!$inputarr) { - $inputarr = array(); - } $inputarr['adodb_offset'] = $nrows; $nrows = -1; } @@ -813,32 +810,31 @@ function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) } $stmt = $stmt_arr[1]; - if (is_array($inputarr)) { - foreach($inputarr as $k => $v) { - $i=0; - if ($this->databaseType == 'oci8po') { - $bv_name = ":".$i++; + foreach($inputarr as $k => $v) { + $i = 0; + if ($this->databaseType == 'oci8po') { + $bv_name = ":" . $i++; + } else { + $bv_name = ":" . $k; + } + if (is_array($v)) { + // suggested by g.giunta@libero. + if (sizeof($v) == 2) { + oci_bind_by_name($stmt, $bv_name, $inputarr[$k][0], $v[1]); } else { - $bv_name = ":".$k; + oci_bind_by_name($stmt, $bv_name, $inputarr[$k][0], $v[1], $v[2]); } - if (is_array($v)) { - // suggested by g.giunta@libero. - if (sizeof($v) == 2) { - oci_bind_by_name($stmt,$bv_name,$inputarr[$k][0],$v[1]); - } - else { - oci_bind_by_name($stmt,$bv_name,$inputarr[$k][0],$v[1],$v[2]); - } + } else { + $len = -1; + if ($v === ' ') { + $len = 1; + } + if (isset($bindarr)) { + // prepared sql, so no need to oci_bind_by_name again + $bindarr[$k] = $v; } else { - $len = -1; - if ($v === ' ') { - $len = 1; - } - if (isset($bindarr)) { // is prepared sql, so no need to oci_bind_by_name again - $bindarr[$k] = $v; - } else { // dynamic sql, so rebind every time - oci_bind_by_name($stmt,$bv_name,$inputarr[$k],$len); - } + // dynamic sql, so rebind every time + oci_bind_by_name($stmt, $bv_name, $inputarr[$k], $len); } } } @@ -975,16 +971,6 @@ function UpdateBlobFile($table,$column,$val,$where,$blobtype='BLOB') return $rez; } - /** - * Execute SQL - * - * @param string|array $sql SQL statement to execute, or possibly an array holding - * prepared statement ($sql[0] will hold sql text). - * @param array|false $inputarr holds the input data to bind to. - * Null elements will be set to null. - * - * @return ADORecordSet|false - */ function Execute($sql,$inputarr=false) { if ($this->fnExecute) { @@ -1151,10 +1137,11 @@ function ExecuteCursor($sql,$cursorName='rs',$params=false) } else $hasref = false; + /** @var ADORecordset_oci8 $rs */ $rs = $this->Execute($stmt); if ($rs) { if ($rs->databaseType == 'array') { - oci_free_cursor($stmt[4]); + oci_free_statement($stmt[4]); } elseif ($hasref) { $rs->_refcursor = $stmt[4]; @@ -1285,7 +1272,8 @@ function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false) } /** - * returns query ID if successful, otherwise false + * Execute a query. + * * this version supports: * * 1. $db->execute('select * from table'); @@ -1298,6 +1286,11 @@ function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false) * 4. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)'); * $db->bind($stmt,1); $db->bind($stmt,2); $db->bind($stmt,3); * $db->execute($stmt); + * + * @param string|array $sql Query to execute. + * @param array $inputarr An optional array of parameters. + * + * @return mixed|bool Query identifier or true if execution successful, false if failed. */ function _query($sql,$inputarr=false) { @@ -1586,6 +1579,9 @@ function qStr($s, $magic_quotes=false) if ($this->noNullStrings && strlen($s) == 0) { $s = ' '; } + else if (strlen($s) == 0) { + return "''"; + } if ($this->replaceQuote[0] == '\\'){ $s = str_replace('\\','\\\\',$s); } @@ -1604,6 +1600,9 @@ class ADORecordset_oci8 extends ADORecordSet { var $bind=false; var $_fieldobjs; + /** @var resource Cursor reference */ + var $_refcursor; + function __construct($queryID,$mode=false) { if ($mode === false) { diff --git a/app/Vendor/adodb5/drivers/adodb-oci8po.inc.php b/app/Vendor/adodb5/drivers/adodb-oci8po.inc.php index aaf4bb5fa..71c203b62 100644 --- a/app/Vendor/adodb5/drivers/adodb-oci8po.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-oci8po.inc.php @@ -70,7 +70,16 @@ function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0 return ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); } - // emulate handling of parameters ? ?, replacing with :bind0 :bind1 + /** + * Execute a query. + * + * Emulate handling of parameters ? ?, replacing with :bind0 :bind1 + * + * @param string|array $sql Query to execute. + * @param array $inputarr An optional array of parameters. + * + * @return mixed|bool Query identifier or true if execution successful, false if failed. + */ function _query($sql,$inputarr=false) { if (is_array($inputarr)) { diff --git a/app/Vendor/adodb5/drivers/adodb-odbc.inc.php b/app/Vendor/adodb5/drivers/adodb-odbc.inc.php index a9705e2d8..56db8b0e1 100644 --- a/app/Vendor/adodb5/drivers/adodb-odbc.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-odbc.inc.php @@ -26,7 +26,7 @@ /* * These constants are used to set define MetaColumns() method's behavior. - * - METACOLUMNS_RETURNS_ACTUAL makes the driver return the actual type, + * - METACOLUMNS_RETURNS_ACTUAL makes the driver return the actual type, * like all other drivers do (default) * - METACOLUMNS_RETURNS_META is provided for legacy compatibility (makes * driver behave as it did prior to v5.21) @@ -35,7 +35,7 @@ */ DEFINE('METACOLUMNS_RETURNS_ACTUAL', 0); DEFINE('METACOLUMNS_RETURNS_META', 1); - + /*-------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------*/ @@ -57,7 +57,7 @@ class ADODB_odbc extends ADOConnection { var $_autocommit = true; var $_lastAffectedRows = 0; var $uCaseTables = true; // for meta* functions, uppercase table names - + /* * Tells the metaColumns feature whether to return actual or meta type */ @@ -81,7 +81,9 @@ function _connect($argDSN, $argUsername, $argPassword, $argDatabasename) if ($this->curmode === false) $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword); else $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword,$this->curmode); $this->_errorMsg = $this->getChangedErrorMsg($last_php_error); - if (isset($this->connectStmt)) $this->Execute($this->connectStmt); + if ($this->connectStmt) { + $this->Execute($this->connectStmt); + } return $this->_connectionID != false; } @@ -102,7 +104,9 @@ function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename) $this->_errorMsg = $this->getChangedErrorMsg($last_php_error); if ($this->_connectionID && $this->autoRollback) @odbc_rollback($this->_connectionID); - if (isset($this->connectStmt)) $this->Execute($this->connectStmt); + if ($this->connectStmt) { + $this->Execute($this->connectStmt); + } return $this->_connectionID != false; } @@ -469,7 +473,7 @@ function MetaColumns($table, $normalize=true) $fld = new ADOFieldObject(); $fld->name = $rs->fields[3]; if ($this->metaColumnsReturnType == METACOLUMNS_RETURNS_META) - /* + /* * This is the broken, original value */ $fld->type = $this->ODBCTypes($rs->fields[4]); @@ -514,7 +518,6 @@ function Prepare($sql) return array($sql,$stmt,false); } - /* returns queryID or false */ function _query($sql,$inputarr=false) { $last_php_error = $this->resetLastError(); diff --git a/app/Vendor/adodb5/drivers/adodb-odbc_mssql.inc.php b/app/Vendor/adodb5/drivers/adodb-odbc_mssql.inc.php index 9f53d3d7c..1f8b98d26 100644 --- a/app/Vendor/adodb5/drivers/adodb-odbc_mssql.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-odbc_mssql.inc.php @@ -49,8 +49,12 @@ class ADODB_odbc_mssql extends ADODB_odbc { var $ansiOuter = true; // for mssql7 or later var $identitySQL = 'select SCOPE_IDENTITY()'; // 'select SCOPE_IDENTITY'; # for mssql 2000 var $hasInsertID = true; - var $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL OFF'; # When SET CONCAT_NULL_YIELDS_NULL is ON, - # concatenating a null value with a string yields a NULL result + /** + * When SET CONCAT_NULL_YIELDS_NULL is ON, concatenating a null value with + * a string yields a NULL result. + * @var string SQL statement executed after successful connection. + */ + public $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL OFF'; # // crashes php... function ServerInfo() diff --git a/app/Vendor/adodb5/drivers/adodb-odbc_mssql2012.inc.php b/app/Vendor/adodb5/drivers/adodb-odbc_mssql2012.inc.php index 79fa32516..86f7f8c31 100644 --- a/app/Vendor/adodb5/drivers/adodb-odbc_mssql2012.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-odbc_mssql2012.inc.php @@ -26,10 +26,11 @@ class ADODB_odbc_mssql2012 extends ADODB_odbc_mssql { - /* - * Makes behavior similar to prior versions of SQL Server - */ - var $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL ON'; + /** + * Makes behavior similar to prior versions of SQL Server. + * @var string SQL statement executed after successful connection. + */ + public $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL ON'; } class ADORecordSet_odbc_mssql2012 extends ADORecordSet_odbc_mssql diff --git a/app/Vendor/adodb5/drivers/adodb-odbtp.inc.php b/app/Vendor/adodb5/drivers/adodb-odbtp.inc.php index 41bd0873b..e3f814810 100644 --- a/app/Vendor/adodb5/drivers/adodb-odbtp.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-odbtp.inc.php @@ -46,6 +46,15 @@ class ADODB_odbtp extends ADOConnection{ var $_canPrepareSP = false; var $_dontPoolDBC = true; + /** @var string DBMS name. */ + var $odbc_name; + + /** @var bool */ + var $_canSelectDb = false; + + /** @var mixed */ + var $_lastAffectedRows; + function ServerInfo() { return array('description' => @odbtp_get_attr( ODB_ATTR_DBMSNAME, $this->_connectionID), @@ -304,7 +313,6 @@ function SelectDB($dbName) return false; } $this->database = $dbName; - $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions return true; } diff --git a/app/Vendor/adodb5/drivers/adodb-oracle.inc.php b/app/Vendor/adodb5/drivers/adodb-oracle.inc.php index 1a2735b14..dc0462fe2 100644 --- a/app/Vendor/adodb5/drivers/adodb-oracle.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-oracle.inc.php @@ -181,7 +181,6 @@ function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename) } - // returns query ID if successful, otherwise false function _query($sql,$inputarr=false) { // Reset error messages before executing diff --git a/app/Vendor/adodb5/drivers/adodb-pdo.inc.php b/app/Vendor/adodb5/drivers/adodb-pdo.inc.php index df7b0e6b2..d3ce12d08 100644 --- a/app/Vendor/adodb5/drivers/adodb-pdo.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-pdo.inc.php @@ -83,8 +83,16 @@ class ADODB_pdo extends ADOConnection { var $_errorno = false; var $_stmt = false; + + /** @var ADODB_pdo_base */ var $_driver; + /** @var PDO */ + var $_connectionID; + + /** @var PDOStatement */ + var $_queryID; + /* * Describe parameters passed directly to the PDO driver * @@ -234,7 +242,7 @@ function Concat() return call_user_func_array(array($this->_driver, 'Concat'), $args); } - return call_user_func_array('parent::Concat', $args); + return call_user_func_array(parent::class . '::Concat', $args); } /** @@ -254,7 +262,7 @@ public function param($name,$type='C') { } // No driver specific method defined, use mysql format '?' - return call_user_func_array('parent::param', $args); + return call_user_func_array(parent::class . '::param', $args); } // returns true or false @@ -570,7 +578,6 @@ function GenID($seqname='adodbseq',$startID=1) } - /* returns queryID or false */ function _query($sql,$inputarr=false) { $ok = false; @@ -661,6 +668,9 @@ function qStr($s, $magic_quotes = false) } +/** + * Base class for Database-specific PDO drivers. + */ class ADODB_pdo_base extends ADODB_pdo { var $sysDate = "'?'"; @@ -778,7 +788,9 @@ class ADORecordSet_pdo extends ADORecordSet { var $bind = false; var $databaseType = "pdo"; var $dataProvider = "pdo"; - var $adodbFetchMode = false; + + /** @var PDOStatement */ + var $_queryID; function __construct($id,$mode=false) { @@ -920,4 +932,7 @@ function Fields($colname) } -class ADORecordSet_array_pdo extends ADORecordSet_array {} +class ADORecordSet_array_pdo extends ADORecordSet_array { + /** @var PDOStatement */ + var $_queryID; +} diff --git a/app/Vendor/adodb5/drivers/adodb-pdo_firebird.inc.php b/app/Vendor/adodb5/drivers/adodb-pdo_firebird.inc.php index 0ee5e02b6..f8847c3cc 100644 --- a/app/Vendor/adodb5/drivers/adodb-pdo_firebird.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-pdo_firebird.inc.php @@ -32,14 +32,6 @@ class ADODB_pdo_firebird extends ADODB_pdo var $arrayClass = 'ADORecordSet_array_pdo_firebird'; - function _init($parentDriver) - { - $this->pdoDriver = $parentDriver; - //$parentDriver->_bindInputArray = true; - //$parentDriver->hasTransactions = false; // // should be set to false because of PDO SQLite driver not supporting changing autocommit mode - //$parentDriver->hasInsertID = true; - } - /** * Gets the version iformation from the server * @@ -243,12 +235,6 @@ public function dropSequence($seqname = 'adodbseq') return $this->Execute("DROP SEQUENCE $seqname"); } - - public function _affectedrows() - { - return fbird_affected_rows($this->_transactionID ? $this->_transactionID : $this->_connectionID); - } - public function genId($seqname = 'adodbseq', $startID = 1) { $getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE"); diff --git a/app/Vendor/adodb5/drivers/adodb-pdo_mysql.inc.php b/app/Vendor/adodb5/drivers/adodb-pdo_mysql.inc.php index c8812453f..a00c8595b 100644 --- a/app/Vendor/adodb5/drivers/adodb-pdo_mysql.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-pdo_mysql.inc.php @@ -57,7 +57,7 @@ function OffsetDate($dayFraction, $date=false) return $date . ' + INTERVAL ' . $fraction . ' SECOND'; // return "from_unixtime(unix_timestamp($date)+$fraction)"; } - + /** * Get a list of indexes on the specified table. * @@ -266,7 +266,6 @@ function MetaColumns($table, $normalize=true) function SelectDB($dbName) { $this->database = $dbName; - $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions $try = $this->Execute('use ' . $dbName); return ($try !== false); } @@ -275,7 +274,7 @@ function SelectDB($dbName) function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs=0) { $nrows = (int) $nrows; - $offset = (int) $offset; + $offset = (int) $offset; $offsetStr =($offset>=0) ? "$offset," : ''; // jason judge, see PHPLens Issue No: 9220 if ($nrows < 0) { diff --git a/app/Vendor/adodb5/drivers/adodb-pdo_sqlsrv.inc.php b/app/Vendor/adodb5/drivers/adodb-pdo_sqlsrv.inc.php index ed73f3a24..de5fbba02 100644 --- a/app/Vendor/adodb5/drivers/adodb-pdo_sqlsrv.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-pdo_sqlsrv.inc.php @@ -36,10 +36,15 @@ function _init(ADODB_pdo $parentDriver) $parentDriver->fmtDate = "'Y-m-d'"; } - function BeginTrans() + function setTransactionMode( $transaction_mode ) { - $returnval = parent::BeginTrans(); - return $returnval; + $this->_transmode = $transaction_mode; + if (empty($transaction_mode)) { + $this->_connectionID->query('SET TRANSACTION ISOLATION LEVEL READ COMMITTED'); + return; + } + if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode; + $this->_connectionID->query("SET TRANSACTION ".$transaction_mode); } function MetaColumns($table, $normalize = true) @@ -54,8 +59,7 @@ function MetaTables($ttype = false, $showSchema = false, $mask = false) function SelectLimit($sql, $nrows = -1, $offset = -1, $inputarr = false, $secs2cache = 0) { - $ret = ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); - return $ret; + return ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); } function ServerInfo() @@ -167,15 +171,5 @@ public function fetchField($fieldOffset = 0) return $o; } - - function SetTransactionMode( $transaction_mode ) - { - $this->_transmode = $transaction_mode; - if (empty($transaction_mode)) { - $this->_connectionID->query('SET TRANSACTION ISOLATION LEVEL READ COMMITTED'); - return; - } - if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode; - $this->_connectionID->query("SET TRANSACTION ".$transaction_mode); - } + } diff --git a/app/Vendor/adodb5/drivers/adodb-postgres64.inc.php b/app/Vendor/adodb5/drivers/adodb-postgres64.inc.php index 1d26c0f58..9bf9e713c 100644 --- a/app/Vendor/adodb5/drivers/adodb-postgres64.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-postgres64.inc.php @@ -258,7 +258,9 @@ function qStr($s, $magic_quotes=false) if ($this->_connectionID) { return "'" . pg_escape_string($this->_connectionID, $s) . "'"; } else { - return "'" . pg_escape_string($s) . "'"; + // Fall back to emulated escaping when there is no database connection. + // Avoids errors when using setSessionVariables() in the load balancer. + return parent::qStr( $s ); } } @@ -659,14 +661,16 @@ function MetaIndexes ($table, $primary = FALSE, $owner = false) return $false; } + // Get column names indexed by attnum so we can lookup the index key $col_names = $this->MetaColumnNames($table,true,true); - // 3rd param is use attnum, - // see https://sourceforge.net/p/adodb/bugs/45/ $indexes = array(); while ($row = $rs->FetchRow()) { $columns = array(); foreach (explode(' ', $row[2]) as $col) { - $columns[] = $col_names[$col]; + // When index attribute (pg_index.indkey) is an expression, $col == 0 + // @see https://www.postgresql.org/docs/current/catalog-pg-index.html + // so there is no matching column name - set it to null (see #940). + $columns[] = $col_names[$col] ?? null; } $indexes[$row[0]] = array( @@ -755,8 +759,7 @@ function _connect($str, $user='', $pwd='', $db='', $ctype=0) # PHP does not handle 'hex' properly ('x74657374' is returned as 't657374') # https://bugs.php.net/bug.php?id=59831 states this is in fact not a bug, # so we manually set bytea_output - if (!empty($this->connection->noBlobs) - && version_compare($info['version'], '9.0', '>=') + if (version_compare($info['version'], '9.0', '>=') && version_compare($info['client'], '9.2', '<') ) { $this->Execute('set bytea_output=escape'); @@ -781,7 +784,6 @@ function _pconnect($str,$user='',$pwd='',$db='') } - // returns queryID or false function _query($sql,$inputarr=false) { $this->_pnum = 0; @@ -936,7 +938,6 @@ class ADORecordSet_postgres64 extends ADORecordSet{ var $_blobArr; var $databaseType = "postgres64"; var $canSeek = true; - var $adodbFetchMode; function __construct($queryID, $mode=false) { diff --git a/app/Vendor/adodb5/drivers/adodb-postgres8.inc.php b/app/Vendor/adodb5/drivers/adodb-postgres8.inc.php index 37c2aae14..58df47c63 100644 --- a/app/Vendor/adodb5/drivers/adodb-postgres8.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-postgres8.inc.php @@ -45,11 +45,23 @@ class ADODB_postgres8 extends ADODB_postgres7 * @return int last inserted ID for given table/column, or the most recently * returned one if $table or $column are empty */ - protected function _insertID($table = '', $column = '') + protected function _insertID( $table = '', $column = '' ) { - return empty($table) || empty($column) - ? $this->GetOne("SELECT lastval()") - : $this->GetOne("SELECT currval(pg_get_serial_sequence('$table', '$column'))"); + global $ADODB_GETONE_EOF; + + $sql = empty($table) || empty($column) + ? 'SELECT lastval()' + : "SELECT currval(pg_get_serial_sequence('$table', '$column'))"; + + // Squelch "ERROR: lastval is not yet defined in this session" (see #978) + $result = @$this->GetOne($sql); + if ($result === false || $result == $ADODB_GETONE_EOF) { + if ($this->debug) { + ADOConnection::outp(__FUNCTION__ . "() failed : " . $this->errorMsg()); + } + return false; + } + return $result; } } diff --git a/app/Vendor/adodb5/drivers/adodb-sqlanywhere.inc.php b/app/Vendor/adodb5/drivers/adodb-sqlanywhere.inc.php index 88897af92..8d909fdea 100644 --- a/app/Vendor/adodb5/drivers/adodb-sqlanywhere.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-sqlanywhere.inc.php @@ -116,7 +116,7 @@ function load_blobvar_from_var($blobVarName, &$varName) { $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)'); $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1'); */ - function UpdateBlob($table,$column,&$val,$where,$blobtype='BLOB') + function updateBlob($table, $column, $val, $where, $blobtype = 'BLOB') { $blobVarName = 'hold_blob'; $this->create_blobvar($blobVarName); diff --git a/app/Vendor/adodb5/drivers/adodb-sqlite.inc.php b/app/Vendor/adodb5/drivers/adodb-sqlite.inc.php index 0711f1dde..d41829c04 100644 --- a/app/Vendor/adodb5/drivers/adodb-sqlite.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-sqlite.inc.php @@ -211,7 +211,6 @@ function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename) return true; } - // returns query ID if successful, otherwise false function _query($sql,$inputarr=false) { $rez = sqlite_query($sql,$this->_connectionID); diff --git a/app/Vendor/adodb5/drivers/adodb-sqlite3.inc.php b/app/Vendor/adodb5/drivers/adodb-sqlite3.inc.php index 318171a8c..7623a3c88 100644 --- a/app/Vendor/adodb5/drivers/adodb-sqlite3.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-sqlite3.inc.php @@ -331,7 +331,6 @@ function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename) return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename); } - // returns query ID if successful, otherwise false function _query($sql,$inputarr=false) { $rez = $this->_connectionID->query($sql); diff --git a/app/Vendor/adodb5/drivers/adodb-sybase.inc.php b/app/Vendor/adodb5/drivers/adodb-sybase.inc.php index b8db07479..79fb82e8b 100644 --- a/app/Vendor/adodb5/drivers/adodb-sybase.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-sybase.inc.php @@ -95,7 +95,9 @@ function RollbackTrans() // http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4 function RowLock($tables,$where,$col='top 1 null as ignore') { - if (!$this->_hastrans) $this->BeginTrans(); + if (!$this->hasTransactions) { + $this->BeginTrans(); + } $tables = str_replace(',',' HOLDLOCK,',$tables); return $this->GetOne("select $col from $tables HOLDLOCK where $where"); @@ -104,7 +106,6 @@ function RowLock($tables,$where,$col='top 1 null as ignore') function SelectDB($dbName) { $this->database = $dbName; - $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions if ($this->_connectionID) { return @sybase_select_db($dbName); } @@ -169,7 +170,6 @@ function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename) return true; } - // returns query ID if successful, otherwise false function _query($sql,$inputarr=false) { global $ADODB_COUNTRECS; diff --git a/app/Vendor/adodb5/drivers/adodb-text.inc.php b/app/Vendor/adodb5/drivers/adodb-text.inc.php index 77ad06a0b..36a1a0d4d 100644 --- a/app/Vendor/adodb5/drivers/adodb-text.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-text.inc.php @@ -129,14 +129,21 @@ function Connect(&$array, $types = false, $colnames = false) return true; } - - - // returns queryID or false - // We presume that the select statement is on the same table (what else?), - // with the only difference being the order by. - //You can filter by using $eval and each clause is stored in $arr .eg. $arr[1] == 'name' - // also supports SELECT [DISTINCT] COL FROM ... -- only 1 col supported - function _query($sql,$input_arr,$eval=false) + /** + * Execute a query. + * + * We presume that the select statement is on the same table (what else?), + * with the only difference being the order by. + * You can filter by using $eval and each clause is stored in $arr e.g. $arr[1] == 'name' + * also supports SELECT [DISTINCT] COL FROM ... -- only 1 col supported + * + * @param string|array $sql Query to execute. + * @param array $inputarr An optional array of parameters. + * @param string $eval Optional eval string + * + * @return mixed|bool Query identifier or true if execution successful, false if failed. + */ + function _query($sql, $inputarr=false, $eval=false) { if ($this->_origarray === false) return false; diff --git a/app/Vendor/adodb5/perf/perf-oci8.inc.php b/app/Vendor/adodb5/perf/perf-oci8.inc.php index c11b261fd..345d8929f 100644 --- a/app/Vendor/adodb5/perf/perf-oci8.inc.php +++ b/app/Vendor/adodb5/perf/perf-oci8.inc.php @@ -23,7 +23,7 @@ if (!defined('ADODB_DIR')) die(); -class perf_oci8 extends ADODB_perf{ +class perf_oci8 extends adodb_perf{ var $noShowIxora = 15; // if the sql for suspicious sql is taking too long, then disable ixora diff --git a/app/Vendor/adodb5/session/adodb-session2.php b/app/Vendor/adodb5/session/adodb-session2.php index bf64b4166..19793960f 100644 --- a/app/Vendor/adodb5/session/adodb-session2.php +++ b/app/Vendor/adodb5/session/adodb-session2.php @@ -28,15 +28,14 @@ define('ADODB_SESSION', dirname(__FILE__)); define('ADODB_SESSION2', ADODB_SESSION); -/* - Unserialize session data manually. See PHPLens Issue No: 9821 - - From Kerr Schere, to unserialize session data stored via ADOdb. - 1. Pull the session data from the db and loop through it. - 2. Inside the loop, you will need to urldecode the data column. - 3. After urldecode, run the serialized string through this function: - -*/ +/** + * Unserialize session data manually. See PHPLens Issue No: 9821 + * + * From Kerr Schere, to unserialize session data stored via ADOdb. + * 1. Pull the session data from the db and loop through it. + * 2. Inside the loop, you will need to urldecode the data column. + * 3. After urldecode, run the serialized string through this function: + */ function adodb_unserialize( $serialized_string ) { $variables = array( ); @@ -47,10 +46,13 @@ function adodb_unserialize( $serialized_string ) return( $variables ); } -/* - Thanks Joe Li. See PHPLens Issue No: 11487&x=1 - Since adodb 4.61. -*/ +/** + * Regenerate session id + * + * Thanks Joe Li. See PHPLens Issue No: 11487&x=1 + * + * @since 4.61 + */ function adodb_session_regenerate_id() { $conn = ADODB_Session::_conn(); @@ -79,45 +81,52 @@ function adodb_session_regenerate_id() return true; } -/* - Generate database table for session data - @see PHPLens Issue No: 12280 - @return 0 if failure, 1 if errors, 2 if successful. - @author Markus Staab http://www.public-4u.de -*/ +/** + * Generate database table for session data. + * @see PHPLens Issue No: 12280 + * + * @return int 0 if failure, 1 if errors, 2 if successful. + * + * @author Markus Staab http://www.public-4u.de + */ function adodb_session_create_table($schemaFile=null,$conn = null) { - // set default values - if ($schemaFile===null) $schemaFile = ADODB_SESSION . '/session_schema2.xml'; - if ($conn===null) $conn = ADODB_Session::_conn(); + // set default values + if ($schemaFile===null) $schemaFile = ADODB_SESSION . '/session_schema2.xml'; + if ($conn===null) $conn = ADODB_Session::_conn(); if (!$conn) return 0; - $schema = new adoSchema($conn); - $schema->ParseSchema($schemaFile); - return $schema->ExecuteSchema(); + $schema = new adoSchema($conn); + $schema->ParseSchema($schemaFile); + return $schema->ExecuteSchema(); } -/*! - \static -*/ +/** + * ADOdb Session v2 class. + */ class ADODB_Session { + + /** + * Session Connection's Database provider. + * + * Populated when opening the database connection. + * @see ADODB_Session::open()}. + * + * @var string + */ + protected static $provider; + ///////////////////// // getter/setter methods ///////////////////// - /* - - function Lock($lock=null) - { - static $_lock = false; - - if (!is_null($lock)) $_lock = $lock; - return $lock; - } - */ - /*! - */ + /** + * Get/Set Database driver. + * + * @param string $driver + * @return string + */ static function driver($driver = null) { static $_driver = 'mysqli'; @@ -136,8 +145,12 @@ static function driver($driver = null) return $_driver; } - /*! - */ + /** + * Get/Set Database hostname. + * + * @param string $host + * @return string + */ static function host($host = null) { static $_host = 'localhost'; static $set = false; @@ -155,8 +168,12 @@ static function host($host = null) { return $_host; } - /*! - */ + /** + * Get/Set Database connection user. + * + * @param string $user + * @return string + */ static function user($user = null) { static $_user = 'root'; @@ -175,8 +192,12 @@ static function user($user = null) return $_user; } - /*! - */ + /** + * Get/Set Database connection password. + * + * @param null $password + * @return string + */ static function password($password = null) { static $_password = ''; @@ -195,8 +216,12 @@ static function password($password = null) return $_password; } - /*! - */ + /** + * Get/Set Database name. + * + * @param null $database + * @return string + */ static function database($database = null) { static $_database = ''; @@ -214,8 +239,12 @@ static function database($database = null) return $_database; } - /*! - */ + /** + * Get/Set Connection's persistence mode. + * + * @param $persist + * @return string|true + */ static function persist($persist = null) { static $_persist = true; @@ -227,8 +256,12 @@ static function persist($persist = null) return $_persist; } - /*! - */ + /** + * Get/Set Connection's lifetime. + * + * @param int $lifetime + * @return int + */ static function lifetime($lifetime = null) { static $_lifetime; @@ -255,8 +288,12 @@ static function lifetime($lifetime = null) return $_lifetime; } - /*! - */ + /** + * Get/Set Connection's debug mode. + * + * @param bool $debug + * @return bool + */ static function debug($debug = null) { static $_debug = false; @@ -264,11 +301,6 @@ static function debug($debug = null) if (!is_null($debug)) { $_debug = (bool) $debug; - - $conn = ADODB_Session::_conn(); - if ($conn) { - #$conn->debug = $_debug; - } $set = true; } elseif (!$set) { // backwards compatibility @@ -280,8 +312,12 @@ static function debug($debug = null) return $_debug; } - /*! - */ + /** + * Get/Set garbage collection function. + * + * @param callable $expire_notify Function name + * @return callable|false + */ static function expireNotify($expire_notify = null) { static $_expire_notify; @@ -300,8 +336,12 @@ static function expireNotify($expire_notify = null) return $_expire_notify; } - /*! - */ + /** + * Get/Set Sessions table name. + * + * @param string $table Session table name (defaults to 'sessions2') + * @return string + */ static function table($table = null) { static $_table = 'sessions2'; @@ -320,8 +360,15 @@ static function table($table = null) return $_table; } - /*! - */ + /** + * Get/Set table optimization mode. + * + * If true, with MySQL and PostgreSQL databases, the Sessions table will + * be optimized when garbage collection is performed. + * + * @param bool $optimize + * @return bool + */ static function optimize($optimize = null) { static $_optimize = false; @@ -340,16 +387,21 @@ static function optimize($optimize = null) return $_optimize; } - /*! - */ + /** + * No longer used, kept for backwards-compatibility only. + * + * @param int $sync_seconds + * @return int + * + * @deprecated + */ static function syncSeconds($sync_seconds = null) { - //echo ("

WARNING: ADODB_SESSION::syncSeconds is longer used, please remove this function for your code

"); - return 0; } - /*! - */ + /** + * Get/Set if CLOBs are available to store session data. + */ static function clob($clob = null) { static $_clob = false; static $set = false; @@ -367,15 +419,24 @@ static function clob($clob = null) { return $_clob; } - /*! - */ + /** + * No longer used, kept for backwards-compatibility only. + * + * @param string $data_field_name + * @return string + * + * @deprecated + */ static function dataFieldName($data_field_name = null) { - //echo ("

WARNING: ADODB_SESSION::dataFieldName() is longer used, please remove this function for your code

"); return ''; } - /*! - */ + /** + * Get/Set session data filter. + * + * @param array $filter + * @return array + */ static function filter($filter = null) { static $_filter = array(); @@ -389,8 +450,12 @@ static function filter($filter = null) { return $_filter; } - /*! - */ + /** + * Get/Set the encryption key if encrypted sessions are in use. + * + * @param string $encryption_key + * @return string + */ static function encryptionKey($encryption_key = null) { static $_encryption_key = 'CRYPTED ADODB SESSIONS ROCK!'; @@ -405,14 +470,19 @@ static function encryptionKey($encryption_key = null) { // private methods ///////////////////// - /*! - */ + /** + * Returns the Session's Database Connection. + * + * @return ADOConnection|false + */ static function _conn($conn=null) { return isset($GLOBALS['ADODB_SESS_CONN']) ? $GLOBALS['ADODB_SESS_CONN'] : false; } - /*! - */ + /** + * @param $crc + * @return false|mixed + */ static function _crc($crc = null) { static $_crc = false; @@ -423,8 +493,9 @@ static function _crc($crc = null) { return $_crc; } - /*! - */ + /** + * Initialize session handler. + */ static function _init() { session_set_save_handler( array('ADODB_Session', 'open'), @@ -437,16 +508,19 @@ static function _init() { } - /*! - */ + /** + * Create the encryption key for crypted sessions. + * + * Crypt the used key, ADODB_Session::encryptionKey() as key and + * session_id() as salt. + */ static function _sessionKey() { - // use this function to create the encryption key for crypted sessions - // crypt the used key, ADODB_Session::encryptionKey() as key and session_id() as salt return crypt(ADODB_Session::encryptionKey(), session_id()); } - /*! - */ + /** + * Dump recordset. + */ static function _dumprs(&$rs) { $conn = ADODB_Session::_conn(); $debug = ADODB_Session::debug(); @@ -476,10 +550,39 @@ static function _dumprs(&$rs) { $rs->MoveFirst(); } + /** + * Check if Session Connection's DB type is MySQL. + * + * @return bool + */ + static protected function isConnectionMysql() { + return self::$provider == 'mysql'; + } + + /** + * Check if Session Connection's DB type is PostgreSQL. + * + * @return bool + */ + static protected function isConnectionPostgres() { + return self::$provider == 'postgres'; + } + ///////////////////// // public methods ///////////////////// + /** + * Establishes a connection to the database for session management. + * + * @param string $host + * @param string $driver + * @param string $user + * @param string $password + * @param string $database + * @param array $options + * @return void + */ static function config($driver, $host, $user, $password, $database=false,$options=false) { ADODB_Session::driver($driver); @@ -495,11 +598,17 @@ static function config($driver, $host, $user, $password, $database=false,$option if (isset($options['debug'])) ADODB_Session::debug($options['debug']); } - /*! - Create the connection to the database. - - If $conn already exists, reuse that connection - */ + /** + * Create the connection to the database. + * + * If $conn already exists, reuse that connection. + * + * @param string $save_path + * @param string $session_name + * @param bool $persist + * + * @return bool + */ static function open($save_path, $session_name, $persist = null) { $conn = ADODB_Session::_conn(); @@ -521,10 +630,6 @@ static function open($save_path, $session_name, $persist = null) $persist = ADODB_Session::persist(); } -# these can all be defaulted to in php.ini -# assert('$database'); -# assert('$driver'); -# assert('$host'); if (strpos($driver, 'pdo_') === 0){ $conn = ADONewConnection('pdo'); $driver = str_replace('pdo_', '', $driver); @@ -562,8 +667,15 @@ static function open($save_path, $session_name, $persist = null) } } + if ($ok) { + $GLOBALS['ADODB_SESS_CONN'] = $conn; - if ($ok) $GLOBALS['ADODB_SESS_CONN'] = $conn; + // Initialize Session data provider + self::$provider = $conn->dataProvider; + if (self::$provider == 'pdo') { + self::$provider = $conn->dsnType == 'pgsql' ? 'postgres' : $conn->dsnType; + } + } else ADOConnection::outp('

Session: connection failed

', false); @@ -571,9 +683,9 @@ static function open($save_path, $session_name, $persist = null) return $ok; } - /*! - Close the connection - */ + /** + * Close the connection + */ static function close() { /* @@ -583,9 +695,12 @@ static function close() return true; } - /* - Slurp in the session variables and return the serialized string - */ + /** + * Slurp in the session variables and return the serialized string. + * + * @param string $key + * @return string + */ static function read($key) { $conn = ADODB_Session::_conn(); @@ -596,9 +711,7 @@ static function read($key) return ''; } - //assert('$table'); - - $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : ''; + $binary = ADODB_Session::isConnectionMysql() ? '/*! BINARY */' : ''; global $ADODB_SESSION_SELECT_FIELDS; if (!isset($ADODB_SESSION_SELECT_FIELDS)) $ADODB_SESSION_SELECT_FIELDS = 'sessdata'; @@ -635,16 +748,22 @@ static function read($key) return ''; } - /*! - Write the serialized data to a database. - - If the data has not been modified since the last read(), we do not write. - */ + /** + * Write the serialized data to a database. + * + * If the data has not been modified since the last read(), we do not write. + * + * @param string $key + * @param string $oval + * + * @return bool + */ static function write($key, $oval) { - global $ADODB_SESSION_READONLY; - - if (!empty($ADODB_SESSION_READONLY)) return; + global $ADODB_SESSION_READONLY; + if (!empty($ADODB_SESSION_READONLY)) { + return false; + } $clob = ADODB_Session::clob(); $conn = ADODB_Session::_conn(); @@ -662,11 +781,9 @@ static function write($key, $oval) if ($debug) $conn->debug = 1; $sysTimeStamp = $conn->sysTimeStamp; - //assert('$table'); - $expiry = $conn->OffsetDate($lifetime/(24*3600),$sysTimeStamp); - $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : ''; + $binary = ADODB_Session::isConnectionMysql() ? '/*! BINARY */' : ''; // crc32 optimization since adodb 2.1 // now we only update expiry date, thx to sebastian thom in adodb 2.32 @@ -684,8 +801,9 @@ static function write($key, $oval) } } - - $sql = "UPDATE $table SET expiry = $expiry ,expireref=".$conn->Param('0').", modified = $sysTimeStamp WHERE $binary sesskey = ".$conn->Param('1')." AND expiry >= $sysTimeStamp"; + $sql = "UPDATE $table SET expiry = $expiry, expireref=" . $conn->Param('0') + . ", modified = $sysTimeStamp WHERE sesskey = $binary " . $conn->Param('1') + . " AND expiry >= $sysTimeStamp"; $rs = $conn->Execute($sql,array($expirevar,$key)); return true; } @@ -705,7 +823,8 @@ static function write($key, $oval) } } - if (!$clob) { // no lobs, simply use replace() + if (!$clob) { + // no lobs, simply use replace() $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key)); if ($rs) $rs->Close(); @@ -717,7 +836,6 @@ static function write($key, $oval) VALUES ($expiry,".$conn->Param('0').", ". $conn->Param('1').", ".$conn->Param('2').", $sysTimeStamp, $sysTimeStamp)"; } - $rs = $conn->Execute($sql,array($val,$expireref,$key)); } else { @@ -737,14 +855,12 @@ static function write($key, $oval) VALUES ($expiry,$lob_value, ". $conn->Param('0').", ".$conn->Param('1').", $sysTimeStamp, $sysTimeStamp)"; } - $rs = $conn->Execute($sql,array($expireref,$key)); + $conn->Execute($sql,array($expireref,$key)); $qkey = $conn->qstr($key); - $rs2 = $conn->UpdateBlob($table, 'sessdata', $val, " sesskey=$qkey", strtoupper($clob)); + $conn->UpdateBlob($table, 'sessdata', $val, " sesskey=$qkey", strtoupper($clob)); if ($debug) echo "
",htmlspecialchars($oval), "
"; $rs = @$conn->CompleteTrans(); - - } if (!$rs) { @@ -768,8 +884,12 @@ static function write($key, $oval) return $rs ? true : false; } - /*! - */ + /** + * Destroy session. + * + * @param string $key + * @return bool + */ static function destroy($key) { $conn = ADODB_Session::_conn(); $table = ADODB_Session::table(); @@ -780,16 +900,15 @@ static function destroy($key) { } $debug = ADODB_Session::debug(); if ($debug) $conn->debug = 1; - //assert('$table'); $qkey = $conn->quote($key); - $binary = $conn->dataProvider === 'mysql' || $conn->dataProvider === 'pdo' ? '/*! BINARY */' : ''; + $binary = ADODB_Session::isConnectionMysql() ? '/*! BINARY */' : ''; if ($expire_notify) { reset($expire_notify); $fn = next($expire_notify); $savem = $conn->SetFetchMode(ADODB_FETCH_NUM); - $sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey"; + $sql = "SELECT expireref, sesskey FROM $table WHERE sesskey = $binary $qkey"; $rs = $conn->Execute($sql); ADODB_Session::_dumprs($rs); $conn->SetFetchMode($savem); @@ -799,24 +918,26 @@ static function destroy($key) { if (!$rs->EOF) { $ref = $rs->fields[0]; $key = $rs->fields[1]; - //assert('$ref'); - //assert('$key'); $fn($ref, $key); } $rs->Close(); } - $sql = "DELETE FROM $table WHERE $binary sesskey = $qkey"; + $sql = "DELETE FROM $table WHERE sesskey = $binary $qkey"; $rs = $conn->Execute($sql); if ($rs) { $rs->Close(); } - return $rs ? true : false; + return (bool)$rs; } - /*! - */ + /** + * Perform garbage collection. + * + * @param int $maxlifetime + * @return bool + */ static function gc($maxlifetime) { $conn = ADODB_Session::_conn(); @@ -829,8 +950,6 @@ static function gc($maxlifetime) return false; } - - $debug = ADODB_Session::debug(); if ($debug) { $conn->debug = 1; $COMMITNUM = 2; @@ -838,10 +957,8 @@ static function gc($maxlifetime) $COMMITNUM = 20; } - //assert('$table'); - $time = $conn->OffsetDate(-$maxlifetime/24/3600,$conn->sysTimeStamp); - $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : ''; + $binary = ADODB_Session::isConnectionMysql() ? '/*! BINARY */' : ''; if ($expire_notify) { reset($expire_notify); @@ -858,13 +975,12 @@ static function gc($maxlifetime) if ($rs) { $tr = $conn->hasTransactions; if ($tr) $conn->BeginTrans(); - $keys = array(); $ccnt = 0; while (!$rs->EOF) { $ref = $rs->fields[0]; $key = $rs->fields[1]; if ($fn) $fn($ref, $key); - $del = $conn->Execute("DELETE FROM $table WHERE sesskey=".$conn->Param('0'),array($key)); + $conn->Execute("DELETE FROM $table WHERE sesskey = $binary " . $conn->Param('0'), array($key)); $rs->MoveNext(); $ccnt += 1; if ($tr && $ccnt % $COMMITNUM == 0) { @@ -881,12 +997,9 @@ static function gc($maxlifetime) // suggested by Cameron, "GaM3R" if ($optimize) { - $driver = ADODB_Session::driver(); - - if (preg_match('/mysql/i', $driver)) { + if (ADODB_Session::isConnectionMysql()) { $sql = "OPTIMIZE TABLE $table"; - } - if (preg_match('/postgres/i', $driver)) { + } elseif (ADODB_Session::isConnectionPostgres()) { $sql = "VACUUM $table"; } if (!empty($sql)) { @@ -903,12 +1016,16 @@ static function gc($maxlifetime) if (empty($ADODB_SESSION_READONLY)) register_shutdown_function('session_write_close'); -// for backwards compatibility only +/** + * @deprecated for backwards compatibility only + */ function adodb_sess_open($save_path, $session_name, $persist = true) { return ADODB_Session::open($save_path, $session_name, $persist); } -// for backwards compatibility only +/** + * @deprecated for backwards compatibility only + */ function adodb_sess_gc($t) { return ADODB_Session::gc($t); diff --git a/app/Vendor/adodb5/tests/test.php b/app/Vendor/adodb5/tests/test.php index fb23980bb..08a2e301b 100644 --- a/app/Vendor/adodb5/tests/test.php +++ b/app/Vendor/adodb5/tests/test.php @@ -1719,7 +1719,7 @@ function adodb_test_err($dbms, $fn, $errno, $errmsg, $p1=false, $p2=false) CheckWS('firebird'); CheckWS('sybase'); - if (!ini_get('safe_mode')) CheckWS('informix'); + CheckWS('informix'); CheckWS('ado_mssql'); CheckWS('ado_access'); diff --git a/app/Vendor/adodb5/tohtml.inc.php b/app/Vendor/adodb5/tohtml.inc.php index b3c08e320..6e9a62863 100644 --- a/app/Vendor/adodb5/tohtml.inc.php +++ b/app/Vendor/adodb5/tohtml.inc.php @@ -113,7 +113,8 @@ function rs2html(&$rs,$ztabhtml=false,$zheaderarray=false,$htmlspecialchars=true else $v = round($v,$ADODB_ROUND); case 'I': - $vv = stripslashes((trim($v))); + $vv = $v ? stripslashes(trim($v)) : ''; + $vv = $vv ?: ' '; if (strlen($vv) == 0) $vv .= ' '; $s .= " ".$vv ."\n"; @@ -140,7 +141,10 @@ function mime_content_type ($file) { default: if ($v) { - $v = htmlspecialchars(stripslashes(trim($v))); + $v = trim($v); + if ($htmlspecialchars) { + $v = htmlspecialchars($v); + } } elseif ($v === null) { $v = '(NULL)'; } else { From b9429a1c9106afc0d800eeba6f872b7f2d1db760 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Sun, 17 Dec 2023 17:33:07 +0200 Subject: [PATCH 6/8] preg_match subject can not be null --- lib/Cake/Network/Email/CakeEmail.php | 2 +- lib/Cake/Network/Email/SmtpTransport.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/Email/CakeEmail.php b/lib/Cake/Network/Email/CakeEmail.php index c6c9ea88a..aeff46cda 100644 --- a/lib/Cake/Network/Email/CakeEmail.php +++ b/lib/Cake/Network/Email/CakeEmail.php @@ -1392,7 +1392,7 @@ protected function _wrap($message, $wrapLength = CakeEmail::LINE_LENGTH_MUST) { $formatted[] = $line; continue; } - if (!preg_match('/<[a-z]+.*>/i', $line)) { + if (!preg_match('/<[a-z]+.*>/i', $line ?? '')) { $formatted = array_merge( $formatted, explode("\n", wordwrap($line, $wrapLength, "\n", $cut)) diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php index a245c5fb4..1a57649e2 100644 --- a/lib/Cake/Network/Email/SmtpTransport.php +++ b/lib/Cake/Network/Email/SmtpTransport.php @@ -366,7 +366,7 @@ protected function _smtpSend($data, $checkCode = '250') { $this->_bufferResponseLines($responseLines); - if (preg_match('/^(' . $checkCode . ')(.)/', $response, $code)) { + if (preg_match('/^(' . $checkCode . ')(.)/', $response ?? '', $code)) { if ($code[2] === '-') { continue; } From 28395d78083b8b4c421cf9e4ebcedf8f98295de0 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Mon, 18 Dec 2023 21:13:08 +0200 Subject: [PATCH 7/8] fix adodb 8.1 errors --- app/Vendor/adodb5/adodb.inc.php | 10 +++++----- app/Vendor/adodb5/drivers/adodb-mssql.inc.php | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/Vendor/adodb5/adodb.inc.php b/app/Vendor/adodb5/adodb.inc.php index 5bb8b23a0..a2aa93cba 100644 --- a/app/Vendor/adodb5/adodb.inc.php +++ b/app/Vendor/adodb5/adodb.inc.php @@ -747,12 +747,12 @@ static function Version() { . '(?:(?:alpha|beta|rc)(?:\.\d+))' // or a preprod suffix and version number . '))?)(?:\s|$)'; // Whitespace or end of string - if (!preg_match("/$regex/", $ADODB_vers, $matches)) { + if (!preg_match("/$regex/", $ADODB_vers ?? '', $matches)) { // This should normally not happen... Return whatever is between the start // of the string and the first whitespace (or the end of the string). self::outp("Invalid version number: '$ADODB_vers'", 'Version'); $regex = '^[vV]?(.*?)(?:\s|$)'; - preg_match("/$regex/", $ADODB_vers, $matches); + preg_match("/$regex/", $ADODB_vers ?? '', $matches); } return $matches[1]; } @@ -827,7 +827,7 @@ function IsConnected() { * @return string */ function _findvers($str) { - if (preg_match('/([0-9]+\.([0-9\.])+)/',$str, $arr)) { + if (preg_match('/([0-9]+\.([0-9\.])+)/', $str ?? '', $arr)) { return $arr[1]; } else { return ''; @@ -3418,7 +3418,7 @@ static function UnixDate($v) { if (is_numeric($v) && strlen($v) !== 8) { return $v; } - if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", $v, $rr)) { + if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", $v ?? '', $rr)) { return false; } @@ -3446,7 +3446,7 @@ static function UnixTimeStamp($v) { if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", - ($v), $rr)) return false; + ($v ?? ''), $rr)) return false; if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1) { return 0; diff --git a/app/Vendor/adodb5/drivers/adodb-mssql.inc.php b/app/Vendor/adodb5/drivers/adodb-mssql.inc.php index c0b714ede..e3c3cb8cf 100644 --- a/app/Vendor/adodb5/drivers/adodb-mssql.inc.php +++ b/app/Vendor/adodb5/drivers/adodb-mssql.inc.php @@ -450,12 +450,13 @@ public function metaForeignKeys($table, $owner = '', $upper = false, $associativ $ADODB_FETCH_MODE = $save; - $arr = false; + $arr = []; foreach($constraints as $constr) { //print_r($constr); + $arr[$constr[0]][$constr[2]] = array(); $arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3]; } - if (!$arr) return false; + if (!empty($arr)) return false; $arr2 = false; From c93dbc7466855330737a7e5a725e3104fbccab68 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Mon, 18 Dec 2023 21:33:15 +0200 Subject: [PATCH 8/8] fix preg_match not allowing null --- lib/Cake/Model/Model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 860ad5bdf..2957da650 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -3181,7 +3181,7 @@ protected function _findCount($state, $query, $results = array()) { } if (!empty($query['fields']) && is_array($query['fields'])) { - if (!preg_match('/^count/i', current($query['fields']))) { + if (!preg_match('/^count/i', current($query['fields']) ?? '')) { unset($query['fields']); } }