diff --git a/.gitignore b/.gitignore
index d81178e11..49dc19fce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,23 @@
+# General
+.DS_Store
+._*
+_*
+*~
+*.sublime-project
+*.sublime-workspace
+.idea/
+.vscode/
+Thumbs.db
+nbproject/
+
+# Config
config.php
+
+# WEB-INF
+WEB-INF/cache/
WEB-INF/templates_c/*.*
WEB-INF/templates_c/import_*
WEB-INF/templates_c/tt*
WEB-INF/lib/tcpdf/
-nbproject/
upload/
-.vscode/
-Thumbs.db
-*.DS_Store
-*~
-.idea/
-api/
+api/
\ No newline at end of file
diff --git a/.htaccess b/.htaccess
index 3b6168c75..aaca1cefd 100644
--- a/.htaccess
+++ b/.htaccess
@@ -1,3 +1,4 @@
+Options -Indexes
AddDefaultCharset utf-8
# Restrict access to Time Tracker only from certain IPs.
diff --git a/2fa.php b/2fa.php
index a7e3dbb29..de38c9c90 100644
--- a/2fa.php
+++ b/2fa.php
@@ -18,9 +18,9 @@
$cl_auth_code = $request->getParameter('auth_code');
$form = new Form('twoFactorAuthForm');
-$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','value'=>$cl_login));
+$form->addInput(array('type'=>'text','maxlength'=>'80','name'=>'login','value'=>$cl_login));
$form->getElement('login')->setEnabled(false);
-$form->addInput(array('type'=>'password','maxlength'=>'50','name'=>'password','value'=>$cl_password));
+$form->addInput(array('type'=>'password','maxlength'=>'128','name'=>'password','value'=>$cl_password));
$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'auth_code','value'=>$cl_auth_code));
$form->addInput(array('type'=>'submit','name'=>'btn_login','value'=>$i18n->get('button.login')));
diff --git a/WEB-INF/.htaccess b/WEB-INF/.htaccess
new file mode 100644
index 000000000..8ab380ebe
--- /dev/null
+++ b/WEB-INF/.htaccess
@@ -0,0 +1,4 @@
+
+ order deny,allow
+ allow from all
+
\ No newline at end of file
diff --git a/WEB-INF/cache/keepme b/WEB-INF/cache/keepme
new file mode 100644
index 000000000..e69de29bb
diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist
index 6b6a68d84..3728a830b 100644
--- a/WEB-INF/config.php.dist
+++ b/WEB-INF/config.php.dist
@@ -68,6 +68,13 @@ define('WEEKEND_START_DAY', 6);
// define('PHP_SESSION_PATH', '/tmp/timetracker'); // Directory must exist and be writable.
+// SESSION_HANDLER
+// Set session storage.
+// 'file' : file stroage. Default value
+// 'db' : db stroage
+define('SESSION_HANDLER', 'file');
+
+
// LOGIN_COOKIE_NAME
//
// Cookie name for user login to remember it between browser sessions.
@@ -132,6 +139,26 @@ define('REPORT_FOOTER', true);
// ldap - authentication against an LDAP directory such as OpenLDAP or Windows Active Directory.
define('AUTH_MODULE', 'db');
+// Password hash algorithm
+// Possible values
+// - DEFAULT ; bcrypt algorithm
+// - BCRYPT : crypt blowfish algorithm
+// - ARGON2I : Argon2i hashing algorithm (only available if PHP has been compiled with Argon2 support)
+// - ARGON2ID : Argon2id hashing algorithm (only available if PHP has been compiled with Argon2 support)
+define('AUTH_DB_HASH_ALGORITHM', 'BCRYPT');
+
+// Password hash options
+//
+define('AUTH_DB_HASH_ALGORITHM_OPTIONS', array('cost' => 10));
+
+// Login minlength
+//
+//define('AUTH_DB_LOGIN_MINLENGTH', 5);
+
+// Password minlength
+//
+//define('AUTH_DB_PWD_MINLENGTH', 12);
+
// LDAP authentication examples.
// Go to https://www.anuko.com/time-tracker/install-guide/ldap-auth/index.htm for detailed configuration instructions.
diff --git a/WEB-INF/configs/keepme b/WEB-INF/configs/keepme
new file mode 100644
index 000000000..e69de29bb
diff --git a/WEB-INF/lib/Auth.class.php b/WEB-INF/lib/Auth.class.php
index 783721090..1b7374956 100644
--- a/WEB-INF/lib/Auth.class.php
+++ b/WEB-INF/lib/Auth.class.php
@@ -31,16 +31,18 @@ class Auth {
// isAuthenticated - checks authentication status for user.
function isAuthenticated() {
if (isset($_SESSION['authenticated'])) {
-// This check does not work properly because we are not getting here. Need to improve.
-// if (!isset($_COOKIE[LOGIN_COOKIE_NAME])) {
-// die ("Your browser's cookie functionality is turned off. Please turn it on.");
-// }
+ // This check does not work properly because we are not getting here. Need to improve.
+ // if (!isset($_COOKIE[LOGIN_COOKIE_NAME])) {
+ // die ("Your browser's cookie functionality is turned off. Please turn it on.");
+ // }
global $smarty;
$smarty->assign('authenticated', true); // Used in header.tpl for menu display.
return true;
}
session_write_close();
+ global $smarty;
+ $smarty->assign('authenticated', false); // Used in header.tpl for menu display.
return false;
}
diff --git a/WEB-INF/lib/I18n.class.php b/WEB-INF/lib/I18n.class.php
index bd4e9ffd3..03da164ed 100644
--- a/WEB-INF/lib/I18n.class.php
+++ b/WEB-INF/lib/I18n.class.php
@@ -46,7 +46,7 @@ function get($key) {
}
eval("\$value = \$this->keys".$str.";");
} else {
- $value = $this->keys[$key];
+ $value = isset($this->keys[$key]) ? $this->keys[$key] : '';
}
return $value;
}
diff --git a/WEB-INF/lib/auth/Auth_db.class.php b/WEB-INF/lib/auth/Auth_db.class.php
index b5fbdaef9..ed0904ad0 100644
--- a/WEB-INF/lib/auth/Auth_db.class.php
+++ b/WEB-INF/lib/auth/Auth_db.class.php
@@ -19,9 +19,41 @@ function authenticate($login, $password)
{
$mdb2 = getConnection();
+ if (AUTH_DB_HASH_ALGORITHM !== '') {
+ $sql = "SELECT id, password as hash FROM tt_users"." WHERE login = ".$mdb2->quote($login)." AND status = 1";
+ $res = $mdb2->query($sql);
+ if (is_a($res, 'PEAR_Error')) {
+ die($res->getMessage());
+ }
+ $val = $res->fetchRow();
+ if (isset($val['id']) && $val['id'] > 0) {
+ if (password_verify($password, $val['hash'])) {
+ if (password_needs_rehash($val['hash'], PASSWORD_ALGORITHM, AUTH_DB_HASH_ALGORITHM_OPTIONS)) {
+ $sql = "update `tt_users` set `password` = '".password_hash($password, PASSWORD_ALGORITHM, AUTH_DB_HASH_ALGORITHM_OPTIONS)."' where `id` = " . $mdb2->quote($val['id']);
+ $affected = $mdb2->exec($sql);
+ if (is_a($res, 'PEAR_Error')) die($res->getMessage());
+ }
+ return array('login'=>$login,'id'=>$val['id']);
+ }
+ }
+ }
+ else {
+ // md5 hash
+ $sql = "SELECT id FROM tt_users"." WHERE login = ".$mdb2->quote($login)." AND password = md5(".$mdb2->quote($password).") AND status = 1";
+ $res = $mdb2->query($sql);
+ if (is_a($res, 'PEAR_Error')) {
+ die($res->getMessage());
+ }
+ $val = $res->fetchRow();
+ if (isset($val['id']) && $val['id'] > 0) {
+ return array('login'=>$login,'id'=>$val['id']);
+ }
+ }
+ return false;
+
+ /*
// Try md5 password match first.
- $sql = "SELECT id FROM tt_users".
- " WHERE login = ".$mdb2->quote($login)." AND password = md5(".$mdb2->quote($password).") AND status = 1";
+ $sql = "SELECT id FROM tt_users"." WHERE login = ".$mdb2->quote($login)." AND password = md5(".$mdb2->quote($password).") AND status = 1";
$res = $mdb2->query($sql);
if (is_a($res, 'PEAR_Error')) {
@@ -74,6 +106,7 @@ function authenticate($login, $password)
}
return false;
+ */
}
function isPasswordExternal() {
diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php
index 79aba106b..838588567 100644
--- a/WEB-INF/lib/common.lib.php
+++ b/WEB-INF/lib/common.lib.php
@@ -150,7 +150,7 @@ function ttValidString($val, $emptyValid = false, $maxChars = 0)
// ttValidCss is used to check user input for custom css.
function ttValidCss($val)
{
- $val = trim($val);
+ $val = is_null($val) ? '' : trim($val);
if (strlen($val) == 0)
return true;
@@ -169,7 +169,7 @@ function ttValidCss($val)
// ttValidTranslation is used to check user input for custom translation.
function ttValidTranslation($val)
{
- $val = trim($val);
+ $val = is_null($val) ? '' : trim($val);
if (strlen($val) == 0)
return true;
@@ -186,7 +186,7 @@ function ttValidTranslation($val)
// ttValidTranslationLine is used to check an individual line in custom translation.
function ttValidTranslationLine($val)
{
- $val = trim($val);
+ $val = is_null($val) ? '' : trim($val);
if (strlen($val) == 0)
return false; // Empty line is not valid.
@@ -211,14 +211,15 @@ function ttValidTranslationLine($val)
// We identify these parts by 3 "stop sign" emojis (aka "octagonal sign" U+1F6D1).
function ttValidTemplateText($val)
{
- $valid = strpos($val, '🛑🛑🛑') === false; // no 3 "stop sign" emojis in a row.
+
+ $valid = (is_null($val) ? false : strpos($val, '🛑🛑🛑') === false); // no 3 "stop sign" emojis in a row.
return $valid;
}
// ttValidEmail is used to check user input to validate an email string.
function ttValidEmail($val, $emptyValid = false)
{
- $val = trim($val);
+ $val = is_null($val) ? '' : trim($val);
if (strlen($val) == 0)
return ($emptyValid ? true : false);
@@ -236,7 +237,7 @@ function ttValidEmail($val, $emptyValid = false)
// ttValidEmailList is used to check user input to validate an email string.
function ttValidEmailList($val, $emptyValid = false)
{
- $val = trim($val);
+ $val = is_null($val) ? '' : trim($val);
if (strlen($val) == 0)
return ($emptyValid ? true : false);
@@ -254,7 +255,7 @@ function ttValidEmailList($val, $emptyValid = false)
// ttValidFloat is used to check user input to validate a float value.
function ttValidFloat($val, $emptyValid = false)
{
- $val = trim($val);
+ $val = is_null($val) ? '' : trim($val);
if (strlen($val) == 0)
return ($emptyValid ? true : false);
@@ -368,7 +369,7 @@ function ttValidTime($val)
// ttValidInteger is used to check user input to validate an integer.
function ttValidInteger($val, $emptyValid = false)
{
- $val = trim($val);
+ $val = is_null($val) ? '' : trim($val);
if (strlen($val) == 0)
return ($emptyValid ? true : false);
@@ -424,7 +425,7 @@ function ttValidCronSpec($val)
// But this works.
$regexp = '/^'.$fields_re.'$/';
-
+ if (is_null($val)) return false;
if (!preg_match($regexp, $val))
return false;
@@ -434,7 +435,7 @@ function ttValidCronSpec($val)
// ttValidCondition is used to check user input to validate a notification condition.
function ttValidCondition($val, $emptyValid = true)
{
- $val = trim($val);
+ $val = is_null($val) ? '' : trim($val);
if (strlen($val) == 0)
return ($emptyValid ? true : false);
@@ -455,7 +456,7 @@ function ttValidCondition($val, $emptyValid = true)
// For example, IPv4-mapped IPv6 addresses will fail. This may need to be fixed.
function ttValidIP($val, $emptyValid = false)
{
- $val = trim($val);
+ $val = is_null($val) ? '' : trim($val);
if (strlen($val) == 0 && $emptyValid)
return true;
@@ -475,7 +476,7 @@ function ttValidIP($val, $emptyValid = false)
// The above means Jan 1 and Dec 31 are holidays in all years, while Apr 20 is only in 2019.
function ttValidHolidays($val)
{
- $val = trim($val);
+ $val = is_null($val) ? '' : trim($val);
if (strlen($val) == 0) return true;
$dates = explode(',', $val);
@@ -660,6 +661,6 @@ function ttRandomString($length = 32) {
// This mitigates a risk of CSV injection, see https://owasp.org/www-community/attacks/CSV_Injection
// Additionally, it replaces each quote character with a double quote.
function ttNeutralizeForCsv($val) {
- $result = ltrim($val, '=+-@');
+ $result = is_null($val) ? '' : ltrim($val, '=+-@');
return str_replace('"', '""', $result);
}
diff --git a/WEB-INF/lib/form/ActionForm.class.php b/WEB-INF/lib/form/ActionForm.class.php
index 358f8af5c..10ae71e05 100644
--- a/WEB-INF/lib/form/ActionForm.class.php
+++ b/WEB-INF/lib/form/ActionForm.class.php
@@ -12,6 +12,7 @@ class ActionForm {
var $mVariables = array();
var $mForm = null;
var $mInitForm = false;
+ var $name = "";
function __construct($name, &$form, $request=null) {
$this->setName($name);
diff --git a/WEB-INF/lib/form/DateField.class.php b/WEB-INF/lib/form/DateField.class.php
index d349d5687..0281c812c 100644
--- a/WEB-INF/lib/form/DateField.class.php
+++ b/WEB-INF/lib/form/DateField.class.php
@@ -9,6 +9,8 @@ class DateField extends TextField {
var $mWeekStartDay = 0;
var $mDateFormat = "d/m/Y";
var $lToday = "Today";
+ var $mMonthNames;
+ var $mWeekDayShortNames;
var $lCalendarButtons = array('today'=>'Today', 'close'=>'Close');
@@ -382,9 +384,9 @@ function adjustiFrame(pickerDiv, iFrameDiv) {
if (defined('DIR_NAME'))
$dir_name = trim(constant('DIR_NAME'), '/');
if (!empty($dir_name))
- $app_root = '/'.$dir_name;
+ $app_root = '/'.$dir_name.'/';
- $html .= "
name."');\">\n";
+ $html .= "
name."');\">\n";
}
return $html;
diff --git a/WEB-INF/lib/form/Form.class.php b/WEB-INF/lib/form/Form.class.php
index cee608fe5..b16998d9f 100644
--- a/WEB-INF/lib/form/Form.class.php
+++ b/WEB-INF/lib/form/Form.class.php
@@ -30,6 +30,7 @@ function addInput($params) {
import('form.TextField');
$el = new TextField($params['name']);
if (isset($params['class'])) $el->setCssClass($params['class']);
+ if (isset($params['minlength'])) $el->setMinLength($params['minlength']);
if (isset($params['maxlength'])) $el->setMaxLength($params['maxlength']);
if (isset($params['placeholder'])) $el->setPLaceholder($params['placeholder']);
break;
@@ -38,7 +39,8 @@ function addInput($params) {
import('form.PasswordField');
$el = new PasswordField($params['name']);
if (isset($params['class'])) $el->setCssClass($params['class']);
- if (isset($params['maxlength'])) $el->setMaxLength($params['maxlength']);
+ if (isset($params['minlength'])) $el->setMinLength($params['minlength']);
+ if (isset($params['maxlength'])) $el->setMaxLength($params['maxlength']);
break;
case 'datefield':
diff --git a/WEB-INF/lib/form/FormElement.class.php b/WEB-INF/lib/form/FormElement.class.php
index 16b8d76d1..570702b06 100644
--- a/WEB-INF/lib/form/FormElement.class.php
+++ b/WEB-INF/lib/form/FormElement.class.php
@@ -11,6 +11,7 @@ class FormElement {
var $placeholder = ''; // placeholder
var $size = ''; // control size
var $max_length = ''; // max length of text in control
+ var $min_length = ''; // min length of text in control
var $on_change = ''; // what happens when value of control changes
var $on_click = ''; // what happens when the control is clicked
var $label = ''; // optional label for control
@@ -52,6 +53,9 @@ function getLabel() { return $this->label; }
function setMaxLength($value) { $this->max_length = $value; }
function getMaxLength() { return $this->max_length; }
+ function setMinLength($value) { $this->min_length = $value; }
+ function getMinLength() { return $this->min_length; }
+
function setStyle($value) { $this->style = $value; }
function getStyle() { return $this->style; }
diff --git a/WEB-INF/lib/form/PasswordField.class.php b/WEB-INF/lib/form/PasswordField.class.php
index ff6802c90..c7984b210 100644
--- a/WEB-INF/lib/form/PasswordField.class.php
+++ b/WEB-INF/lib/form/PasswordField.class.php
@@ -27,6 +27,9 @@ function getHtml() {
if ($this->style != '')
$html.= ' style="'.$this->style.'"';
+ if ($this->min_length != '')
+ $html.= ' minlength="'.$this->min_length.'"';
+
if ($this->max_length != '')
$html.= ' maxlength="'.$this->max_length.'"';
diff --git a/WEB-INF/lib/form/Submit.class.php b/WEB-INF/lib/form/Submit.class.php
index 151600b32..22d717706 100644
--- a/WEB-INF/lib/form/Submit.class.php
+++ b/WEB-INF/lib/form/Submit.class.php
@@ -39,6 +39,9 @@ function getHtml() {
if (empty($this->id))
$this->id = $this->name;
+ if (is_array($this->value))
+ return '';
+
// Output HTML.
$html = "\n\tname\" id=\"$this->id\"";
$html .= " value=\"$this->value\"";
diff --git a/WEB-INF/lib/form/Table.class.php b/WEB-INF/lib/form/Table.class.php
index acdf4813a..d164efb2f 100644
--- a/WEB-INF/lib/form/Table.class.php
+++ b/WEB-INF/lib/form/Table.class.php
@@ -157,8 +157,9 @@ function getHtml() {
// Print rows.
if (is_array($this->mData)) {
+ $rowHoverBackgroundColor = ($this->isInteractive() ? "onmouseover=\"setRowBackground(this, '".$this->mBgColorOver."')\" onmouseout=\"setRowBackground(this, null)\"" : "");
for ($row = 0; $row < count($this->mData); $row++) {
- $html .= "\n
mBgColor."\" onmouseover=\"setRowBackground(this, '".$this->mBgColorOver."')\" onmouseout=\"setRowBackground(this, null)\">\n";
+ $html .= "\n
mBgColor."\" ".$rowHoverBackgroundColor.">\n";
for ($col = 0; $col < $this->getColumnCount(); $col++) {
if (0 == $col && strtolower(get_class($this->mColumns[$col]->getRenderer())) == 'checkboxcellrenderer') {
// Checkbox for the row. Determine if selected.
diff --git a/WEB-INF/lib/form/TextArea.class.php b/WEB-INF/lib/form/TextArea.class.php
index 4faac1447..07dfa3a10 100644
--- a/WEB-INF/lib/form/TextArea.class.php
+++ b/WEB-INF/lib/form/TextArea.class.php
@@ -46,7 +46,6 @@ function getHtml() {
$html .= " name=\"$this->name\" id=\"$this->id\"";
if ($this->max_length!="") {
- if ($this->mOnKeyPress) $this->mOnKeyPress .= ";";
$html .= " maxlength=\"$this->max_length\"";
}
diff --git a/WEB-INF/lib/form/TextField.class.php b/WEB-INF/lib/form/TextField.class.php
index bfc0e551f..dd20f0dfa 100644
--- a/WEB-INF/lib/form/TextField.class.php
+++ b/WEB-INF/lib/form/TextField.class.php
@@ -49,15 +49,14 @@ function getHtml() {
if (!empty($this->size)) $html .= " size=\"$this->size\"";
if (!empty($this->style)) $html .= " style=\"$this->style\"";
if (!empty($this->title)) $html .= " title=\"$this->title\"";
+ if (!empty($this->min_length)) $html .= " minlength=\"$this->min_length\"";
if (!empty($this->placeholder)) $html .= " placeholder=\"$this->placeholder\"";
if($this->isEnabled()) {
if (!empty($this->max_length)) $html .= " maxlength=\"$this->max_length\"";
if (!empty($this->on_change)) $html .= " onchange=\"$this->on_change\"";
}
-
- $html .= " value=\"".htmlspecialchars($this->getValue())."\"";
-
+ $html .= " value=\"". (is_null($this->getValue()) ? '' : htmlspecialchars($this->getValue())) ."\"";
if(!$this->isEnabled()) $html .= " readonly";
$html .= ">\n";
return $html;
diff --git a/WEB-INF/lib/libchart/classes/view/chart/PieChart.php b/WEB-INF/lib/libchart/classes/view/chart/PieChart.php
index 0b5c417a4..9d0350fec 100644
--- a/WEB-INF/lib/libchart/classes/view/chart/PieChart.php
+++ b/WEB-INF/lib/libchart/classes/view/chart/PieChart.php
@@ -26,6 +26,13 @@ class PieChart extends Chart {
protected $pieCenterX;
protected $pieCenterY;
+ protected $total;
+ protected $percent;
+ protected $pieWidth;
+ protected $pieHeight;
+ protected $pieDepth;
+
+
/**
* Constructor of a pie chart.
*
@@ -167,7 +174,7 @@ protected function drawDisc($cy, $colorArray, $mode) {
if ($angle2 - $angle1 <= 0)
$angle2 = $angle1 + 1;
- imagefilledarc($img, $this->pieCenterX, $cy, $this->pieWidth, $this->pieHeight, $angle1, $angle2, $color->getColor($img), $mode);
+ imagefilledarc($img, intval($this->pieCenterX), intval($cy), intval($this->pieWidth), intval($this->pieHeight), intval($angle1), intval($angle2), $color->getColor($img), $mode);
$angle1 = $angle2;
diff --git a/WEB-INF/lib/libchart/classes/view/plot/Plot.php b/WEB-INF/lib/libchart/classes/view/plot/Plot.php
index 88e42dfb3..2bdb35210 100644
--- a/WEB-INF/lib/libchart/classes/view/plot/Plot.php
+++ b/WEB-INF/lib/libchart/classes/view/plot/Plot.php
@@ -102,6 +102,8 @@ class Plot {
* GD image
*/
protected $img;
+ protected $width;
+ protected $height;
/**
* Drawing primitives
diff --git a/WEB-INF/lib/libchart/classes/view/primitive/Primitive.php b/WEB-INF/lib/libchart/classes/view/primitive/Primitive.php
index f88c99e02..7db38ea87 100644
--- a/WEB-INF/lib/libchart/classes/view/primitive/Primitive.php
+++ b/WEB-INF/lib/libchart/classes/view/primitive/Primitive.php
@@ -44,8 +44,18 @@ public function __construct($img) {
* @param Color line color
*/
public function line($x1, $y1, $x2, $y2, $color, $width = 1) {
- imagefilledpolygon($this->img, array($x1, $y1 - $width / 2, $x1, $y1 + $width / 2, $x2, $y2 + $width / 2, $x2, $y2 - $width / 2), 4, $color->getColor($this->img));
- // imageline($this->img, $x1, $y1, $x2, $y2, $color->getColor($this->img));
+ //imagefilledpolygon($this->img, array($x1, $y1 - $width / 2, $x1, $y1 + $width / 2, $x2, $y2 + $width / 2, $x2, $y2 - $width / 2), 4, $color->getColor($this->img));
+ // imageline($this->img, $x1, $y1, $x2, $y2, $color->getColor($this->img));
+
+ if (version_compare(phpversion(), '8.0', '>=')) {
+ // PHP > 8.1 : Using the $num_points parameter is deprecated
+ // imagefilledpolygon(GdImage $image, array $points, int $color): bool
+ imagefilledpolygon($this->img, array($x1, $y1 - $width / 2, $x1, $y1 + $width / 2, $x2, $y2 + $width / 2, $x2, $y2 - $width / 2), $color->getColor($this->img));
+ }
+ else {
+ // imagefilledpolygon(GdImage $image, array $points, int $num_points, int $color): bool
+ imagefilledpolygon($this->img, array($x1, $y1 - $width / 2, $x1, $y1 + $width / 2, $x2, $y2 + $width / 2, $x2, $y2 - $width / 2), 4, $color->getColor($this->img));
+ }
}
/**
diff --git a/WEB-INF/lib/libchart/classes/view/text/Text.php b/WEB-INF/lib/libchart/classes/view/text/Text.php
index f66ea7d3e..088150183 100644
--- a/WEB-INF/lib/libchart/classes/view/text/Text.php
+++ b/WEB-INF/lib/libchart/classes/view/text/Text.php
@@ -30,6 +30,9 @@ class Text {
public $VERTICAL_CENTER_ALIGN = 16;
public $VERTICAL_BOTTOM_ALIGN = 32;
+ public $fontCondensed;
+ public $fontCondensedBold;
+
/**
* Creates a new text drawing helper.
*/
@@ -87,7 +90,7 @@ public function printText($img, $px, $py, $color, $text, $fontFileName, $align =
$py += $textHeight;
}
- imagettftext($img, $fontSize, $angle, $px, $py, $color->getColor($img), $fontFileName, $text);
+ imagettftext($img, intval($fontSize), intval($angle), intval($px), intval($py), $color->getColor($img), $fontFileName, $text);
}
/**
diff --git a/WEB-INF/lib/pear/MDB2/Date.php b/WEB-INF/lib/pear/MDB2/Date.php
index e867e48e5..c7b95ffcb 100644
--- a/WEB-INF/lib/pear/MDB2/Date.php
+++ b/WEB-INF/lib/pear/MDB2/Date.php
@@ -122,7 +122,7 @@ public static function mdbTime()
public static function date2Mdbstamp($hour = null, $minute = null, $second = null,
$month = null, $day = null, $year = null)
{
- return MDB2_Date::unix2Mdbstamp(mktime($hour, $minute, $second, $month, $day, $year, -1));
+ return MDB2_Date::unix2Mdbstamp(mktime($hour, $minute, $second, $month, $day, $year)); // The "is_dst" parameter for function mktime() is deprecated since PHP 5.1 and removed since PHP 7.0
}
// }}}
@@ -156,7 +156,7 @@ public static function mdbstamp2Unix($mdb_timestamp)
{
$arr = MDB2_Date::mdbstamp2Date($mdb_timestamp);
- return mktime($arr['hour'], $arr['minute'], $arr['second'], $arr['month'], $arr['day'], $arr['year'], -1);
+ return mktime($arr['hour'], $arr['minute'], $arr['second'], $arr['month'], $arr['day'], $arr['year']); // The "is_dst" parameter for function mktime() is deprecated since PHP 5.1 and removed since PHP 7.0
}
// }}}
diff --git a/WEB-INF/lib/pear/MDB2/Driver/mysqli.php b/WEB-INF/lib/pear/MDB2/Driver/mysqli.php
index f49e8eb87..cac6784c9 100644
--- a/WEB-INF/lib/pear/MDB2/Driver/mysqli.php
+++ b/WEB-INF/lib/pear/MDB2/Driver/mysqli.php
@@ -94,6 +94,12 @@ class MDB2_Driver_mysqli extends MDB2_Driver_Common
public $varchar_max_length = 255;
+
+ // Added 2024-10-15
+ // PHP Deprecated: Creation of dynamic property MDB2_Driver_mysqli::$loaded_version_modules is deprecated
+ // Ideally, this should be fixed in MDB2 package.
+ public $loaded_version_modules = array();
+
// }}}
// {{{ constructor
diff --git a/WEB-INF/lib/pear/Mail.php b/WEB-INF/lib/pear/Mail.php
old mode 100644
new mode 100755
index e7cff2f64..df4b28c8a
--- a/WEB-INF/lib/pear/Mail.php
+++ b/WEB-INF/lib/pear/Mail.php
@@ -1,265 +1,267 @@
-
- * @copyright 1997-2010 Chuck Hagenbuch
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id$
- * @link http://pear.php.net/package/Mail/
- */
-
-require_once 'PEAR.php';
-
-/**
- * PEAR's Mail:: interface. Defines the interface for implementing
- * mailers under the PEAR hierarchy, and provides supporting functions
- * useful in multiple mailer backends.
- *
- * @version $Revision$
- * @package Mail
- */
-class Mail
-{
- /**
- * Line terminator used for separating header lines.
- * @var string
- */
- public $sep = "\r\n";
-
- /**
- * Provides an interface for generating Mail:: objects of various
- * types
- *
- * @param string $driver The kind of Mail:: object to instantiate.
- * @param array $params The parameters to pass to the Mail:: object.
- *
- * @return object Mail a instance of the driver class or if fails a PEAR Error
- */
- public static function factory($driver, $params = array())
- {
- $driver = strtolower($driver);
- @include_once 'Mail/' . $driver . '.php';
- $class = 'Mail_' . $driver;
- if (class_exists($class)) {
- $mailer = new $class($params);
- return $mailer;
- } else {
- return PEAR::raiseError('Unable to find class for driver ' . $driver);
- }
- }
-
- /**
- * Implements Mail::send() function using php's built-in mail()
- * command.
- *
- * @param mixed $recipients Either a comma-seperated list of recipients
- * (RFC822 compliant), or an array of recipients,
- * each RFC822 valid. This may contain recipients not
- * specified in the headers, for Bcc:, resending
- * messages, etc.
- *
- * @param array $headers The array of headers to send with the mail, in an
- * associative array, where the array key is the
- * header name (ie, 'Subject'), and the array value
- * is the header value (ie, 'test'). The header
- * produced from those values would be 'Subject:
- * test'.
- *
- * @param string $body The full text of the message body, including any
- * Mime parts, etc.
- *
- * @return mixed Returns true on success, or a PEAR_Error
- * containing a descriptive error message on
- * failure.
- *
- * @deprecated use Mail_mail::send instead
- */
- public function send($recipients, $headers, $body)
- {
- if (!is_array($headers)) {
- return PEAR::raiseError('$headers must be an array');
- }
-
- $result = $this->_sanitizeHeaders($headers);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- // if we're passed an array of recipients, implode it.
- if (is_array($recipients)) {
- $recipients = implode(', ', $recipients);
- }
-
- // get the Subject out of the headers array so that we can
- // pass it as a seperate argument to mail().
- $subject = '';
- if (isset($headers['Subject'])) {
- $subject = $headers['Subject'];
- unset($headers['Subject']);
- }
-
- // flatten the headers out.
- list(, $text_headers) = Mail::prepareHeaders($headers);
-
- return mail($recipients, $subject, $body, $text_headers);
- }
-
- /**
- * Sanitize an array of mail headers by removing any additional header
- * strings present in a legitimate header's value. The goal of this
- * filter is to prevent mail injection attacks.
- *
- * @param array $headers The associative array of headers to sanitize.
- */
- protected function _sanitizeHeaders(&$headers)
- {
- foreach ($headers as $key => $value) {
- $headers[$key] =
- preg_replace('=((||0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
- null, $value);
- }
- }
-
- /**
- * Take an array of mail headers and return a string containing
- * text usable in sending a message.
- *
- * @param array $headers The array of headers to prepare, in an associative
- * array, where the array key is the header name (ie,
- * 'Subject'), and the array value is the header
- * value (ie, 'test'). The header produced from those
- * values would be 'Subject: test'.
- *
- * @return mixed Returns false if it encounters a bad address,
- * otherwise returns an array containing two
- * elements: Any From: address found in the headers,
- * and the plain text version of the headers.
- */
- protected function prepareHeaders($headers)
- {
- $lines = array();
- $from = null;
-
- foreach ($headers as $key => $value) {
- if (strcasecmp($key, 'From') === 0) {
- include_once 'Mail/RFC822.php';
- $parser = new Mail_RFC822();
- $addresses = $parser->parseAddressList($value, 'localhost', false);
- if (is_a($addresses, 'PEAR_Error')) {
- return $addresses;
- }
-
- $from = $addresses[0]->mailbox . '@' . $addresses[0]->host;
-
- // Reject envelope From: addresses with spaces.
- if (strstr($from, ' ')) {
- return false;
- }
-
- $lines[] = $key . ': ' . $value;
- } elseif (strcasecmp($key, 'Received') === 0) {
- $received = array();
- if (is_array($value)) {
- foreach ($value as $line) {
- $received[] = $key . ': ' . $line;
- }
- }
- else {
- $received[] = $key . ': ' . $value;
- }
- // Put Received: headers at the top. Spam detectors often
- // flag messages with Received: headers after the Subject:
- // as spam.
- $lines = array_merge($received, $lines);
- } else {
- // If $value is an array (i.e., a list of addresses), convert
- // it to a comma-delimited string of its elements (addresses).
- if (is_array($value)) {
- $value = implode(', ', $value);
- }
- $lines[] = $key . ': ' . $value;
- }
- }
-
- return array($from, join($this->sep, $lines));
- }
-
- /**
- * Take a set of recipients and parse them, returning an array of
- * bare addresses (forward paths) that can be passed to sendmail
- * or an smtp server with the rcpt to: command.
- *
- * @param mixed Either a comma-seperated list of recipients
- * (RFC822 compliant), or an array of recipients,
- * each RFC822 valid.
- *
- * @return mixed An array of forward paths (bare addresses) or a PEAR_Error
- * object if the address list could not be parsed.
- */
- protected function parseRecipients($recipients)
- {
- include_once 'Mail/RFC822.php';
-
- // if we're passed an array, assume addresses are valid and
- // implode them before parsing.
- if (is_array($recipients)) {
- $recipients = implode(', ', $recipients);
- }
-
- // Parse recipients, leaving out all personal info. This is
- // for smtp recipients, etc. All relevant personal information
- // should already be in the headers.
- $Mail_RFC822 = new Mail_RFC822();
- $addresses = $Mail_RFC822->parseAddressList($recipients, 'localhost', false);
-
- // If parseAddressList() returned a PEAR_Error object, just return it.
- if (is_a($addresses, 'PEAR_Error')) {
- return $addresses;
- }
-
- $recipients = array();
- if (is_array($addresses)) {
- foreach ($addresses as $ob) {
- $recipients[] = $ob->mailbox . '@' . $ob->host;
- }
- }
-
- return $recipients;
- }
-
-}
+
+ * @copyright 1997-2017 Chuck Hagenbuch
+ * @license http://opensource.org/licenses/BSD-3-Clause New BSD License
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/Mail/
+ */
+
+require_once 'PEAR.php';
+
+/**
+ * PEAR's Mail:: interface. Defines the interface for implementing
+ * mailers under the PEAR hierarchy, and provides supporting functions
+ * useful in multiple mailer backends.
+ *
+ * @version $Revision$
+ * @package Mail
+ */
+class Mail
+{
+ /**
+ * Line terminator used for separating header lines.
+ * @var string
+ */
+ public $sep = "\r\n";
+
+ /**
+ * Provides an interface for generating Mail:: objects of various
+ * types
+ *
+ * @param string $driver The kind of Mail:: object to instantiate.
+ * @param array $params The parameters to pass to the Mail:: object.
+ *
+ * @return object Mail a instance of the driver class or if fails a PEAR Error
+ */
+ public static function factory($driver, $params = array())
+ {
+ $driver = strtolower($driver);
+ @include_once 'Mail/' . $driver . '.php';
+ $class = 'Mail_' . $driver;
+ if (class_exists($class)) {
+ $mailer = new $class($params);
+ return $mailer;
+ } else {
+ return PEAR::raiseError('Unable to find class for driver ' . $driver);
+ }
+ }
+
+ /**
+ * Implements Mail::send() function using php's built-in mail()
+ * command.
+ *
+ * @param mixed $recipients Either a comma-seperated list of recipients
+ * (RFC822 compliant), or an array of recipients,
+ * each RFC822 valid. This may contain recipients not
+ * specified in the headers, for Bcc:, resending
+ * messages, etc.
+ *
+ * @param array $headers The array of headers to send with the mail, in an
+ * associative array, where the array key is the
+ * header name (ie, 'Subject'), and the array value
+ * is the header value (ie, 'test'). The header
+ * produced from those values would be 'Subject:
+ * test'.
+ *
+ * @param string $body The full text of the message body, including any
+ * Mime parts, etc.
+ *
+ * @return mixed Returns true on success, or a PEAR_Error
+ * containing a descriptive error message on
+ * failure.
+ *
+ * @deprecated use Mail_mail::send instead
+ */
+ public function send($recipients, $headers, $body)
+ {
+ if (!is_array($headers)) {
+ return PEAR::raiseError('$headers must be an array');
+ }
+
+ $result = $this->_sanitizeHeaders($headers);
+ if (is_a($result, 'PEAR_Error')) {
+ return $result;
+ }
+
+ // if we're passed an array of recipients, implode it.
+ if (is_array($recipients)) {
+ $recipients = implode(', ', $recipients);
+ }
+
+ // get the Subject out of the headers array so that we can
+ // pass it as a seperate argument to mail().
+ $subject = '';
+ if (isset($headers['Subject'])) {
+ $subject = $headers['Subject'];
+ unset($headers['Subject']);
+ }
+
+ // flatten the headers out.
+ list(, $text_headers) = Mail::prepareHeaders($headers);
+
+ return mail($recipients, $subject, $body, $text_headers);
+ }
+
+ /**
+ * Sanitize an array of mail headers by removing any additional header
+ * strings present in a legitimate header's value. The goal of this
+ * filter is to prevent mail injection attacks.
+ *
+ * @param array $headers The associative array of headers to sanitize.
+ */
+ protected function _sanitizeHeaders(&$headers)
+ {
+ foreach ($headers as $key => $value) {
+ $headers[$key] =
+ preg_replace('=((||0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
+ '', $value);
+ }
+ }
+
+ /**
+ * Take an array of mail headers and return a string containing
+ * text usable in sending a message.
+ *
+ * @param array $headers The array of headers to prepare, in an associative
+ * array, where the array key is the header name (ie,
+ * 'Subject'), and the array value is the header
+ * value (ie, 'test'). The header produced from those
+ * values would be 'Subject: test'.
+ *
+ * @return mixed Returns false if it encounters a bad address,
+ * otherwise returns an array containing two
+ * elements: Any From: address found in the headers,
+ * and the plain text version of the headers.
+ */
+ protected function prepareHeaders($headers)
+ {
+ $lines = array();
+ $from = null;
+
+ foreach ($headers as $key => $value) {
+ if (strcasecmp($key, 'From') === 0) {
+ include_once 'Mail/RFC822.php';
+ $parser = new Mail_RFC822();
+ $addresses = $parser->parseAddressList($value, 'localhost', false);
+ if (is_a($addresses, 'PEAR_Error')) {
+ return $addresses;
+ }
+
+ $from = $addresses[0]->mailbox . '@' . $addresses[0]->host;
+
+ // Reject envelope From: addresses with spaces.
+ if (strstr($from, ' ')) {
+ return false;
+ }
+
+ $lines[] = $key . ': ' . $value;
+ } elseif (strcasecmp($key, 'Received') === 0) {
+ $received = array();
+ if (is_array($value)) {
+ foreach ($value as $line) {
+ $received[] = $key . ': ' . $line;
+ }
+ }
+ else {
+ $received[] = $key . ': ' . $value;
+ }
+ // Put Received: headers at the top. Spam detectors often
+ // flag messages with Received: headers after the Subject:
+ // as spam.
+ $lines = array_merge($received, $lines);
+ } else {
+ // If $value is an array (i.e., a list of addresses), convert
+ // it to a comma-delimited string of its elements (addresses).
+ if (is_array($value)) {
+ $value = implode(', ', $value);
+ }
+ $lines[] = $key . ': ' . $value;
+ }
+ }
+
+ return array($from, join($this->sep, $lines));
+ }
+
+ /**
+ * Take a set of recipients and parse them, returning an array of
+ * bare addresses (forward paths) that can be passed to sendmail
+ * or an smtp server with the rcpt to: command.
+ *
+ * @param mixed Either a comma-seperated list of recipients
+ * (RFC822 compliant), or an array of recipients,
+ * each RFC822 valid.
+ *
+ * @return mixed An array of forward paths (bare addresses) or a PEAR_Error
+ * object if the address list could not be parsed.
+ */
+ protected function parseRecipients($recipients)
+ {
+ include_once 'Mail/RFC822.php';
+
+ // if we're passed an array, assume addresses are valid and
+ // implode them before parsing.
+ if (is_array($recipients)) {
+ $recipients = implode(', ', $recipients);
+ }
+
+ // Parse recipients, leaving out all personal info. This is
+ // for smtp recipients, etc. All relevant personal information
+ // should already be in the headers.
+ $Mail_RFC822 = new Mail_RFC822();
+ $addresses = $Mail_RFC822->parseAddressList($recipients, 'localhost', false);
+
+ // If parseAddressList() returned a PEAR_Error object, just return it.
+ if (is_a($addresses, 'PEAR_Error')) {
+ return $addresses;
+ }
+
+ $recipients = array();
+ if (is_array($addresses)) {
+ foreach ($addresses as $ob) {
+ $recipients[] = $ob->mailbox . '@' . $ob->host;
+ }
+ }
+
+ return $recipients;
+ }
+
+}
diff --git a/WEB-INF/lib/pear/Mail/RFC822.php b/WEB-INF/lib/pear/Mail/RFC822.php
old mode 100644
new mode 100755
index d010a20e8..0c2abd34d
--- a/WEB-INF/lib/pear/Mail/RFC822.php
+++ b/WEB-INF/lib/pear/Mail/RFC822.php
@@ -1,927 +1,940 @@
-
- * @author Chuck Hagenbuch (A comment), ted@example.com (Ted Bloggs), Barney;';
- * $structure = Mail_RFC822::parseAddressList($address_string, 'example.com', true)
- * print_r($structure);
- *
- * @author Richard Heyes
- * @author Chuck Hagenbuch
- * @version $Revision$
- * @license BSD
- * @package Mail
- */
-class Mail_RFC822 {
-
- /**
- * The address being parsed by the RFC822 object.
- * @var string $address
- */
- var $address = '';
-
- /**
- * The default domain to use for unqualified addresses.
- * @var string $default_domain
- */
- var $default_domain = 'localhost';
-
- /**
- * Should we return a nested array showing groups, or flatten everything?
- * @var boolean $nestGroups
- */
- var $nestGroups = true;
-
- /**
- * Whether or not to validate atoms for non-ascii characters.
- * @var boolean $validate
- */
- var $validate = true;
-
- /**
- * The array of raw addresses built up as we parse.
- * @var array $addresses
- */
- var $addresses = array();
-
- /**
- * The final array of parsed address information that we build up.
- * @var array $structure
- */
- var $structure = array();
-
- /**
- * The current error message, if any.
- * @var string $error
- */
- var $error = null;
-
- /**
- * An internal counter/pointer.
- * @var integer $index
- */
- var $index = null;
-
- /**
- * The number of groups that have been found in the address list.
- * @var integer $num_groups
- * @access public
- */
- var $num_groups = 0;
-
- /**
- * A variable so that we can tell whether or not we're inside a
- * Mail_RFC822 object.
- * @var boolean $mailRFC822
- */
- var $mailRFC822 = true;
-
- /**
- * A limit after which processing stops
- * @var int $limit
- */
- var $limit = null;
-
- /**
- * Sets up the object. The address must either be set here or when
- * calling parseAddressList(). One or the other.
- *
- * @param string $address The address(es) to validate.
- * @param string $default_domain Default domain/host etc. If not supplied, will be set to localhost.
- * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing.
- * @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance.
- *
- * @return object Mail_RFC822 A new Mail_RFC822 object.
- */
- public function __construct($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null)
- {
- if (isset($address)) $this->address = $address;
- if (isset($default_domain)) $this->default_domain = $default_domain;
- if (isset($nest_groups)) $this->nestGroups = $nest_groups;
- if (isset($validate)) $this->validate = $validate;
- if (isset($limit)) $this->limit = $limit;
- }
-
- /**
- * Starts the whole process. The address must either be set here
- * or when creating the object. One or the other.
- *
- * @param string $address The address(es) to validate.
- * @param string $default_domain Default domain/host etc.
- * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing.
- * @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance.
- *
- * @return array A structured array of addresses.
- */
- public function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null)
- {
- if (!isset($this) || !isset($this->mailRFC822)) {
- $obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit);
- return $obj->parseAddressList();
- }
-
- if (isset($address)) $this->address = $address;
- if (isset($default_domain)) $this->default_domain = $default_domain;
- if (isset($nest_groups)) $this->nestGroups = $nest_groups;
- if (isset($validate)) $this->validate = $validate;
- if (isset($limit)) $this->limit = $limit;
-
- $this->structure = array();
- $this->addresses = array();
- $this->error = null;
- $this->index = null;
-
- // Unfold any long lines in $this->address.
- $this->address = preg_replace('/\r?\n/', "\r\n", $this->address);
- $this->address = preg_replace('/\r\n(\t| )+/', ' ', $this->address);
-
- while ($this->address = $this->_splitAddresses($this->address));
-
- if ($this->address === false || isset($this->error)) {
- require_once 'PEAR.php';
- return PEAR::raiseError($this->error);
- }
-
- // Validate each address individually. If we encounter an invalid
- // address, stop iterating and return an error immediately.
- foreach ($this->addresses as $address) {
- $valid = $this->_validateAddress($address);
-
- if ($valid === false || isset($this->error)) {
- require_once 'PEAR.php';
- return PEAR::raiseError($this->error);
- }
-
- if (!$this->nestGroups) {
- $this->structure = array_merge($this->structure, $valid);
- } else {
- $this->structure[] = $valid;
- }
- }
-
- return $this->structure;
- }
-
- /**
- * Splits an address into separate addresses.
- *
- * @param string $address The addresses to split.
- * @return boolean Success or failure.
- */
- protected function _splitAddresses($address)
- {
- if (!empty($this->limit) && count($this->addresses) == $this->limit) {
- return '';
- }
-
- if ($this->_isGroup($address) && !isset($this->error)) {
- $split_char = ';';
- $is_group = true;
- } elseif (!isset($this->error)) {
- $split_char = ',';
- $is_group = false;
- } elseif (isset($this->error)) {
- return false;
- }
-
- // Split the string based on the above ten or so lines.
- $parts = explode($split_char, $address);
- $string = $this->_splitCheck($parts, $split_char);
-
- // If a group...
- if ($is_group) {
- // If $string does not contain a colon outside of
- // brackets/quotes etc then something's fubar.
-
- // First check there's a colon at all:
- if (strpos($string, ':') === false) {
- $this->error = 'Invalid address: ' . $string;
- return false;
- }
-
- // Now check it's outside of brackets/quotes:
- if (!$this->_splitCheck(explode(':', $string), ':')) {
- return false;
- }
-
- // We must have a group at this point, so increase the counter:
- $this->num_groups++;
- }
-
- // $string now contains the first full address/group.
- // Add to the addresses array.
- $this->addresses[] = array(
- 'address' => trim($string),
- 'group' => $is_group
- );
-
- // Remove the now stored address from the initial line, the +1
- // is to account for the explode character.
- $address = trim(substr($address, strlen($string) + 1));
-
- // If the next char is a comma and this was a group, then
- // there are more addresses, otherwise, if there are any more
- // chars, then there is another address.
- if ($is_group && substr($address, 0, 1) == ','){
- $address = trim(substr($address, 1));
- return $address;
-
- } elseif (strlen($address) > 0) {
- return $address;
-
- } else {
- return '';
- }
-
- // If you got here then something's off
- return false;
- }
-
- /**
- * Checks for a group at the start of the string.
- *
- * @param string $address The address to check.
- * @return boolean Whether or not there is a group at the start of the string.
- */
- protected function _isGroup($address)
- {
- // First comma not in quotes, angles or escaped:
- $parts = explode(',', $address);
- $string = $this->_splitCheck($parts, ',');
-
- // Now we have the first address, we can reliably check for a
- // group by searching for a colon that's not escaped or in
- // quotes or angle brackets.
- if (count($parts = explode(':', $string)) > 1) {
- $string2 = $this->_splitCheck($parts, ':');
- return ($string2 !== $string);
- } else {
- return false;
- }
- }
-
- /**
- * A common function that will check an exploded string.
- *
- * @param array $parts The exloded string.
- * @param string $char The char that was exploded on.
- * @return mixed False if the string contains unclosed quotes/brackets, or the string on success.
- */
- protected function _splitCheck($parts, $char)
- {
- $string = $parts[0];
-
- for ($i = 0; $i < count($parts); $i++) {
- if ($this->_hasUnclosedQuotes($string)
- || $this->_hasUnclosedBrackets($string, '<>')
- || $this->_hasUnclosedBrackets($string, '[]')
- || $this->_hasUnclosedBrackets($string, '()')
- || substr($string, -1) == '\\') {
- if (isset($parts[$i + 1])) {
- $string = $string . $char . $parts[$i + 1];
- } else {
- $this->error = 'Invalid address spec. Unclosed bracket or quotes';
- return false;
- }
- } else {
- $this->index = $i;
- break;
- }
- }
-
- return $string;
- }
-
- /**
- * Checks if a string has unclosed quotes or not.
- *
- * @param string $string The string to check.
- * @return boolean True if there are unclosed quotes inside the string,
- * false otherwise.
- */
- protected function _hasUnclosedQuotes($string)
- {
- $string = trim($string);
- $iMax = strlen($string);
- $in_quote = false;
- $i = $slashes = 0;
-
- for (; $i < $iMax; ++$i) {
- switch ($string[$i]) {
- case '\\':
- ++$slashes;
- break;
-
- case '"':
- if ($slashes % 2 == 0) {
- $in_quote = !$in_quote;
- }
- // Fall through to default action below.
-
- default:
- $slashes = 0;
- break;
- }
- }
-
- return $in_quote;
- }
-
- /**
- * Checks if a string has an unclosed brackets or not. IMPORTANT:
- * This function handles both angle brackets and square brackets;
- *
- * @param string $string The string to check.
- * @param string $chars The characters to check for.
- * @return boolean True if there are unclosed brackets inside the string, false otherwise.
- */
- protected function _hasUnclosedBrackets($string, $chars)
- {
- $num_angle_start = substr_count($string, $chars[0]);
- $num_angle_end = substr_count($string, $chars[1]);
-
- $this->_hasUnclosedBracketsSub($string, $num_angle_start, $chars[0]);
- $this->_hasUnclosedBracketsSub($string, $num_angle_end, $chars[1]);
-
- if ($num_angle_start < $num_angle_end) {
- $this->error = 'Invalid address spec. Unmatched quote or bracket (' . $chars . ')';
- return false;
- } else {
- return ($num_angle_start > $num_angle_end);
- }
- }
-
- /**
- * Sub function that is used only by hasUnclosedBrackets().
- *
- * @param string $string The string to check.
- * @param integer &$num The number of occurences.
- * @param string $char The character to count.
- * @return integer The number of occurences of $char in $string, adjusted for backslashes.
- */
- protected function _hasUnclosedBracketsSub($string, &$num, $char)
- {
- $parts = explode($char, $string);
- for ($i = 0; $i < count($parts); $i++){
- if (substr($parts[$i], -1) == '\\' || $this->_hasUnclosedQuotes($parts[$i]))
- $num--;
- if (isset($parts[$i + 1]))
- $parts[$i + 1] = $parts[$i] . $char . $parts[$i + 1];
- }
-
- return $num;
- }
-
- /**
- * Function to begin checking the address.
- *
- * @param string $address The address to validate.
- * @return mixed False on failure, or a structured array of address information on success.
- */
- protected function _validateAddress($address)
- {
- $is_group = false;
- $addresses = array();
-
- if ($address['group']) {
- $is_group = true;
-
- // Get the group part of the name
- $parts = explode(':', $address['address']);
- $groupname = $this->_splitCheck($parts, ':');
- $structure = array();
-
- // And validate the group part of the name.
- if (!$this->_validatePhrase($groupname)){
- $this->error = 'Group name did not validate.';
- return false;
- } else {
- // Don't include groups if we are not nesting
- // them. This avoids returning invalid addresses.
- if ($this->nestGroups) {
- $structure = new stdClass;
- $structure->groupname = $groupname;
- }
- }
-
- $address['address'] = ltrim(substr($address['address'], strlen($groupname . ':')));
- }
-
- // If a group then split on comma and put into an array.
- // Otherwise, Just put the whole address in an array.
- if ($is_group) {
- while (strlen($address['address']) > 0) {
- $parts = explode(',', $address['address']);
- $addresses[] = $this->_splitCheck($parts, ',');
- $address['address'] = trim(substr($address['address'], strlen(end($addresses) . ',')));
- }
- } else {
- $addresses[] = $address['address'];
- }
-
- // Trim the whitespace from all of the address strings.
- array_map('trim', $addresses);
-
- // Validate each mailbox.
- // Format could be one of: name
- // geezer@domain.com
- // geezer
- // ... or any other format valid by RFC 822.
- for ($i = 0; $i < count($addresses); $i++) {
- if (!$this->validateMailbox($addresses[$i])) {
- if (empty($this->error)) {
- $this->error = 'Validation failed for: ' . $addresses[$i];
- }
- return false;
- }
- }
-
- // Nested format
- if ($this->nestGroups) {
- if ($is_group) {
- $structure->addresses = $addresses;
- } else {
- $structure = $addresses[0];
- }
-
- // Flat format
- } else {
- if ($is_group) {
- $structure = array_merge($structure, $addresses);
- } else {
- $structure = $addresses;
- }
- }
-
- return $structure;
- }
-
- /**
- * Function to validate a phrase.
- *
- * @param string $phrase The phrase to check.
- * @return boolean Success or failure.
- */
- protected function _validatePhrase($phrase)
- {
- // Splits on one or more Tab or space.
- $parts = preg_split('/[ \\x09]+/', $phrase, -1, PREG_SPLIT_NO_EMPTY);
-
- $phrase_parts = array();
- while (count($parts) > 0){
- $phrase_parts[] = $this->_splitCheck($parts, ' ');
- for ($i = 0; $i < $this->index + 1; $i++)
- array_shift($parts);
- }
-
- foreach ($phrase_parts as $part) {
- // If quoted string:
- if (substr($part, 0, 1) == '"') {
- if (!$this->_validateQuotedString($part)) {
- return false;
- }
- continue;
- }
-
- // Otherwise it's an atom:
- if (!$this->_validateAtom($part)) return false;
- }
-
- return true;
- }
-
- /**
- * Function to validate an atom which from rfc822 is:
- * atom = 1*
- *
- * If validation ($this->validate) has been turned off, then
- * validateAtom() doesn't actually check anything. This is so that you
- * can split a list of addresses up before encoding personal names
- * (umlauts, etc.), for example.
- *
- * @param string $atom The string to check.
- * @return boolean Success or failure.
- */
- protected function _validateAtom($atom)
- {
- if (!$this->validate) {
- // Validation has been turned off; assume the atom is okay.
- return true;
- }
-
- // Check for any char from ASCII 0 - ASCII 127
- if (!preg_match('/^[\\x00-\\x7E]+$/i', $atom, $matches)) {
- return false;
- }
-
- // Check for specials:
- if (preg_match('/[][()<>@,;\\:". ]/', $atom)) {
- return false;
- }
-
- // Check for control characters (ASCII 0-31):
- if (preg_match('/[\\x00-\\x1F]+/', $atom)) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Function to validate quoted string, which is:
- * quoted-string = <"> *(qtext/quoted-pair) <">
- *
- * @param string $qstring The string to check
- * @return boolean Success or failure.
- */
- protected function _validateQuotedString($qstring)
- {
- // Leading and trailing "
- $qstring = substr($qstring, 1, -1);
-
- // Perform check, removing quoted characters first.
- return !preg_match('/[\x0D\\\\"]/', preg_replace('/\\\\./', '', $qstring));
- }
-
- /**
- * Function to validate a mailbox, which is:
- * mailbox = addr-spec ; simple address
- * / phrase route-addr ; name and route-addr
- *
- * @param string &$mailbox The string to check.
- * @return boolean Success or failure.
- */
- public function validateMailbox(&$mailbox)
- {
- // A couple of defaults.
- $phrase = '';
- $comment = '';
- $comments = array();
-
- // Catch any RFC822 comments and store them separately.
- $_mailbox = $mailbox;
- while (strlen(trim($_mailbox)) > 0) {
- $parts = explode('(', $_mailbox);
- $before_comment = $this->_splitCheck($parts, '(');
- if ($before_comment != $_mailbox) {
- // First char should be a (.
- $comment = substr(str_replace($before_comment, '', $_mailbox), 1);
- $parts = explode(')', $comment);
- $comment = $this->_splitCheck($parts, ')');
- $comments[] = $comment;
-
- // +2 is for the brackets
- $_mailbox = substr($_mailbox, strpos($_mailbox, '('.$comment)+strlen($comment)+2);
- } else {
- break;
- }
- }
-
- foreach ($comments as $comment) {
- $mailbox = str_replace("($comment)", '', $mailbox);
- }
-
- $mailbox = trim($mailbox);
-
- // Check for name + route-addr
- if (substr($mailbox, -1) == '>' && substr($mailbox, 0, 1) != '<') {
- $parts = explode('<', $mailbox);
- $name = $this->_splitCheck($parts, '<');
-
- $phrase = trim($name);
- $route_addr = trim(substr($mailbox, strlen($name.'<'), -1));
-
- if ($this->_validatePhrase($phrase) === false || ($route_addr = $this->_validateRouteAddr($route_addr)) === false) {
- return false;
- }
-
- // Only got addr-spec
- } else {
- // First snip angle brackets if present.
- if (substr($mailbox, 0, 1) == '<' && substr($mailbox, -1) == '>') {
- $addr_spec = substr($mailbox, 1, -1);
- } else {
- $addr_spec = $mailbox;
- }
-
- if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
- return false;
- }
- }
-
- // Construct the object that will be returned.
- $mbox = new stdClass();
-
- // Add the phrase (even if empty) and comments
- $mbox->personal = $phrase;
- $mbox->comment = isset($comments) ? $comments : array();
-
- if (isset($route_addr)) {
- $mbox->mailbox = $route_addr['local_part'];
- $mbox->host = $route_addr['domain'];
- $route_addr['adl'] !== '' ? $mbox->adl = $route_addr['adl'] : '';
- } else {
- $mbox->mailbox = $addr_spec['local_part'];
- $mbox->host = $addr_spec['domain'];
- }
-
- $mailbox = $mbox;
- return true;
- }
-
- /**
- * This function validates a route-addr which is:
- * route-addr = "<" [route] addr-spec ">"
- *
- * Angle brackets have already been removed at the point of
- * getting to this function.
- *
- * @param string $route_addr The string to check.
- * @return mixed False on failure, or an array containing validated address/route information on success.
- */
- protected function _validateRouteAddr($route_addr)
- {
- // Check for colon.
- if (strpos($route_addr, ':') !== false) {
- $parts = explode(':', $route_addr);
- $route = $this->_splitCheck($parts, ':');
- } else {
- $route = $route_addr;
- }
-
- // If $route is same as $route_addr then the colon was in
- // quotes or brackets or, of course, non existent.
- if ($route === $route_addr){
- unset($route);
- $addr_spec = $route_addr;
- if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
- return false;
- }
- } else {
- // Validate route part.
- if (($route = $this->_validateRoute($route)) === false) {
- return false;
- }
-
- $addr_spec = substr($route_addr, strlen($route . ':'));
-
- // Validate addr-spec part.
- if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
- return false;
- }
- }
-
- if (isset($route)) {
- $return['adl'] = $route;
- } else {
- $return['adl'] = '';
- }
-
- $return = array_merge($return, $addr_spec);
- return $return;
- }
-
- /**
- * Function to validate a route, which is:
- * route = 1#("@" domain) ":"
- *
- * @param string $route The string to check.
- * @return mixed False on failure, or the validated $route on success.
- */
- protected function _validateRoute($route)
- {
- // Split on comma.
- $domains = explode(',', trim($route));
-
- foreach ($domains as $domain) {
- $domain = str_replace('@', '', trim($domain));
- if (!$this->_validateDomain($domain)) return false;
- }
-
- return $route;
- }
-
- /**
- * Function to validate a domain, though this is not quite what
- * you expect of a strict internet domain.
- *
- * domain = sub-domain *("." sub-domain)
- *
- * @param string $domain The string to check.
- * @return mixed False on failure, or the validated domain on success.
- */
- protected function _validateDomain($domain)
- {
- // Note the different use of $subdomains and $sub_domains
- $subdomains = explode('.', $domain);
-
- while (count($subdomains) > 0) {
- $sub_domains[] = $this->_splitCheck($subdomains, '.');
- for ($i = 0; $i < $this->index + 1; $i++)
- array_shift($subdomains);
- }
-
- foreach ($sub_domains as $sub_domain) {
- if (!$this->_validateSubdomain(trim($sub_domain)))
- return false;
- }
-
- // Managed to get here, so return input.
- return $domain;
- }
-
- /**
- * Function to validate a subdomain:
- * subdomain = domain-ref / domain-literal
- *
- * @param string $subdomain The string to check.
- * @return boolean Success or failure.
- */
- protected function _validateSubdomain($subdomain)
- {
- if (preg_match('|^\[(.*)]$|', $subdomain, $arr)){
- if (!$this->_validateDliteral($arr[1])) return false;
- } else {
- if (!$this->_validateAtom($subdomain)) return false;
- }
-
- // Got here, so return successful.
- return true;
- }
-
- /**
- * Function to validate a domain literal:
- * domain-literal = "[" *(dtext / quoted-pair) "]"
- *
- * @param string $dliteral The string to check.
- * @return boolean Success or failure.
- */
- protected function _validateDliteral($dliteral)
- {
- return !preg_match('/(.)[][\x0D\\\\]/', $dliteral, $matches) && $matches[1] != '\\';
- }
-
- /**
- * Function to validate an addr-spec.
- *
- * addr-spec = local-part "@" domain
- *
- * @param string $addr_spec The string to check.
- * @return mixed False on failure, or the validated addr-spec on success.
- */
- protected function _validateAddrSpec($addr_spec)
- {
- $addr_spec = trim($addr_spec);
-
- // Split on @ sign if there is one.
- if (strpos($addr_spec, '@') !== false) {
- $parts = explode('@', $addr_spec);
- $local_part = $this->_splitCheck($parts, '@');
- $domain = substr($addr_spec, strlen($local_part . '@'));
-
- // No @ sign so assume the default domain.
- } else {
- $local_part = $addr_spec;
- $domain = $this->default_domain;
- }
-
- if (($local_part = $this->_validateLocalPart($local_part)) === false) return false;
- if (($domain = $this->_validateDomain($domain)) === false) return false;
-
- // Got here so return successful.
- return array('local_part' => $local_part, 'domain' => $domain);
- }
-
- /**
- * Function to validate the local part of an address:
- * local-part = word *("." word)
- *
- * @param string $local_part
- * @return mixed False on failure, or the validated local part on success.
- */
- protected function _validateLocalPart($local_part)
- {
- $parts = explode('.', $local_part);
- $words = array();
-
- // Split the local_part into words.
- while (count($parts) > 0) {
- $words[] = $this->_splitCheck($parts, '.');
- for ($i = 0; $i < $this->index + 1; $i++) {
- array_shift($parts);
- }
- }
-
- // Validate each word.
- foreach ($words as $word) {
- // word cannot be empty (#17317)
- if ($word === '') {
- return false;
- }
- // If this word contains an unquoted space, it is invalid. (6.2.4)
- if (strpos($word, ' ') && $word[0] !== '"')
- {
- return false;
- }
-
- if ($this->_validatePhrase(trim($word)) === false) return false;
- }
-
- // Managed to get here, so return the input.
- return $local_part;
- }
-
- /**
- * Returns an approximate count of how many addresses are in the
- * given string. This is APPROXIMATE as it only splits based on a
- * comma which has no preceding backslash. Could be useful as
- * large amounts of addresses will end up producing *large*
- * structures when used with parseAddressList().
- *
- * @param string $data Addresses to count
- * @return int Approximate count
- */
- public function approximateCount($data)
- {
- return count(preg_split('/(?@. This can be sufficient for most
- * people. Optional stricter mode can be utilised which restricts
- * mailbox characters allowed to alphanumeric, full stop, hyphen
- * and underscore.
- *
- * @param string $data Address to check
- * @param boolean $strict Optional stricter mode
- * @return mixed False if it fails, an indexed array
- * username/domain if it matches
- */
- public function isValidInetAddress($data, $strict = false)
- {
- $regex = $strict ? '/^([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i' : '/^([*+!.$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i';
- if (preg_match($regex, trim($data), $matches)) {
- return array($matches[1], $matches[2]);
- } else {
- return false;
- }
- }
-
-}
+
+ * @author Chuck Hagenbuch (A comment), ted@example.com (Ted Bloggs), Barney;';
+ * $parser = new Mail_RFC822();
+ * $structure = $parser->parseAddressList($address_string, 'example.com', true);
+ * print_r($structure);
+ *
+ * @author Richard Heyes
+ * @author Chuck Hagenbuch
+ * @version $Revision$
+ * @license BSD
+ * @package Mail
+ */
+class Mail_RFC822 {
+
+ /**
+ * The address being parsed by the RFC822 object.
+ * @var string $address
+ */
+ var $address = '';
+
+ /**
+ * The default domain to use for unqualified addresses.
+ * @var string $default_domain
+ */
+ var $default_domain = 'localhost';
+
+ /**
+ * Should we return a nested array showing groups, or flatten everything?
+ * @var boolean $nestGroups
+ */
+ var $nestGroups = true;
+
+ /**
+ * Whether or not to validate atoms for non-ascii characters.
+ * @var boolean $validate
+ */
+ var $validate = true;
+
+ /**
+ * The array of raw addresses built up as we parse.
+ * @var array $addresses
+ */
+ var $addresses = array();
+
+ /**
+ * The final array of parsed address information that we build up.
+ * @var array $structure
+ */
+ var $structure = array();
+
+ /**
+ * The current error message, if any.
+ * @var string $error
+ */
+ var $error = null;
+
+ /**
+ * An internal counter/pointer.
+ * @var integer $index
+ */
+ var $index = null;
+
+ /**
+ * The number of groups that have been found in the address list.
+ * @var integer $num_groups
+ * @access public
+ */
+ var $num_groups = 0;
+
+ /**
+ * A variable so that we can tell whether or not we're inside a
+ * Mail_RFC822 object.
+ * @var boolean $mailRFC822
+ */
+ var $mailRFC822 = true;
+
+ /**
+ * A limit after which processing stops
+ * @var int $limit
+ */
+ var $limit = null;
+
+ /**
+ * Sets up the object. The address must either be set here or when
+ * calling parseAddressList(). One or the other.
+ *
+ * @param string $address The address(es) to validate.
+ * @param string $default_domain Default domain/host etc. If not supplied, will be set to localhost.
+ * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing.
+ * @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance.
+ *
+ * @return object Mail_RFC822 A new Mail_RFC822 object.
+ */
+ public function __construct($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null)
+ {
+ if (isset($address)) $this->address = $address;
+ if (isset($default_domain)) $this->default_domain = $default_domain;
+ if (isset($nest_groups)) $this->nestGroups = $nest_groups;
+ if (isset($validate)) $this->validate = $validate;
+ if (isset($limit)) $this->limit = $limit;
+ }
+
+ /**
+ * Starts the whole process. The address must either be set here
+ * or when creating the object. One or the other.
+ *
+ * @param string $address The address(es) to validate.
+ * @param string $default_domain Default domain/host etc.
+ * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing.
+ * @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance.
+ *
+ * @return array A structured array of addresses.
+ */
+ public function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null)
+ {
+ if (version_compare(PHP_VERSION, '8.0.0', '<')) {
+ if (!isset($this) || !isset($this->mailRFC822)) {
+ $warn = "Calling non-static methods statically is no longer supported since PHP 8";
+ trigger_error($warn, E_USER_NOTICE);
+ $obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit);
+ return $obj->parseAddressList();
+ }
+ }
+
+ if (isset($address)) $this->address = $address;
+ if (isset($default_domain)) $this->default_domain = $default_domain;
+ if (isset($nest_groups)) $this->nestGroups = $nest_groups;
+ if (isset($validate)) $this->validate = $validate;
+ if (isset($limit)) $this->limit = $limit;
+
+ $this->structure = array();
+ $this->addresses = array();
+ $this->error = null;
+ $this->index = null;
+
+ // Unfold any long lines in $this->address.
+ $this->address = preg_replace('/\r?\n/', "\r\n", $this->address);
+ $this->address = preg_replace('/\r\n(\t| )+/', ' ', $this->address);
+
+ while ($this->address = $this->_splitAddresses($this->address));
+
+ if ($this->address === false || isset($this->error)) {
+ require_once 'PEAR.php';
+ return PEAR::raiseError($this->error);
+ }
+
+ // Validate each address individually. If we encounter an invalid
+ // address, stop iterating and return an error immediately.
+ foreach ($this->addresses as $address) {
+ $valid = $this->_validateAddress($address);
+
+ if ($valid === false || isset($this->error)) {
+ require_once 'PEAR.php';
+ return PEAR::raiseError($this->error);
+ }
+
+ if (!$this->nestGroups) {
+ $this->structure = array_merge($this->structure, $valid);
+ } else {
+ $this->structure[] = $valid;
+ }
+ }
+
+ return $this->structure;
+ }
+
+ /**
+ * Splits an address into separate addresses.
+ *
+ * @param string $address The addresses to split.
+ * @return boolean Success or failure.
+ */
+ protected function _splitAddresses($address)
+ {
+ $is_group = false;
+ $split_char = ',';
+
+ if (!empty($this->limit) && count($this->addresses) == $this->limit) {
+ return '';
+ }
+
+ if ($this->_isGroup($address) && !isset($this->error)) {
+ $split_char = ';';
+ $is_group = true;
+ } elseif (!isset($this->error)) {
+ $split_char = ',';
+ $is_group = false;
+ } elseif (isset($this->error)) {
+ return false;
+ }
+
+ // Split the string based on the above ten or so lines.
+ $parts = explode($split_char, $address);
+ $string = $this->_splitCheck($parts, $split_char);
+
+ // If a group...
+ if ($is_group) {
+ // If $string does not contain a colon outside of
+ // brackets/quotes etc then something's fubar.
+
+ // First check there's a colon at all:
+ if (strpos($string, ':') === false) {
+ $this->error = 'Invalid address: ' . $string;
+ return false;
+ }
+
+ // Now check it's outside of brackets/quotes:
+ if (!$this->_splitCheck(explode(':', $string), ':')) {
+ return false;
+ }
+
+ // We must have a group at this point, so increase the counter:
+ $this->num_groups++;
+ }
+
+ // $string now contains the first full address/group.
+ // Add to the addresses array.
+ $this->addresses[] = array(
+ 'address' => trim($string),
+ 'group' => $is_group
+ );
+
+ // Remove the now stored address from the initial line, the +1
+ // is to account for the explode character.
+ $address = trim(substr($address, strlen($string) + 1));
+
+ // If the next char is a comma and this was a group, then
+ // there are more addresses, otherwise, if there are any more
+ // chars, then there is another address.
+ if ($is_group && substr($address, 0, 1) == ','){
+ $address = trim(substr($address, 1));
+ return $address;
+
+ } elseif (strlen($address) > 0) {
+ return $address;
+
+ } else {
+ return '';
+ }
+
+ // If you got here then something's off
+ return false;
+ }
+
+ /**
+ * Checks for a group at the start of the string.
+ *
+ * @param string $address The address to check.
+ * @return boolean Whether or not there is a group at the start of the string.
+ */
+ protected function _isGroup($address)
+ {
+ // First comma not in quotes, angles or escaped:
+ $parts = explode(',', $address);
+ $string = $this->_splitCheck($parts, ',');
+
+ // Now we have the first address, we can reliably check for a
+ // group by searching for a colon that's not escaped or in
+ // quotes or angle brackets.
+ if (count($parts = explode(':', $string)) > 1) {
+ $string2 = $this->_splitCheck($parts, ':');
+ return ($string2 !== $string);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * A common function that will check an exploded string.
+ *
+ * @param array $parts The exloded string.
+ * @param string $char The char that was exploded on.
+ * @return mixed False if the string contains unclosed quotes/brackets, or the string on success.
+ */
+ protected function _splitCheck($parts, $char)
+ {
+ $string = $parts[0];
+
+ for ($i = 0; $i < count($parts); $i++) {
+ if ($this->_hasUnclosedQuotes($string)
+ || $this->_hasUnclosedBrackets($string, '<>')
+ || $this->_hasUnclosedBrackets($string, '[]')
+ || $this->_hasUnclosedBrackets($string, '()')
+ || substr($string, -1) == '\\') {
+ if (isset($parts[$i + 1])) {
+ $string = $string . $char . $parts[$i + 1];
+ } else {
+ $this->error = 'Invalid address spec. Unclosed bracket or quotes';
+ return false;
+ }
+ } else {
+ $this->index = $i;
+ break;
+ }
+ }
+
+ return $string;
+ }
+
+ /**
+ * Checks if a string has unclosed quotes or not.
+ *
+ * @param string $string The string to check.
+ * @return boolean True if there are unclosed quotes inside the string,
+ * false otherwise.
+ */
+ protected function _hasUnclosedQuotes($string)
+ {
+ $string = trim($string);
+ $iMax = strlen($string);
+ $in_quote = false;
+ $i = $slashes = 0;
+
+ for (; $i < $iMax; ++$i) {
+ switch ($string[$i]) {
+ case '\\':
+ ++$slashes;
+ break;
+
+ case '"':
+ if ($slashes % 2 == 0) {
+ $in_quote = !$in_quote;
+ }
+ // Fall through to default action below.
+
+ default:
+ $slashes = 0;
+ break;
+ }
+ }
+
+ return $in_quote;
+ }
+
+ /**
+ * Checks if a string has an unclosed brackets or not. IMPORTANT:
+ * This function handles both angle brackets and square brackets;
+ *
+ * @param string $string The string to check.
+ * @param string $chars The characters to check for.
+ * @return boolean True if there are unclosed brackets inside the string, false otherwise.
+ */
+ protected function _hasUnclosedBrackets($string, $chars)
+ {
+ $num_angle_start = substr_count($string, $chars[0]);
+ $num_angle_end = substr_count($string, $chars[1]);
+
+ $this->_hasUnclosedBracketsSub($string, $num_angle_start, $chars[0]);
+ $this->_hasUnclosedBracketsSub($string, $num_angle_end, $chars[1]);
+
+ if ($num_angle_start < $num_angle_end) {
+ $this->error = 'Invalid address spec. Unmatched quote or bracket (' . $chars . ')';
+ return false;
+ } else {
+ return ($num_angle_start > $num_angle_end);
+ }
+ }
+
+ /**
+ * Sub function that is used only by hasUnclosedBrackets().
+ *
+ * @param string $string The string to check.
+ * @param integer &$num The number of occurences.
+ * @param string $char The character to count.
+ * @return integer The number of occurences of $char in $string, adjusted for backslashes.
+ */
+ protected function _hasUnclosedBracketsSub($string, &$num, $char)
+ {
+ $parts = explode($char, $string);
+ for ($i = 0; $i < count($parts); $i++){
+ if (substr($parts[$i], -1) == '\\' || $this->_hasUnclosedQuotes($parts[$i]))
+ $num--;
+ if (isset($parts[$i + 1]))
+ $parts[$i + 1] = $parts[$i] . $char . $parts[$i + 1];
+ }
+
+ return $num;
+ }
+
+ /**
+ * Function to begin checking the address.
+ *
+ * @param string $address The address to validate.
+ * @return mixed False on failure, or a structured array of address information on success.
+ */
+ protected function _validateAddress($address)
+ {
+ $structure = null;
+ $is_group = false;
+ $addresses = array();
+
+ if ($address['group']) {
+ $is_group = true;
+
+ // Get the group part of the name
+ $parts = explode(':', $address['address']);
+ $groupname = $this->_splitCheck($parts, ':');
+ $structure = array();
+
+ // And validate the group part of the name.
+ if (!$this->_validatePhrase($groupname)){
+ $this->error = 'Group name did not validate.';
+ return false;
+ } else {
+ // Don't include groups if we are not nesting
+ // them. This avoids returning invalid addresses.
+ if ($this->nestGroups) {
+ $structure = new stdClass;
+ $structure->groupname = $groupname;
+ }
+ }
+
+ $address['address'] = ltrim(substr($address['address'], strlen($groupname . ':')));
+ }
+
+ // If a group then split on comma and put into an array.
+ // Otherwise, Just put the whole address in an array.
+ if ($is_group) {
+ while (strlen($address['address']) > 0) {
+ $parts = explode(',', $address['address']);
+ $addresses[] = $this->_splitCheck($parts, ',');
+ $address['address'] = trim(substr($address['address'], strlen(end($addresses) . ',')));
+ }
+ } else {
+ $addresses[] = $address['address'];
+ }
+
+ // Trim the whitespace from all of the address strings.
+ $addresses = array_map('trim', $addresses);
+
+ // Validate each mailbox.
+ // Format could be one of: name
+ // geezer@domain.com
+ // geezer
+ // ... or any other format valid by RFC 822.
+ for ($i = 0; $i < count($addresses); $i++) {
+ if (!$this->validateMailbox($addresses[$i])) {
+ if (empty($this->error)) {
+ $this->error = 'Validation failed for: ' . $addresses[$i];
+ }
+ return false;
+ }
+ }
+
+ // Nested format
+ if ($this->nestGroups) {
+ if ($is_group) {
+ $structure->addresses = $addresses;
+ } else {
+ $structure = $addresses[0];
+ }
+
+ // Flat format
+ } else {
+ if ($is_group) {
+ $structure = array_merge($structure, $addresses);
+ } else {
+ $structure = $addresses;
+ }
+ }
+
+ return $structure;
+ }
+
+ /**
+ * Function to validate a phrase.
+ *
+ * @param string $phrase The phrase to check.
+ * @return boolean Success or failure.
+ */
+ protected function _validatePhrase($phrase)
+ {
+ // Splits on one or more Tab or space.
+ $parts = preg_split('/[ \\x09]+/', $phrase, -1, PREG_SPLIT_NO_EMPTY);
+
+ $phrase_parts = array();
+ while (count($parts) > 0){
+ $phrase_parts[] = $this->_splitCheck($parts, ' ');
+ for ($i = 0; $i < $this->index + 1; $i++)
+ array_shift($parts);
+ }
+
+ foreach ($phrase_parts as $part) {
+ // If quoted string:
+ if (substr($part, 0, 1) == '"') {
+ if (!$this->_validateQuotedString($part)) {
+ return false;
+ }
+ continue;
+ }
+
+ // Otherwise it's an atom:
+ if (!$this->_validateAtom($part)) return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Function to validate an atom which from rfc822 is:
+ * atom = 1*
+ *
+ * If validation ($this->validate) has been turned off, then
+ * validateAtom() doesn't actually check anything. This is so that you
+ * can split a list of addresses up before encoding personal names
+ * (umlauts, etc.), for example.
+ *
+ * @param string $atom The string to check.
+ * @return boolean Success or failure.
+ */
+ protected function _validateAtom($atom)
+ {
+ if (!$this->validate) {
+ // Validation has been turned off; assume the atom is okay.
+ return true;
+ }
+
+ // Check for any char from ASCII 0 - ASCII 127
+ if (!preg_match('/^[\\x00-\\x7E]+$/i', $atom, $matches)) {
+ return false;
+ }
+
+ // Check for specials:
+ if (preg_match('/[][()<>@,;\\:". ]/', $atom)) {
+ return false;
+ }
+
+ // Check for control characters (ASCII 0-31):
+ if (preg_match('/[\\x00-\\x1F]+/', $atom)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Function to validate quoted string, which is:
+ * quoted-string = <"> *(qtext/quoted-pair) <">
+ *
+ * @param string $qstring The string to check
+ * @return boolean Success or failure.
+ */
+ protected function _validateQuotedString($qstring)
+ {
+ // Leading and trailing "
+ $qstring = substr($qstring, 1, -1);
+
+ // Perform check, removing quoted characters first.
+ return !preg_match('/[\x0D\\\\"]/', preg_replace('/\\\\./', '', $qstring));
+ }
+
+ /**
+ * Function to validate a mailbox, which is:
+ * mailbox = addr-spec ; simple address
+ * / phrase route-addr ; name and route-addr
+ *
+ * @param string &$mailbox The string to check.
+ * @return boolean Success or failure.
+ */
+ public function validateMailbox(&$mailbox)
+ {
+ // A couple of defaults.
+ $phrase = '';
+ $comment = '';
+ $comments = array();
+ $addr_spec = null;
+
+ // Catch any RFC822 comments and store them separately.
+ $_mailbox = $mailbox;
+ while (strlen(trim($_mailbox)) > 0) {
+ $parts = explode('(', $_mailbox);
+ $before_comment = $this->_splitCheck($parts, '(');
+ if ($before_comment != $_mailbox) {
+ // First char should be a (.
+ $comment = substr(str_replace($before_comment, '', $_mailbox), 1);
+ $parts = explode(')', $comment);
+ $comment = $this->_splitCheck($parts, ')');
+ $comments[] = $comment;
+
+ // +2 is for the brackets
+ $_mailbox = substr($_mailbox, strpos($_mailbox, '('.$comment)+strlen($comment)+2);
+ } else {
+ break;
+ }
+ }
+
+ foreach ($comments as $comment) {
+ $mailbox = str_replace("($comment)", '', $mailbox);
+ }
+
+ $mailbox = trim($mailbox);
+
+ // Check for name + route-addr
+ if (substr($mailbox, -1) == '>' && substr($mailbox, 0, 1) != '<') {
+ $parts = explode('<', $mailbox);
+ $name = $this->_splitCheck($parts, '<');
+
+ $phrase = trim($name);
+ $route_addr = trim(substr($mailbox, strlen($name.'<'), -1));
+
+ if ($this->_validatePhrase($phrase) === false || ($route_addr = $this->_validateRouteAddr($route_addr)) === false) {
+ return false;
+ }
+
+ // Only got addr-spec
+ } else {
+ // First snip angle brackets if present.
+ if (substr($mailbox, 0, 1) == '<' && substr($mailbox, -1) == '>') {
+ $addr_spec = substr($mailbox, 1, -1);
+ } else {
+ $addr_spec = $mailbox;
+ }
+
+ if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
+ return false;
+ }
+ }
+
+ // Construct the object that will be returned.
+ $mbox = new stdClass();
+
+ // Add the phrase (even if empty) and comments
+ $mbox->personal = $phrase;
+ $mbox->comment = isset($comments) ? $comments : array();
+
+ if (isset($route_addr)) {
+ $mbox->mailbox = $route_addr['local_part'];
+ $mbox->host = $route_addr['domain'];
+ $route_addr['adl'] !== '' ? $mbox->adl = $route_addr['adl'] : '';
+ } else {
+ $mbox->mailbox = $addr_spec['local_part'];
+ $mbox->host = $addr_spec['domain'];
+ }
+
+ $mailbox = $mbox;
+ return true;
+ }
+
+ /**
+ * This function validates a route-addr which is:
+ * route-addr = "<" [route] addr-spec ">"
+ *
+ * Angle brackets have already been removed at the point of
+ * getting to this function.
+ *
+ * @param string $route_addr The string to check.
+ * @return mixed False on failure, or an array containing validated address/route information on success.
+ */
+ protected function _validateRouteAddr($route_addr)
+ {
+ // Check for colon.
+ if (strpos($route_addr, ':') !== false) {
+ $parts = explode(':', $route_addr);
+ $route = $this->_splitCheck($parts, ':');
+ } else {
+ $route = $route_addr;
+ }
+
+ // If $route is same as $route_addr then the colon was in
+ // quotes or brackets or, of course, non existent.
+ if ($route === $route_addr){
+ unset($route);
+ $addr_spec = $route_addr;
+ if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
+ return false;
+ }
+ } else {
+ // Validate route part.
+ if (($route = $this->_validateRoute($route)) === false) {
+ return false;
+ }
+
+ $addr_spec = substr($route_addr, strlen($route . ':'));
+
+ // Validate addr-spec part.
+ if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
+ return false;
+ }
+ }
+
+ if (isset($route)) {
+ $return['adl'] = $route;
+ } else {
+ $return['adl'] = '';
+ }
+
+ $return = array_merge($return, $addr_spec);
+ return $return;
+ }
+
+ /**
+ * Function to validate a route, which is:
+ * route = 1#("@" domain) ":"
+ *
+ * @param string $route The string to check.
+ * @return mixed False on failure, or the validated $route on success.
+ */
+ protected function _validateRoute($route)
+ {
+ // Split on comma.
+ $domains = explode(',', trim($route));
+
+ foreach ($domains as $domain) {
+ $domain = str_replace('@', '', trim($domain));
+ if (!$this->_validateDomain($domain)) return false;
+ }
+
+ return $route;
+ }
+
+ /**
+ * Function to validate a domain, though this is not quite what
+ * you expect of a strict internet domain.
+ *
+ * domain = sub-domain *("." sub-domain)
+ *
+ * @param string $domain The string to check.
+ * @return mixed False on failure, or the validated domain on success.
+ */
+ protected function _validateDomain($domain)
+ {
+ // Note the different use of $subdomains and $sub_domains
+ $subdomains = explode('.', $domain);
+ $sub_domains = array();
+
+ while (count($subdomains) > 0) {
+ $sub_domains[] = $this->_splitCheck($subdomains, '.');
+ for ($i = 0; $i < $this->index + 1; $i++)
+ array_shift($subdomains);
+ }
+
+ foreach ($sub_domains as $sub_domain) {
+ if (!$this->_validateSubdomain(trim($sub_domain)))
+ return false;
+ }
+
+ // Managed to get here, so return input.
+ return $domain;
+ }
+
+ /**
+ * Function to validate a subdomain:
+ * subdomain = domain-ref / domain-literal
+ *
+ * @param string $subdomain The string to check.
+ * @return boolean Success or failure.
+ */
+ protected function _validateSubdomain($subdomain)
+ {
+ if (preg_match('|^\[(.*)]$|', $subdomain, $arr)){
+ if (!$this->_validateDliteral($arr[1])) return false;
+ } else {
+ if (!$this->_validateAtom($subdomain)) return false;
+ }
+
+ // Got here, so return successful.
+ return true;
+ }
+
+ /**
+ * Function to validate a domain literal:
+ * domain-literal = "[" *(dtext / quoted-pair) "]"
+ *
+ * @param string $dliteral The string to check.
+ * @return boolean Success or failure.
+ */
+ protected function _validateDliteral($dliteral)
+ {
+ return !preg_match('/(.)[][\x0D\\\\]/', $dliteral, $matches) && ((! isset($matches[1])) || $matches[1] != '\\');
+ }
+
+ /**
+ * Function to validate an addr-spec.
+ *
+ * addr-spec = local-part "@" domain
+ *
+ * @param string $addr_spec The string to check.
+ * @return mixed False on failure, or the validated addr-spec on success.
+ */
+ protected function _validateAddrSpec($addr_spec)
+ {
+ $addr_spec = trim($addr_spec);
+
+ // Split on @ sign if there is one.
+ if (strpos($addr_spec, '@') !== false) {
+ $parts = explode('@', $addr_spec);
+ $local_part = $this->_splitCheck($parts, '@');
+ $domain = substr($addr_spec, strlen($local_part . '@'));
+
+ // No @ sign so assume the default domain.
+ } else {
+ $local_part = $addr_spec;
+ $domain = $this->default_domain;
+ }
+
+ if (($local_part = $this->_validateLocalPart($local_part)) === false) return false;
+ if (($domain = $this->_validateDomain($domain)) === false) return false;
+
+ // Got here so return successful.
+ return array('local_part' => $local_part, 'domain' => $domain);
+ }
+
+ /**
+ * Function to validate the local part of an address:
+ * local-part = word *("." word)
+ *
+ * @param string $local_part
+ * @return mixed False on failure, or the validated local part on success.
+ */
+ protected function _validateLocalPart($local_part)
+ {
+ $parts = explode('.', $local_part);
+ $words = array();
+
+ // Split the local_part into words.
+ while (count($parts) > 0) {
+ $words[] = $this->_splitCheck($parts, '.');
+ for ($i = 0; $i < $this->index + 1; $i++) {
+ array_shift($parts);
+ }
+ }
+
+ // Validate each word.
+ foreach ($words as $word) {
+ // word cannot be empty (#17317)
+ if ($word === '') {
+ return false;
+ }
+ // If this word contains an unquoted space, it is invalid. (6.2.4)
+ if (strpos($word, ' ') && $word[0] !== '"')
+ {
+ return false;
+ }
+
+ if ($this->_validatePhrase(trim($word)) === false) return false;
+ }
+
+ // Managed to get here, so return the input.
+ return $local_part;
+ }
+
+ /**
+ * Returns an approximate count of how many addresses are in the
+ * given string. This is APPROXIMATE as it only splits based on a
+ * comma which has no preceding backslash. Could be useful as
+ * large amounts of addresses will end up producing *large*
+ * structures when used with parseAddressList().
+ *
+ * @param string $data Addresses to count
+ * @return int Approximate count
+ */
+ public function approximateCount($data)
+ {
+ return count(preg_split('/(?@. This can be sufficient for most
+ * people. Optional stricter mode can be utilised which restricts
+ * mailbox characters allowed to alphanumeric, full stop, hyphen
+ * and underscore.
+ *
+ * @param string $data Address to check
+ * @param boolean $strict Optional stricter mode
+ * @return mixed False if it fails, an indexed array
+ * username/domain if it matches
+ */
+ public function isValidInetAddress($data, $strict = false)
+ {
+ $regex = $strict ? '/^([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i' : '/^([*+!.$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i';
+ if (preg_match($regex, trim($data), $matches)) {
+ return array($matches[1], $matches[2]);
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/WEB-INF/lib/pear/Mail/mail.php b/WEB-INF/lib/pear/Mail/mail.php
old mode 100644
new mode 100755
index 4d21dc29a..d5160c0cf
--- a/WEB-INF/lib/pear/Mail/mail.php
+++ b/WEB-INF/lib/pear/Mail/mail.php
@@ -1,166 +1,158 @@
-
- * @copyright 2010 Chuck Hagenbuch
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id$
- * @link http://pear.php.net/package/Mail/
- */
-
-/**
- * internal PHP-mail() implementation of the PEAR Mail:: interface.
- * @package Mail
- * @version $Revision$
- */
-class Mail_mail extends Mail {
-
- /**
- * Any arguments to pass to the mail() function.
- * @var string
- */
- var $_params = '';
-
- /**
- * Constructor.
- *
- * Instantiates a new Mail_mail:: object based on the parameters
- * passed in.
- *
- * @param array $params Extra arguments for the mail() function.
- */
- public function __construct($params = null)
- {
- // The other mail implementations accept parameters as arrays.
- // In the interest of being consistent, explode an array into
- // a string of parameter arguments.
- if (is_array($params)) {
- $this->_params = join(' ', $params);
- } else {
- $this->_params = $params;
- }
-
- /* Because the mail() function may pass headers as command
- * line arguments, we can't guarantee the use of the standard
- * "\r\n" separator. Instead, we use the system's native line
- * separator. */
- if (defined('PHP_EOL')) {
- $this->sep = PHP_EOL;
- } else {
- $this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n";
- }
- }
-
- /**
- * Implements Mail_mail::send() function using php's built-in mail()
- * command.
- *
- * @param mixed $recipients Either a comma-seperated list of recipients
- * (RFC822 compliant), or an array of recipients,
- * each RFC822 valid. This may contain recipients not
- * specified in the headers, for Bcc:, resending
- * messages, etc.
- *
- * @param array $headers The array of headers to send with the mail, in an
- * associative array, where the array key is the
- * header name (ie, 'Subject'), and the array value
- * is the header value (ie, 'test'). The header
- * produced from those values would be 'Subject:
- * test'.
- *
- * @param string $body The full text of the message body, including any
- * Mime parts, etc.
- *
- * @return mixed Returns true on success, or a PEAR_Error
- * containing a descriptive error message on
- * failure.
- */
- public function send($recipients, $headers, $body)
- {
- if (!is_array($headers)) {
- return PEAR::raiseError('$headers must be an array');
- }
-
- $result = $this->_sanitizeHeaders($headers);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- // If we're passed an array of recipients, implode it.
- if (is_array($recipients)) {
- $recipients = implode(', ', $recipients);
- }
-
- // Get the Subject out of the headers array so that we can
- // pass it as a seperate argument to mail().
- $subject = '';
- if (isset($headers['Subject'])) {
- $subject = $headers['Subject'];
- unset($headers['Subject']);
- }
-
- // Also remove the To: header. The mail() function will add its own
- // To: header based on the contents of $recipients.
- unset($headers['To']);
-
- // Flatten the headers out.
- $headerElements = $this->prepareHeaders($headers);
- if (is_a($headerElements, 'PEAR_Error')) {
- return $headerElements;
- }
- list(, $text_headers) = $headerElements;
-
- // We only use mail()'s optional fifth parameter if the additional
- // parameters have been provided and we're not running in safe mode.
- if (empty($this->_params) || ini_get('safe_mode')) {
- $result = mail($recipients, $subject, $body, $text_headers);
- } else {
- $result = mail($recipients, $subject, $body, $text_headers,
- $this->_params);
- }
-
- // If the mail() function returned failure, we need to create a
- // PEAR_Error object and return it instead of the boolean result.
- if ($result === false) {
- $result = PEAR::raiseError('mail() returned failure');
- }
-
- return $result;
- }
-
-}
+
+ * @copyright 2010-2017 Chuck Hagenbuch
+ * @license http://opensource.org/licenses/BSD-3-Clause New BSD License
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/Mail/
+ */
+
+/**
+ * internal PHP-mail() implementation of the PEAR Mail:: interface.
+ * @package Mail
+ * @version $Revision$
+ */
+class Mail_mail extends Mail {
+
+ /**
+ * Any arguments to pass to the mail() function.
+ * @var string
+ */
+ var $_params = '';
+
+ /**
+ * Constructor.
+ *
+ * Instantiates a new Mail_mail:: object based on the parameters
+ * passed in.
+ *
+ * @param array $params Extra arguments for the mail() function.
+ */
+ public function __construct($params = null)
+ {
+ // The other mail implementations accept parameters as arrays.
+ // In the interest of being consistent, explode an array into
+ // a string of parameter arguments.
+ if (is_array($params)) {
+ $this->_params = join(' ', $params);
+ } else {
+ $this->_params = $params;
+ }
+ }
+
+ /**
+ * Implements Mail_mail::send() function using php's built-in mail()
+ * command.
+ *
+ * @param mixed $recipients Either a comma-seperated list of recipients
+ * (RFC822 compliant), or an array of recipients,
+ * each RFC822 valid. This may contain recipients not
+ * specified in the headers, for Bcc:, resending
+ * messages, etc.
+ *
+ * @param array $headers The array of headers to send with the mail, in an
+ * associative array, where the array key is the
+ * header name (ie, 'Subject'), and the array value
+ * is the header value (ie, 'test'). The header
+ * produced from those values would be 'Subject:
+ * test'.
+ *
+ * @param string $body The full text of the message body, including any
+ * Mime parts, etc.
+ *
+ * @return mixed Returns true on success, or a PEAR_Error
+ * containing a descriptive error message on
+ * failure.
+ */
+ public function send($recipients, $headers, $body)
+ {
+ if (!is_array($headers)) {
+ return PEAR::raiseError('$headers must be an array');
+ }
+
+ $result = $this->_sanitizeHeaders($headers);
+ if (is_a($result, 'PEAR_Error')) {
+ return $result;
+ }
+
+ // If we're passed an array of recipients, implode it.
+ if (is_array($recipients)) {
+ $recipients = implode(', ', $recipients);
+ }
+
+ // Get the Subject out of the headers array so that we can
+ // pass it as a seperate argument to mail().
+ $subject = '';
+ if (isset($headers['Subject'])) {
+ $subject = $headers['Subject'];
+ unset($headers['Subject']);
+ }
+
+ // Also remove the To: header. The mail() function will add its own
+ // To: header based on the contents of $recipients.
+ unset($headers['To']);
+
+ // Flatten the headers out.
+ $headerElements = $this->prepareHeaders($headers);
+ if (is_a($headerElements, 'PEAR_Error')) {
+ return $headerElements;
+ }
+ list(, $text_headers) = $headerElements;
+
+ // We only use mail()'s optional fifth parameter if the additional
+ // parameters have been provided and we're not running in safe mode.
+ if (empty($this->_params) || ini_get('safe_mode')) {
+ $result = mail($recipients, $subject, $body, $text_headers);
+ } else {
+ $result = mail($recipients, $subject, $body, $text_headers,
+ $this->_params);
+ }
+
+ // If the mail() function returned failure, we need to create a
+ // PEAR_Error object and return it instead of the boolean result.
+ if ($result === false) {
+ $result = PEAR::raiseError('mail() returned failure');
+ }
+
+ return $result;
+ }
+
+}
diff --git a/WEB-INF/lib/pear/Mail/mock.php b/WEB-INF/lib/pear/Mail/mock.php
old mode 100644
new mode 100755
index e3e290bdc..dd84792ef
--- a/WEB-INF/lib/pear/Mail/mock.php
+++ b/WEB-INF/lib/pear/Mail/mock.php
@@ -1,140 +1,142 @@
-
- * @copyright 2010 Chuck Hagenbuch
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id$
- * @link http://pear.php.net/package/Mail/
- */
-
-/**
- * Mock implementation of the PEAR Mail:: interface for testing.
- * @access public
- * @package Mail
- * @version $Revision$
- */
-class Mail_mock extends Mail {
-
- /**
- * Array of messages that have been sent with the mock.
- *
- * @var array
- */
- public $sentMessages = array();
-
- /**
- * Callback before sending mail.
- *
- * @var callback
- */
- protected $_preSendCallback;
-
- /**
- * Callback after sending mai.
- *
- * @var callback
- */
- protected $_postSendCallback;
-
- /**
- * Constructor.
- *
- * Instantiates a new Mail_mock:: object based on the parameters
- * passed in. It looks for the following parameters, both optional:
- * preSendCallback Called before an email would be sent.
- * postSendCallback Called after an email would have been sent.
- *
- * @param array Hash containing any parameters.
- */
- public function __construct($params)
- {
- if (isset($params['preSendCallback']) &&
- is_callable($params['preSendCallback'])) {
- $this->_preSendCallback = $params['preSendCallback'];
- }
-
- if (isset($params['postSendCallback']) &&
- is_callable($params['postSendCallback'])) {
- $this->_postSendCallback = $params['postSendCallback'];
- }
- }
-
- /**
- * Implements Mail_mock::send() function. Silently discards all
- * mail.
- *
- * @param mixed $recipients Either a comma-seperated list of recipients
- * (RFC822 compliant), or an array of recipients,
- * each RFC822 valid. This may contain recipients not
- * specified in the headers, for Bcc:, resending
- * messages, etc.
- *
- * @param array $headers The array of headers to send with the mail, in an
- * associative array, where the array key is the
- * header name (ie, 'Subject'), and the array value
- * is the header value (ie, 'test'). The header
- * produced from those values would be 'Subject:
- * test'.
- *
- * @param string $body The full text of the message body, including any
- * Mime parts, etc.
- *
- * @return mixed Returns true on success, or a PEAR_Error
- * containing a descriptive error message on
- * failure.
- */
- public function send($recipients, $headers, $body)
- {
- if ($this->_preSendCallback) {
- call_user_func_array($this->_preSendCallback,
- array(&$this, $recipients, $headers, $body));
- }
-
- $entry = array('recipients' => $recipients, 'headers' => $headers, 'body' => $body);
- $this->sentMessages[] = $entry;
-
- if ($this->_postSendCallback) {
- call_user_func_array($this->_postSendCallback,
- array(&$this, $recipients, $headers, $body));
- }
-
- return true;
- }
-
-}
+
+ * @copyright 2010-2017 Chuck Hagenbuch
+ * @license http://opensource.org/licenses/BSD-3-Clause New BSD License
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/Mail/
+ */
+
+/**
+ * Mock implementation of the PEAR Mail:: interface for testing.
+ * @access public
+ * @package Mail
+ * @version $Revision$
+ */
+class Mail_mock extends Mail {
+
+ /**
+ * Array of messages that have been sent with the mock.
+ *
+ * @var array
+ */
+ public $sentMessages = array();
+
+ /**
+ * Callback before sending mail.
+ *
+ * @var callback
+ */
+ protected $_preSendCallback;
+
+ /**
+ * Callback after sending mai.
+ *
+ * @var callback
+ */
+ protected $_postSendCallback;
+
+ /**
+ * Constructor.
+ *
+ * Instantiates a new Mail_mock:: object based on the parameters
+ * passed in. It looks for the following parameters, both optional:
+ * preSendCallback Called before an email would be sent.
+ * postSendCallback Called after an email would have been sent.
+ *
+ * @param array Hash containing any parameters.
+ */
+ public function __construct($params)
+ {
+ if (isset($params['preSendCallback']) &&
+ is_callable($params['preSendCallback'])) {
+ $this->_preSendCallback = $params['preSendCallback'];
+ }
+
+ if (isset($params['postSendCallback']) &&
+ is_callable($params['postSendCallback'])) {
+ $this->_postSendCallback = $params['postSendCallback'];
+ }
+ }
+
+ /**
+ * Implements Mail_mock::send() function. Silently discards all
+ * mail.
+ *
+ * @param mixed $recipients Either a comma-seperated list of recipients
+ * (RFC822 compliant), or an array of recipients,
+ * each RFC822 valid. This may contain recipients not
+ * specified in the headers, for Bcc:, resending
+ * messages, etc.
+ *
+ * @param array $headers The array of headers to send with the mail, in an
+ * associative array, where the array key is the
+ * header name (ie, 'Subject'), and the array value
+ * is the header value (ie, 'test'). The header
+ * produced from those values would be 'Subject:
+ * test'.
+ *
+ * @param string $body The full text of the message body, including any
+ * Mime parts, etc.
+ *
+ * @return mixed Returns true on success, or a PEAR_Error
+ * containing a descriptive error message on
+ * failure.
+ */
+ public function send($recipients, $headers, $body)
+ {
+ if ($this->_preSendCallback) {
+ call_user_func_array($this->_preSendCallback,
+ array(&$this, $recipients, $headers, $body));
+ }
+
+ $entry = array('recipients' => $recipients, 'headers' => $headers, 'body' => $body);
+ $this->sentMessages[] = $entry;
+
+ if ($this->_postSendCallback) {
+ call_user_func_array($this->_postSendCallback,
+ array(&$this, $recipients, $headers, $body));
+ }
+
+ return true;
+ }
+
+}
diff --git a/WEB-INF/lib/pear/Mail/null.php b/WEB-INF/lib/pear/Mail/null.php
old mode 100644
new mode 100755
index 7896a4299..36d8e8464
--- a/WEB-INF/lib/pear/Mail/null.php
+++ b/WEB-INF/lib/pear/Mail/null.php
@@ -1,83 +1,85 @@
-
- * @copyright 2010 Phil Kernick
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id$
- * @link http://pear.php.net/package/Mail/
- */
-
-/**
- * Null implementation of the PEAR Mail:: interface.
- * @access public
- * @package Mail
- * @version $Revision$
- */
-class Mail_null extends Mail {
-
- /**
- * Implements Mail_null::send() function. Silently discards all
- * mail.
- *
- * @param mixed $recipients Either a comma-seperated list of recipients
- * (RFC822 compliant), or an array of recipients,
- * each RFC822 valid. This may contain recipients not
- * specified in the headers, for Bcc:, resending
- * messages, etc.
- *
- * @param array $headers The array of headers to send with the mail, in an
- * associative array, where the array key is the
- * header name (ie, 'Subject'), and the array value
- * is the header value (ie, 'test'). The header
- * produced from those values would be 'Subject:
- * test'.
- *
- * @param string $body The full text of the message body, including any
- * Mime parts, etc.
- *
- * @return mixed Returns true on success, or a PEAR_Error
- * containing a descriptive error message on
- * failure.
- */
- public function send($recipients, $headers, $body)
- {
- return true;
- }
-
-}
+
+ * @copyright 2010-2017 Phil Kernick
+ * @license http://opensource.org/licenses/BSD-3-Clause New BSD License
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/Mail/
+ */
+
+/**
+ * Null implementation of the PEAR Mail:: interface.
+ * @access public
+ * @package Mail
+ * @version $Revision$
+ */
+class Mail_null extends Mail {
+
+ /**
+ * Implements Mail_null::send() function. Silently discards all
+ * mail.
+ *
+ * @param mixed $recipients Either a comma-seperated list of recipients
+ * (RFC822 compliant), or an array of recipients,
+ * each RFC822 valid. This may contain recipients not
+ * specified in the headers, for Bcc:, resending
+ * messages, etc.
+ *
+ * @param array $headers The array of headers to send with the mail, in an
+ * associative array, where the array key is the
+ * header name (ie, 'Subject'), and the array value
+ * is the header value (ie, 'test'). The header
+ * produced from those values would be 'Subject:
+ * test'.
+ *
+ * @param string $body The full text of the message body, including any
+ * Mime parts, etc.
+ *
+ * @return mixed Returns true on success, or a PEAR_Error
+ * containing a descriptive error message on
+ * failure.
+ */
+ public function send($recipients, $headers, $body)
+ {
+ return true;
+ }
+
+}
diff --git a/WEB-INF/lib/pear/Mail/sendmail.php b/WEB-INF/lib/pear/Mail/sendmail.php
old mode 100644
new mode 100755
index f8866bdf3..0c3f9801d
--- a/WEB-INF/lib/pear/Mail/sendmail.php
+++ b/WEB-INF/lib/pear/Mail/sendmail.php
@@ -1,169 +1,199 @@
- |
-// +----------------------------------------------------------------------+
-
-/**
- * Sendmail implementation of the PEAR Mail:: interface.
- * @access public
- * @package Mail
- * @version $Revision$
- */
-class Mail_sendmail extends Mail {
-
- /**
- * The location of the sendmail or sendmail wrapper binary on the
- * filesystem.
- * @var string
- */
- var $sendmail_path = '/usr/sbin/sendmail';
-
- /**
- * Any extra command-line parameters to pass to the sendmail or
- * sendmail wrapper binary.
- * @var string
- */
- var $sendmail_args = '-i';
-
- /**
- * Constructor.
- *
- * Instantiates a new Mail_sendmail:: object based on the parameters
- * passed in. It looks for the following parameters:
- * sendmail_path The location of the sendmail binary on the
- * filesystem. Defaults to '/usr/sbin/sendmail'.
- *
- * sendmail_args Any extra parameters to pass to the sendmail
- * or sendmail wrapper binary.
- *
- * If a parameter is present in the $params array, it replaces the
- * default.
- *
- * @param array $params Hash containing any parameters different from the
- * defaults.
- */
- public function __construct($params)
- {
- if (isset($params['sendmail_path'])) {
- $this->sendmail_path = $params['sendmail_path'];
- }
- if (isset($params['sendmail_args'])) {
- $this->sendmail_args = $params['sendmail_args'];
- }
-
- /*
- * Because we need to pass message headers to the sendmail program on
- * the commandline, we can't guarantee the use of the standard "\r\n"
- * separator. Instead, we use the system's native line separator.
- */
- if (defined('PHP_EOL')) {
- $this->sep = PHP_EOL;
- } else {
- $this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n";
- }
- }
-
- /**
- * Implements Mail::send() function using the sendmail
- * command-line binary.
- *
- * @param mixed $recipients Either a comma-seperated list of recipients
- * (RFC822 compliant), or an array of recipients,
- * each RFC822 valid. This may contain recipients not
- * specified in the headers, for Bcc:, resending
- * messages, etc.
- *
- * @param array $headers The array of headers to send with the mail, in an
- * associative array, where the array key is the
- * header name (ie, 'Subject'), and the array value
- * is the header value (ie, 'test'). The header
- * produced from those values would be 'Subject:
- * test'.
- *
- * @param string $body The full text of the message body, including any
- * Mime parts, etc.
- *
- * @return mixed Returns true on success, or a PEAR_Error
- * containing a descriptive error message on
- * failure.
- */
- public function send($recipients, $headers, $body)
- {
- if (!is_array($headers)) {
- return PEAR::raiseError('$headers must be an array');
- }
-
- $result = $this->_sanitizeHeaders($headers);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- $recipients = $this->parseRecipients($recipients);
- if (is_a($recipients, 'PEAR_Error')) {
- return $recipients;
- }
- $recipients = implode(' ', array_map('escapeshellarg', $recipients));
-
- $headerElements = $this->prepareHeaders($headers);
- if (is_a($headerElements, 'PEAR_Error')) {
- return $headerElements;
- }
- list($from, $text_headers) = $headerElements;
-
- /* Since few MTAs are going to allow this header to be forged
- * unless it's in the MAIL FROM: exchange, we'll use
- * Return-Path instead of From: if it's set. */
- if (!empty($headers['Return-Path'])) {
- $from = $headers['Return-Path'];
- }
-
- if (!isset($from)) {
- return PEAR::raiseError('No from address given.');
- } elseif (strpos($from, ' ') !== false ||
- strpos($from, ';') !== false ||
- strpos($from, '&') !== false ||
- strpos($from, '`') !== false) {
- return PEAR::raiseError('From address specified with dangerous characters.');
- }
-
- $from = escapeshellarg($from); // Security bug #16200
-
- $mail = @popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$from -- $recipients", 'w');
- if (!$mail) {
- return PEAR::raiseError('Failed to open sendmail [' . $this->sendmail_path . '] for execution.');
- }
-
- // Write the headers following by two newlines: one to end the headers
- // section and a second to separate the headers block from the body.
- fputs($mail, $text_headers . $this->sep . $this->sep);
-
- fputs($mail, $body);
- $result = pclose($mail);
- if (version_compare(phpversion(), '4.2.3') == -1) {
- // With older php versions, we need to shift the pclose
- // result to get the exit code.
- $result = $result >> 8 & 0xFF;
- }
-
- if ($result != 0) {
- return PEAR::raiseError('sendmail returned error code ' . $result,
- $result);
- }
-
- return true;
- }
-
-}
+
+ * @author Chuck Hagenbuch
+ * @copyright 2010-2017 Chuck Hagenbuch
+ * @license http://opensource.org/licenses/BSD-3-Clause New BSD License
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/Mail/
+ */
+
+/**
+ * Sendmail implementation of the PEAR Mail:: interface.
+ * @access public
+ * @package Mail
+ * @version $Revision$
+ */
+class Mail_sendmail extends Mail {
+
+ /**
+ * The location of the sendmail or sendmail wrapper binary on the
+ * filesystem.
+ * @var string
+ */
+ var $sendmail_path = '/usr/sbin/sendmail';
+
+ /**
+ * Any extra command-line parameters to pass to the sendmail or
+ * sendmail wrapper binary.
+ * @var string
+ */
+ var $sendmail_args = '-i';
+
+ /**
+ * Constructor.
+ *
+ * Instantiates a new Mail_sendmail:: object based on the parameters
+ * passed in. It looks for the following parameters:
+ * sendmail_path The location of the sendmail binary on the
+ * filesystem. Defaults to '/usr/sbin/sendmail'.
+ *
+ * sendmail_args Any extra parameters to pass to the sendmail
+ * or sendmail wrapper binary.
+ *
+ * If a parameter is present in the $params array, it replaces the
+ * default.
+ *
+ * @param array $params Hash containing any parameters different from the
+ * defaults.
+ */
+ public function __construct($params)
+ {
+ if (isset($params['sendmail_path'])) {
+ $this->sendmail_path = $params['sendmail_path'];
+ }
+ if (isset($params['sendmail_args'])) {
+ $this->sendmail_args = $params['sendmail_args'];
+ }
+
+ /*
+ * Because we need to pass message headers to the sendmail program on
+ * the commandline, we can't guarantee the use of the standard "\r\n"
+ * separator. Instead, we use the system's native line separator.
+ */
+ if (defined('PHP_EOL')) {
+ $this->sep = PHP_EOL;
+ } else {
+ $this->sep = (strpos(PHP_OS, 'WIN') === false) ? "\n" : "\r\n";
+ }
+ }
+
+ /**
+ * Implements Mail::send() function using the sendmail
+ * command-line binary.
+ *
+ * @param mixed $recipients Either a comma-seperated list of recipients
+ * (RFC822 compliant), or an array of recipients,
+ * each RFC822 valid. This may contain recipients not
+ * specified in the headers, for Bcc:, resending
+ * messages, etc.
+ *
+ * @param array $headers The array of headers to send with the mail, in an
+ * associative array, where the array key is the
+ * header name (ie, 'Subject'), and the array value
+ * is the header value (ie, 'test'). The header
+ * produced from those values would be 'Subject:
+ * test'.
+ *
+ * @param string $body The full text of the message body, including any
+ * Mime parts, etc.
+ *
+ * @return mixed Returns true on success, or a PEAR_Error
+ * containing a descriptive error message on
+ * failure.
+ */
+ public function send($recipients, $headers, $body)
+ {
+ if (!is_array($headers)) {
+ return PEAR::raiseError('$headers must be an array');
+ }
+
+ $result = $this->_sanitizeHeaders($headers);
+ if (is_a($result, 'PEAR_Error')) {
+ return $result;
+ }
+
+ $recipients = $this->parseRecipients($recipients);
+ if (is_a($recipients, 'PEAR_Error')) {
+ return $recipients;
+ }
+ $recipients = implode(' ', array_map('escapeshellarg', $recipients));
+
+ $headerElements = $this->prepareHeaders($headers);
+ if (is_a($headerElements, 'PEAR_Error')) {
+ return $headerElements;
+ }
+ list($from, $text_headers) = $headerElements;
+
+ /* Since few MTAs are going to allow this header to be forged
+ * unless it's in the MAIL FROM: exchange, we'll use
+ * Return-Path instead of From: if it's set. */
+ if (!empty($headers['Return-Path'])) {
+ $from = $headers['Return-Path'];
+ }
+
+ if (!isset($from)) {
+ return PEAR::raiseError('No from address given.');
+ } elseif (strpos($from, ' ') !== false ||
+ strpos($from, ';') !== false ||
+ strpos($from, '&') !== false ||
+ strpos($from, '`') !== false) {
+ return PEAR::raiseError('From address specified with dangerous characters.');
+ }
+
+ $from = escapeshellarg($from); // Security bug #16200
+
+ $mail = @popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$from -- $recipients", 'w');
+ if (!$mail) {
+ return PEAR::raiseError('Failed to open sendmail [' . $this->sendmail_path . '] for execution.');
+ }
+
+ // Write the headers following by two newlines: one to end the headers
+ // section and a second to separate the headers block from the body.
+ fputs($mail, $text_headers . $this->sep . $this->sep);
+
+ fputs($mail, $body);
+ $result = pclose($mail);
+ if (version_compare(phpversion(), '4.2.3') == -1) {
+ // With older php versions, we need to shift the pclose
+ // result to get the exit code.
+ $result = $result >> 8 & 0xFF;
+ }
+
+ if ($result != 0) {
+ return PEAR::raiseError('sendmail returned error code ' . $result,
+ $result);
+ }
+
+ return true;
+ }
+
+}
diff --git a/WEB-INF/lib/pear/Mail/smtp.php b/WEB-INF/lib/pear/Mail/smtp.php
old mode 100644
new mode 100755
index d446b1bcd..8d3181891
--- a/WEB-INF/lib/pear/Mail/smtp.php
+++ b/WEB-INF/lib/pear/Mail/smtp.php
@@ -1,441 +1,562 @@
-
- * @author Chuck Hagenbuch
- * @copyright 2010 Chuck Hagenbuch
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id$
- * @link http://pear.php.net/package/Mail/
- */
-
-/** Error: Failed to create a Net_SMTP object */
-define('PEAR_MAIL_SMTP_ERROR_CREATE', 10000);
-
-/** Error: Failed to connect to SMTP server */
-define('PEAR_MAIL_SMTP_ERROR_CONNECT', 10001);
-
-/** Error: SMTP authentication failure */
-define('PEAR_MAIL_SMTP_ERROR_AUTH', 10002);
-
-/** Error: No From: address has been provided */
-define('PEAR_MAIL_SMTP_ERROR_FROM', 10003);
-
-/** Error: Failed to set sender */
-define('PEAR_MAIL_SMTP_ERROR_SENDER', 10004);
-
-/** Error: Failed to add recipient */
-define('PEAR_MAIL_SMTP_ERROR_RECIPIENT', 10005);
-
-/** Error: Failed to send data */
-define('PEAR_MAIL_SMTP_ERROR_DATA', 10006);
-
-/**
- * SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class.
- * @access public
- * @package Mail
- * @version $Revision$
- */
-class Mail_smtp extends Mail {
-
- /**
- * SMTP connection object.
- *
- * @var object
- * @access private
- */
- var $_smtp = null;
-
- /**
- * The list of service extension parameters to pass to the Net_SMTP
- * mailFrom() command.
- * @var array
- */
- var $_extparams = array();
-
- /**
- * The SMTP host to connect to.
- * @var string
- */
- var $host = 'localhost';
-
- /**
- * The port the SMTP server is on.
- * @var integer
- */
- var $port = 25;
-
- /**
- * Should SMTP authentication be used?
- *
- * This value may be set to true, false or the name of a specific
- * authentication method.
- *
- * If the value is set to true, the Net_SMTP package will attempt to use
- * the best authentication method advertised by the remote SMTP server.
- *
- * @var mixed
- */
- var $auth = false;
-
- /**
- * The username to use if the SMTP server requires authentication.
- * @var string
- */
- var $username = '';
-
- /**
- * The password to use if the SMTP server requires authentication.
- * @var string
- */
- var $password = '';
-
- /**
- * Hostname or domain that will be sent to the remote SMTP server in the
- * HELO / EHLO message.
- *
- * @var string
- */
- var $localhost = 'localhost';
-
- /**
- * SMTP connection timeout value. NULL indicates no timeout.
- *
- * @var integer
- */
- var $timeout = null;
-
- /**
- * Turn on Net_SMTP debugging?
- *
- * @var boolean $debug
- */
- var $debug = false;
-
- /**
- * Indicates whether or not the SMTP connection should persist over
- * multiple calls to the send() method.
- *
- * @var boolean
- */
- var $persist = false;
-
- /**
- * Use SMTP command pipelining (specified in RFC 2920) if the SMTP server
- * supports it. This speeds up delivery over high-latency connections. By
- * default, use the default value supplied by Net_SMTP.
- * @var bool
- */
- var $pipelining;
-
- var $socket_options = array();
-
- /**
- * Constructor.
- *
- * Instantiates a new Mail_smtp:: object based on the parameters
- * passed in. It looks for the following parameters:
- * host The server to connect to. Defaults to localhost.
- * port The port to connect to. Defaults to 25.
- * auth SMTP authentication. Defaults to none.
- * username The username to use for SMTP auth. No default.
- * password The password to use for SMTP auth. No default.
- * localhost The local hostname / domain. Defaults to localhost.
- * timeout The SMTP connection timeout. Defaults to none.
- * verp Whether to use VERP or not. Defaults to false.
- * DEPRECATED as of 1.2.0 (use setMailParams()).
- * debug Activate SMTP debug mode? Defaults to false.
- * persist Should the SMTP connection persist?
- * pipelining Use SMTP command pipelining
- *
- * If a parameter is present in the $params array, it replaces the
- * default.
- *
- * @param array Hash containing any parameters different from the
- * defaults.
- */
- public function __construct($params)
- {
- if (isset($params['host'])) $this->host = $params['host'];
- if (isset($params['port'])) $this->port = $params['port'];
- if (isset($params['auth'])) $this->auth = $params['auth'];
- if (isset($params['username'])) $this->username = $params['username'];
- if (isset($params['password'])) $this->password = $params['password'];
- if (isset($params['localhost'])) $this->localhost = $params['localhost'];
- if (isset($params['timeout'])) $this->timeout = $params['timeout'];
- if (isset($params['debug'])) $this->debug = (bool)$params['debug'];
- if (isset($params['persist'])) $this->persist = (bool)$params['persist'];
- if (isset($params['pipelining'])) $this->pipelining = (bool)$params['pipelining'];
- if (isset($params['socket_options'])) $this->socket_options = $params['socket_options'];
- // Deprecated options
- if (isset($params['verp'])) {
- $this->addServiceExtensionParameter('XVERP', is_bool($params['verp']) ? null : $params['verp']);
- }
- }
-
- /**
- * Destructor implementation to ensure that we disconnect from any
- * potentially-alive persistent SMTP connections.
- */
- public function __destruct()
- {
- $this->disconnect();
- }
-
- /**
- * Implements Mail::send() function using SMTP.
- *
- * @param mixed $recipients Either a comma-seperated list of recipients
- * (RFC822 compliant), or an array of recipients,
- * each RFC822 valid. This may contain recipients not
- * specified in the headers, for Bcc:, resending
- * messages, etc.
- *
- * @param array $headers The array of headers to send with the mail, in an
- * associative array, where the array key is the
- * header name (e.g., 'Subject'), and the array value
- * is the header value (e.g., 'test'). The header
- * produced from those values would be 'Subject:
- * test'.
- *
- * @param string $body The full text of the message body, including any
- * MIME parts, etc.
- *
- * @return mixed Returns true on success, or a PEAR_Error
- * containing a descriptive error message on
- * failure.
- */
- public function send($recipients, $headers, $body)
- {
- /* If we don't already have an SMTP object, create one. */
- $result = $this->getSMTPObject();
- if (PEAR::isError($result)) {
- return $result;
- }
-
- if (!is_array($headers)) {
- return PEAR::raiseError('$headers must be an array');
- }
-
- $this->_sanitizeHeaders($headers);
-
- $headerElements = $this->prepareHeaders($headers);
- if (is_a($headerElements, 'PEAR_Error')) {
- $this->_smtp->rset();
- return $headerElements;
- }
- list($from, $textHeaders) = $headerElements;
-
- /* Since few MTAs are going to allow this header to be forged
- * unless it's in the MAIL FROM: exchange, we'll use
- * Return-Path instead of From: if it's set. */
- if (!empty($headers['Return-Path'])) {
- $from = $headers['Return-Path'];
- }
-
- if (!isset($from)) {
- $this->_smtp->rset();
- return PEAR::raiseError('No From: address has been provided',
- PEAR_MAIL_SMTP_ERROR_FROM);
- }
-
- $params = null;
- if (!empty($this->_extparams)) {
- foreach ($this->_extparams as $key => $val) {
- $params .= ' ' . $key . (is_null($val) ? '' : '=' . $val);
- }
- }
- if (PEAR::isError($res = $this->_smtp->mailFrom($from, ltrim($params)))) {
- $error = $this->_error("Failed to set sender: $from", $res);
- $this->_smtp->rset();
- return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_SENDER);
- }
-
- $recipients = $this->parseRecipients($recipients);
- if (is_a($recipients, 'PEAR_Error')) {
- $this->_smtp->rset();
- return $recipients;
- }
-
- foreach ($recipients as $recipient) {
- $res = $this->_smtp->rcptTo($recipient);
- if (is_a($res, 'PEAR_Error')) {
- $error = $this->_error("Failed to add recipient: $recipient", $res);
- $this->_smtp->rset();
- return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_RECIPIENT);
- }
- }
-
- /* Send the message's headers and the body as SMTP data. */
- $res = $this->_smtp->data($body, $textHeaders);
- list(,$args) = $this->_smtp->getResponse();
-
- if (preg_match("/Ok: queued as (.*)/", $args, $queued)) {
- $this->queued_as = $queued[1];
- }
-
- /* we need the greeting; from it we can extract the authorative name of the mail server we've really connected to.
- * ideal if we're connecting to a round-robin of relay servers and need to track which exact one took the email */
- $this->greeting = $this->_smtp->getGreeting();
-
- if (is_a($res, 'PEAR_Error')) {
- $error = $this->_error('Failed to send data', $res);
- $this->_smtp->rset();
- return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_DATA);
- }
-
- /* If persistent connections are disabled, destroy our SMTP object. */
- if ($this->persist === false) {
- $this->disconnect();
- }
-
- return true;
- }
-
- /**
- * Connect to the SMTP server by instantiating a Net_SMTP object.
- *
- * @return mixed Returns a reference to the Net_SMTP object on success, or
- * a PEAR_Error containing a descriptive error message on
- * failure.
- *
- * @since 1.2.0
- */
- public function getSMTPObject()
- {
- if (is_object($this->_smtp) !== false) {
- return $this->_smtp;
- }
-
- include_once 'Net/SMTP.php';
- $this->_smtp = new Net_SMTP($this->host,
- $this->port,
- $this->localhost,
- $this->pipelining,
- 0,
- $this->socket_options);
-
- /* If we still don't have an SMTP object at this point, fail. */
- if (is_object($this->_smtp) === false) {
- return PEAR::raiseError('Failed to create a Net_SMTP object',
- PEAR_MAIL_SMTP_ERROR_CREATE);
- }
-
- /* Configure the SMTP connection. */
- if ($this->debug) {
- $this->_smtp->setDebug(true);
- }
-
- /* Attempt to connect to the configured SMTP server. */
- if (PEAR::isError($res = $this->_smtp->connect($this->timeout))) {
- $error = $this->_error('Failed to connect to ' .
- $this->host . ':' . $this->port,
- $res);
- return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_CONNECT);
- }
-
- /* Attempt to authenticate if authentication has been enabled. */
- if ($this->auth) {
- $method = is_string($this->auth) ? $this->auth : '';
-
- if (PEAR::isError($res = $this->_smtp->auth($this->username,
- $this->password,
- $method))) {
- $error = $this->_error("$method authentication failure",
- $res);
- $this->_smtp->rset();
- return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_AUTH);
- }
- }
-
- return $this->_smtp;
- }
-
- /**
- * Add parameter associated with a SMTP service extension.
- *
- * @param string Extension keyword.
- * @param string Any value the keyword needs.
- *
- * @since 1.2.0
- */
- public function addServiceExtensionParameter($keyword, $value = null)
- {
- $this->_extparams[$keyword] = $value;
- }
-
- /**
- * Disconnect and destroy the current SMTP connection.
- *
- * @return boolean True if the SMTP connection no longer exists.
- *
- * @since 1.1.9
- */
- public function disconnect()
- {
- /* If we have an SMTP object, disconnect and destroy it. */
- if (is_object($this->_smtp) && $this->_smtp->disconnect()) {
- $this->_smtp = null;
- }
-
- /* We are disconnected if we no longer have an SMTP object. */
- return ($this->_smtp === null);
- }
-
- /**
- * Build a standardized string describing the current SMTP error.
- *
- * @param string $text Custom string describing the error context.
- * @param object $error Reference to the current PEAR_Error object.
- *
- * @return string A string describing the current SMTP error.
- *
- * @since 1.1.7
- */
- protected function _error($text, $error)
- {
- /* Split the SMTP response into a code and a response string. */
- list($code, $response) = $this->_smtp->getResponse();
-
- /* Build our standardized error string. */
- return $text
- . ' [SMTP: ' . $error->getMessage()
- . " (code: $code, response: $response)]";
- }
-
-}
+
+ * @author Chuck Hagenbuch
+ * @copyright 2010-2021 Chuck Hagenbuch
+ * @license http://opensource.org/licenses/BSD-3-Clause New BSD License
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/Mail/
+ */
+
+/** Error: Failed to create a Net_SMTP object */
+define('PEAR_MAIL_SMTP_ERROR_CREATE', 10000);
+
+/** Error: Failed to connect to SMTP server */
+define('PEAR_MAIL_SMTP_ERROR_CONNECT', 10001);
+
+/** Error: SMTP authentication failure */
+define('PEAR_MAIL_SMTP_ERROR_AUTH', 10002);
+
+/** Error: No From: address has been provided */
+define('PEAR_MAIL_SMTP_ERROR_FROM', 10003);
+
+/** Error: Failed to set sender */
+define('PEAR_MAIL_SMTP_ERROR_SENDER', 10004);
+
+/** Error: Failed to add recipient */
+define('PEAR_MAIL_SMTP_ERROR_RECIPIENT', 10005);
+
+/** Error: Failed to send data */
+define('PEAR_MAIL_SMTP_ERROR_DATA', 10006);
+
+/**
+ * SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class.
+ * @access public
+ * @package Mail
+ * @version $Revision$
+ */
+class Mail_smtp extends Mail {
+
+ /**
+ * SMTP connection object.
+ *
+ * @var object
+ * @access private
+ */
+ var $_smtp = null;
+
+ /**
+ * The list of service extension parameters to pass to the Net_SMTP
+ * mailFrom() command.
+ *
+ * @var array
+ */
+ var $_extparams = array();
+
+ /**
+ * The SMTP host to connect to.
+ *
+ * @var string
+ */
+ var $host = 'localhost';
+
+ /**
+ * The port the SMTP server is on.
+ *
+ * @var integer
+ */
+ var $port = 25;
+
+ /**
+ * Should STARTTLS connection be used?
+ *
+ * This value may be set to true or false.
+ *
+ * If the value is set to true, the Net_SMTP package will attempt to use
+ * a STARTTLS encrypted connection.
+ *
+ * If the value is set to false, the Net_SMTP package will avoid
+ * a STARTTLS encrypted connection.
+ *
+ * NULL indicates only STARTTLS if $auth is set.
+ *
+ * PEAR/Net_SMTP >= 1.10.0 required.
+ *
+ * @var boolean
+ */
+ var $starttls = null;
+
+ /**
+ * Should SMTP authentication be used?
+ *
+ * This value may be set to true, false or the name of a specific
+ * authentication method.
+ *
+ * If the value is set to true, the Net_SMTP package will attempt to use
+ * the best authentication method advertised by the remote SMTP server.
+ *
+ * @var mixed
+ */
+ var $auth = false;
+
+ /**
+ * The username to use if the SMTP server requires authentication.
+ *
+ * @var string
+ */
+ var $username = '';
+
+ /**
+ * The password to use if the SMTP server requires authentication.
+ *
+ * @var string
+ */
+ var $password = '';
+
+ /**
+ * Hostname or domain that will be sent to the remote SMTP server in the
+ * HELO / EHLO message.
+ *
+ * @var string
+ */
+ var $localhost = 'localhost';
+
+ /**
+ * SMTP connection timeout value. NULL indicates no timeout.
+ *
+ * @var integer
+ */
+ var $timeout = null;
+
+ /**
+ * Turn on Net_SMTP debugging?
+ *
+ * @var boolean $debug
+ */
+ var $debug = false;
+
+ /**
+ * Set debug_handler on Net_SMTP
+ *
+ * @var callable $debug_handler
+ */
+ var $debug_handler = null;
+
+ /**
+ * we need the greeting; from it we can extract the authorative name of the mail
+ * server we've really connected to. ideal if we're connecting to a round-robin
+ * of relay servers and need to track which exact one took the email
+ *
+ * @var string
+ */
+ var $greeting = null;
+
+ /**
+ * Indicates whether or not the SMTP connection should persist over
+ * multiple calls to the send() method.
+ *
+ * @var boolean
+ */
+ var $persist = false;
+
+ /**
+ * Use SMTP command pipelining (specified in RFC 2920) if the SMTP server
+ * supports it. This speeds up delivery over high-latency connections. By
+ * default, use the default value supplied by Net_SMTP.
+ *
+ * @var boolean
+ */
+ var $pipelining;
+
+ /**
+ * The list of socket options
+ *
+ * @var array
+ */
+ var $socket_options = array();
+
+ /**
+ * SMTP response message
+ *
+ * @var string
+ * @since 1.6.0
+ */
+ var $response = null;
+
+ /**
+ * If the message ends up in the queue, on the recipient server,
+ * the response will be saved here.
+ * Some successfully delivered emails will include a “queued”
+ * notation in the SMTP response, such as "250 OK; queued as 12345".
+ * This indicates that the email was delivered to the recipient
+ * as expected, but may require additional processing before it
+ * lands in the recipient’s inbox.
+ *
+ * @var string
+ */
+ var $queued_as = null;
+
+ /**
+ * Constructor.
+ *
+ * Instantiates a new Mail_smtp:: object based on the parameters
+ * passed in. It looks for the following parameters:
+ * host The server to connect to. Defaults to localhost.
+ * port The port to connect to. Defaults to 25.
+ * auth SMTP authentication. Defaults to none.
+ * starttls Should STARTTLS connection be used? No default. PEAR/Net_SMTP >= 1.10.0 required.
+ * username The username to use for SMTP auth. No default.
+ * password The password to use for SMTP auth. No default.
+ * localhost The local hostname / domain. Defaults to localhost.
+ * timeout The SMTP connection timeout. Defaults to none.
+ * verp Whether to use VERP or not. Defaults to false.
+ * DEPRECATED as of 1.2.0 (use setMailParams()).
+ * debug Activate SMTP debug mode? Defaults to false.
+ * debug_handler Set SMTP debug handler function. Defaults to null.
+ * persist Should the SMTP connection persist?
+ * pipelining Use SMTP command pipelining
+ * socket_options Socket stream_context_create() options.
+ *
+ * If a parameter is present in the $params array, it replaces the
+ * default.
+ *
+ * @param array Hash containing any parameters different from the
+ * defaults.
+ */
+ public function __construct($params)
+ {
+ if (isset($params['host'])) $this->host = $params['host'];
+ if (isset($params['port'])) $this->port = $params['port'];
+ if (isset($params['auth'])) $this->auth = $params['auth'];
+ if (isset($params['starttls'])) $this->starttls = $params['starttls'];
+ if (isset($params['username'])) $this->username = $params['username'];
+ if (isset($params['password'])) $this->password = $params['password'];
+ if (isset($params['localhost'])) $this->localhost = $params['localhost'];
+ if (isset($params['timeout'])) $this->timeout = $params['timeout'];
+ if (isset($params['debug'])) $this->debug = (bool)$params['debug'];
+ if (isset($params['debug_handler'])) $this->debug_handler = $params['debug_handler'];
+ if (isset($params['persist'])) $this->persist = (bool)$params['persist'];
+ if (isset($params['pipelining'])) $this->pipelining = (bool)$params['pipelining'];
+ if (isset($params['socket_options'])) $this->socket_options = $params['socket_options'];
+ // Deprecated options
+ if (isset($params['verp'])) {
+ $this->addServiceExtensionParameter('XVERP', is_bool($params['verp']) ? null : $params['verp']);
+ }
+ }
+
+ /**
+ * Destructor implementation to ensure that we disconnect from any
+ * potentially-alive persistent SMTP connections.
+ */
+ public function __destruct()
+ {
+ $this->disconnect();
+ }
+
+ /**
+ * Implements Mail::send() function using SMTP.
+ *
+ * @param mixed $recipients Either a comma-seperated list of recipients
+ * (RFC822 compliant), or an array of recipients,
+ * each RFC822 valid. This may contain recipients not
+ * specified in the headers, for Bcc:, resending
+ * messages, etc.
+ *
+ * @param array $headers The array of headers to send with the mail, in an
+ * associative array, where the array key is the
+ * header name (e.g., 'Subject'), and the array value
+ * is the header value (e.g., 'test'). The header
+ * produced from those values would be 'Subject:
+ * test'.
+ *
+ * @param string $body The full text of the message body, including any
+ * MIME parts, etc.
+ *
+ * @return mixed Returns true on success, or a PEAR_Error
+ * containing a descriptive error message on
+ * failure.
+ */
+ public function send($recipients, $headers, $body)
+ {
+ $result = $this->send_or_fail($recipients, $headers, $body);
+
+ /* If persistent connections are disabled, destroy our SMTP object. */
+ if ($this->persist === false) {
+ $this->disconnect();
+ }
+
+ return $result;
+ }
+
+ protected function send_or_fail($recipients, $headers, $body)
+ {
+ /* If we don't already have an SMTP object, create one. */
+ $result = $this->getSMTPObject();
+ if (PEAR::isError($result)) {
+ return $result;
+ }
+
+ if (!is_array($headers)) {
+ return PEAR::raiseError('$headers must be an array');
+ }
+
+ $this->_sanitizeHeaders($headers);
+
+ $headerElements = $this->prepareHeaders($headers);
+ if (is_a($headerElements, 'PEAR_Error')) {
+ $this->_smtp->rset();
+ return $headerElements;
+ }
+ list($from, $textHeaders) = $headerElements;
+
+ /* Since few MTAs are going to allow this header to be forged
+ * unless it's in the MAIL FROM: exchange, we'll use
+ * Return-Path instead of From: if it's set. */
+ if (!empty($headers['Return-Path'])) {
+ $from = $headers['Return-Path'];
+ }
+
+ if (!isset($from)) {
+ $this->_smtp->rset();
+ return PEAR::raiseError('No From: address has been provided',
+ PEAR_MAIL_SMTP_ERROR_FROM);
+ }
+
+ $params = '';
+ if (!empty($this->_extparams)) {
+ foreach ($this->_extparams as $key => $val) {
+ $params .= ' ' . $key . (is_null($val) ? '' : '=' . $val);
+ }
+ }
+ if (PEAR::isError($res = $this->_smtp->mailFrom($from, ltrim($params)))) {
+ $error = $this->_error("Failed to set sender: $from", $res);
+ $this->_smtp->rset();
+ return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_SENDER);
+ }
+
+ $recipients = $this->parseRecipients($recipients);
+ if (is_a($recipients, 'PEAR_Error')) {
+ $this->_smtp->rset();
+ return $recipients;
+ }
+
+ foreach ($recipients as $recipient) {
+ $res = $this->_smtp->rcptTo($recipient);
+ if (is_a($res, 'PEAR_Error')) {
+ $error = $this->_error("Failed to add recipient: $recipient", $res);
+ $this->_smtp->rset();
+ return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_RECIPIENT);
+ }
+ }
+
+ /* Send the message's headers and the body as SMTP data. */
+ $res = $this->_smtp->data($body, $textHeaders);
+
+ list($code, $args) = $this->_smtp->getResponse();
+
+ $this->response = $code . ' ' . $args;
+
+ if (preg_match("/ queued as (.*)/", $args, $queued)) {
+ $this->queued_as = $queued[1];
+ }
+
+ /* we need the greeting; from it we can extract the authorative name of the mail server we've really connected to.
+ * ideal if we're connecting to a round-robin of relay servers and need to track which exact one took the email */
+ $this->greeting = $this->_smtp->getGreeting();
+
+ if (is_a($res, 'PEAR_Error')) {
+ $error = $this->_error('Failed to send data', $res);
+ $this->_smtp->rset();
+ return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_DATA);
+ }
+
+ return true;
+ }
+
+ /**
+ * Connect to the SMTP server by instantiating a Net_SMTP object.
+ *
+ * @return mixed Returns a reference to the Net_SMTP object on success, or
+ * a PEAR_Error containing a descriptive error message on
+ * failure.
+ *
+ * @since 1.2.0
+ */
+ public function getSMTPObject()
+ {
+ if (is_object($this->_smtp) !== false) {
+ return $this->_smtp;
+ }
+
+ include_once 'Net/SMTP.php';
+ $this->_smtp = new Net_SMTP($this->host,
+ $this->port,
+ $this->localhost,
+ $this->pipelining,
+ 0,
+ $this->socket_options);
+
+ /* If we still don't have an SMTP object at this point, fail. */
+ if (is_object($this->_smtp) === false) {
+ return PEAR::raiseError('Failed to create a Net_SMTP object',
+ PEAR_MAIL_SMTP_ERROR_CREATE);
+ }
+
+ /* Configure the SMTP connection. */
+ if ($this->debug) {
+ $this->_smtp->setDebug(true, $this->debug_handler);
+ }
+
+ /* Attempt to connect to the configured SMTP server. */
+ if (PEAR::isError($res = $this->_smtp->connect($this->timeout))) {
+ $error = $this->_error('Failed to connect to ' .
+ $this->host . ':' . $this->port,
+ $res);
+ return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_CONNECT);
+ }
+
+ /* Attempt to authenticate if authentication has been enabled. */
+ if ($this->auth) {
+ $method = is_string($this->auth) ? $this->auth : '';
+
+ $tls = $this->starttls === false ? false : true;
+
+ if (PEAR::isError($res = $this->_smtp->auth($this->username,
+ $this->password,
+ $method,
+ $tls))) {
+ $error = $this->_error("$method authentication failure",
+ $res);
+ $this->_smtp->rset();
+ return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_AUTH);
+ }
+ }
+
+ /* Attempt to establish a TLS encrypted connection. PEAR/Net_SMTP >= 1.10.0 required. */
+ if ($this->starttls && !$this->auth) {
+ $starttls = $this->_smtp->starttls();
+ if (PEAR::isError($starttls)) {
+ return PEAR::raiseError($starttls);
+ } elseif ($starttls === false) {
+ return PEAR::raiseError('STARTTLS failed');
+ }
+ }
+
+ return $this->_smtp;
+ }
+
+ /**
+ * Add parameter associated with a SMTP service extension.
+ *
+ * @param string Extension keyword.
+ * @param string Any value the keyword needs.
+ *
+ * @since 1.2.0
+ */
+ public function addServiceExtensionParameter($keyword, $value = null)
+ {
+ $this->_extparams[$keyword] = $value;
+ }
+
+ /**
+ * Disconnect and destroy the current SMTP connection.
+ *
+ * @return boolean True if the SMTP connection no longer exists.
+ *
+ * @since 1.1.9
+ */
+ public function disconnect()
+ {
+ /* If we have an SMTP object, disconnect and destroy it. */
+ if (is_object($this->_smtp) && $this->_smtp->disconnect()) {
+ $this->_smtp = null;
+ }
+
+ /* We are disconnected if we no longer have an SMTP object. */
+ return ($this->_smtp === null);
+ }
+
+ /**
+ * Returns the SMTP response message after sending.
+ *
+ * @return string SMTP response message or NULL.
+ *
+ * @since 1.6.0
+ */
+ public function getResponse()
+ {
+ return $this->response;
+ }
+
+ /**
+ * Returns the SMTP response message if includes "queue" after sending.
+ *
+ * @return string SMTP queue message or NULL.
+ *
+ * @since 1.6.0
+ */
+ public function getQueuedAs()
+ {
+ return $this->queued_as;
+ }
+
+ /**
+ * Build a standardized string describing the current SMTP error.
+ *
+ * @param string $text Custom string describing the error context.
+ * @param object $error Reference to the current PEAR_Error object.
+ *
+ * @return string A string describing the current SMTP error.
+ *
+ * @since 1.1.7
+ */
+ protected function _error($text, $error)
+ {
+ /* Split the SMTP response into a code and a response string. */
+ list($code, $response) = $this->_smtp->getResponse();
+
+ /* Build our standardized error string. */
+ return $text
+ . ' [SMTP: ' . $error->getMessage()
+ . " (code: $code, response: $response)]";
+ }
+
+}
diff --git a/WEB-INF/lib/pear/Mail/smtpmx.php b/WEB-INF/lib/pear/Mail/smtpmx.php
old mode 100644
new mode 100755
index 6eb8bec2e..5c63b5240
--- a/WEB-INF/lib/pear/Mail/smtpmx.php
+++ b/WEB-INF/lib/pear/Mail/smtpmx.php
@@ -1,502 +1,515 @@
-
- * @copyright 2010 gERD Schaufelberger
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id$
- * @link http://pear.php.net/package/Mail/
- */
-
-require_once 'Net/SMTP.php';
-
-/**
- * SMTP MX implementation of the PEAR Mail interface. Requires the Net_SMTP class.
- *
- *
- * @access public
- * @author gERD Schaufelberger
- * @package Mail
- * @version $Revision$
- */
-class Mail_smtpmx extends Mail {
-
- /**
- * SMTP connection object.
- *
- * @var object
- * @access private
- */
- var $_smtp = null;
-
- /**
- * The port the SMTP server is on.
- * @var integer
- * @see getservicebyname()
- */
- var $port = 25;
-
- /**
- * Hostname or domain that will be sent to the remote SMTP server in the
- * HELO / EHLO message.
- *
- * @var string
- * @see posix_uname()
- */
- var $mailname = 'localhost';
-
- /**
- * SMTP connection timeout value. NULL indicates no timeout.
- *
- * @var integer
- */
- var $timeout = 10;
-
- /**
- * use either PEAR:Net_DNS or getmxrr
- *
- * @var boolean
- */
- var $withNetDns = true;
-
- /**
- * PEAR:Net_DNS_Resolver
- *
- * @var object
- */
- var $resolver;
-
- /**
- * Whether to use VERP or not. If not a boolean, the string value
- * will be used as the VERP separators.
- *
- * @var mixed boolean or string
- */
- var $verp = false;
-
- /**
- * Whether to use VRFY or not.
- *
- * @var boolean $vrfy
- */
- var $vrfy = false;
-
- /**
- * Switch to test mode - don't send emails for real
- *
- * @var boolean $debug
- */
- var $test = false;
-
- /**
- * Turn on Net_SMTP debugging?
- *
- * @var boolean $peardebug
- */
- var $debug = false;
-
- /**
- * internal error codes
- *
- * translate internal error identifier to PEAR-Error codes and human
- * readable messages.
- *
- * @var boolean $debug
- * @todo as I need unique error-codes to identify what exactly went wrond
- * I did not use intergers as it should be. Instead I added a "namespace"
- * for each code. This avoids conflicts with error codes from different
- * classes. How can I use unique error codes and stay conform with PEAR?
- */
- var $errorCode = array(
- 'not_connected' => array(
- 'code' => 1,
- 'msg' => 'Could not connect to any mail server ({HOST}) at port {PORT} to send mail to {RCPT}.'
- ),
- 'failed_vrfy_rcpt' => array(
- 'code' => 2,
- 'msg' => 'Recipient "{RCPT}" could not be veryfied.'
- ),
- 'failed_set_from' => array(
- 'code' => 3,
- 'msg' => 'Failed to set sender: {FROM}.'
- ),
- 'failed_set_rcpt' => array(
- 'code' => 4,
- 'msg' => 'Failed to set recipient: {RCPT}.'
- ),
- 'failed_send_data' => array(
- 'code' => 5,
- 'msg' => 'Failed to send mail to: {RCPT}.'
- ),
- 'no_from' => array(
- 'code' => 5,
- 'msg' => 'No from address has be provided.'
- ),
- 'send_data' => array(
- 'code' => 7,
- 'msg' => 'Failed to create Net_SMTP object.'
- ),
- 'no_mx' => array(
- 'code' => 8,
- 'msg' => 'No MX-record for {RCPT} found.'
- ),
- 'no_resolver' => array(
- 'code' => 9,
- 'msg' => 'Could not start resolver! Install PEAR:Net_DNS or switch off "netdns"'
- ),
- 'failed_rset' => array(
- 'code' => 10,
- 'msg' => 'RSET command failed, SMTP-connection corrupt.'
- ),
- );
-
- /**
- * Constructor.
- *
- * Instantiates a new Mail_smtp:: object based on the parameters
- * passed in. It looks for the following parameters:
- * mailname The name of the local mail system (a valid hostname which matches the reverse lookup)
- * port smtp-port - the default comes from getservicebyname() and should work fine
- * timeout The SMTP connection timeout. Defaults to 30 seconds.
- * vrfy Whether to use VRFY or not. Defaults to false.
- * verp Whether to use VERP or not. Defaults to false.
- * test Activate test mode? Defaults to false.
- * debug Activate SMTP and Net_DNS debug mode? Defaults to false.
- * netdns whether to use PEAR:Net_DNS or the PHP build in function getmxrr, default is true
- *
- * If a parameter is present in the $params array, it replaces the
- * default.
- *
- * @access public
- * @param array Hash containing any parameters different from the
- * defaults.
- * @see _Mail_smtpmx()
- */
- function __construct($params)
- {
- if (isset($params['mailname'])) {
- $this->mailname = $params['mailname'];
- } else {
- // try to find a valid mailname
- if (function_exists('posix_uname')) {
- $uname = posix_uname();
- $this->mailname = $uname['nodename'];
- }
- }
-
- // port number
- if (isset($params['port'])) {
- $this->_port = $params['port'];
- } else {
- $this->_port = getservbyname('smtp', 'tcp');
- }
-
- if (isset($params['timeout'])) $this->timeout = $params['timeout'];
- if (isset($params['verp'])) $this->verp = $params['verp'];
- if (isset($params['test'])) $this->test = $params['test'];
- if (isset($params['peardebug'])) $this->test = $params['peardebug'];
- if (isset($params['netdns'])) $this->withNetDns = $params['netdns'];
- }
-
- /**
- * Constructor wrapper for PHP4
- *
- * @access public
- * @param array Hash containing any parameters different from the defaults
- * @see __construct()
- */
- function Mail_smtpmx($params)
- {
- $this->__construct($params);
- register_shutdown_function(array(&$this, '__destruct'));
- }
-
- /**
- * Destructor implementation to ensure that we disconnect from any
- * potentially-alive persistent SMTP connections.
- */
- function __destruct()
- {
- if (is_object($this->_smtp)) {
- $this->_smtp->disconnect();
- $this->_smtp = null;
- }
- }
-
- /**
- * Implements Mail::send() function using SMTP direct delivery
- *
- * @access public
- * @param mixed $recipients in RFC822 style or array
- * @param array $headers The array of headers to send with the mail.
- * @param string $body The full text of the message body,
- * @return mixed Returns true on success, or a PEAR_Error
- */
- function send($recipients, $headers, $body)
- {
- if (!is_array($headers)) {
- return PEAR::raiseError('$headers must be an array');
- }
-
- $result = $this->_sanitizeHeaders($headers);
- if (is_a($result, 'PEAR_Error')) {
- return $result;
- }
-
- // Prepare headers
- $headerElements = $this->prepareHeaders($headers);
- if (is_a($headerElements, 'PEAR_Error')) {
- return $headerElements;
- }
- list($from, $textHeaders) = $headerElements;
-
- // use 'Return-Path' if possible
- if (!empty($headers['Return-Path'])) {
- $from = $headers['Return-Path'];
- }
- if (!isset($from)) {
- return $this->_raiseError('no_from');
- }
-
- // Prepare recipients
- $recipients = $this->parseRecipients($recipients);
- if (is_a($recipients, 'PEAR_Error')) {
- return $recipients;
- }
-
- foreach ($recipients as $rcpt) {
- list($user, $host) = explode('@', $rcpt);
-
- $mx = $this->_getMx($host);
- if (is_a($mx, 'PEAR_Error')) {
- return $mx;
- }
-
- if (empty($mx)) {
- $info = array('rcpt' => $rcpt);
- return $this->_raiseError('no_mx', $info);
- }
-
- $connected = false;
- foreach ($mx as $mserver => $mpriority) {
- $this->_smtp = new Net_SMTP($mserver, $this->port, $this->mailname);
-
- // configure the SMTP connection.
- if ($this->debug) {
- $this->_smtp->setDebug(true);
- }
-
- // attempt to connect to the configured SMTP server.
- $res = $this->_smtp->connect($this->timeout);
- if (is_a($res, 'PEAR_Error')) {
- $this->_smtp = null;
- continue;
- }
-
- // connection established
- if ($res) {
- $connected = true;
- break;
- }
- }
-
- if (!$connected) {
- $info = array(
- 'host' => implode(', ', array_keys($mx)),
- 'port' => $this->port,
- 'rcpt' => $rcpt,
- );
- return $this->_raiseError('not_connected', $info);
- }
-
- // Verify recipient
- if ($this->vrfy) {
- $res = $this->_smtp->vrfy($rcpt);
- if (is_a($res, 'PEAR_Error')) {
- $info = array('rcpt' => $rcpt);
- return $this->_raiseError('failed_vrfy_rcpt', $info);
- }
- }
-
- // mail from:
- $args['verp'] = $this->verp;
- $res = $this->_smtp->mailFrom($from, $args);
- if (is_a($res, 'PEAR_Error')) {
- $info = array('from' => $from);
- return $this->_raiseError('failed_set_from', $info);
- }
-
- // rcpt to:
- $res = $this->_smtp->rcptTo($rcpt);
- if (is_a($res, 'PEAR_Error')) {
- $info = array('rcpt' => $rcpt);
- return $this->_raiseError('failed_set_rcpt', $info);
- }
-
- // Don't send anything in test mode
- if ($this->test) {
- $result = $this->_smtp->rset();
- $res = $this->_smtp->rset();
- if (is_a($res, 'PEAR_Error')) {
- return $this->_raiseError('failed_rset');
- }
-
- $this->_smtp->disconnect();
- $this->_smtp = null;
- return true;
- }
-
- // Send data
- $res = $this->_smtp->data($body, $textHeaders);
- if (is_a($res, 'PEAR_Error')) {
- $info = array('rcpt' => $rcpt);
- return $this->_raiseError('failed_send_data', $info);
- }
-
- $this->_smtp->disconnect();
- $this->_smtp = null;
- }
-
- return true;
- }
-
- /**
- * Recieve mx rexords for a spciefied host
- *
- * The MX records
- *
- * @access private
- * @param string $host mail host
- * @return mixed sorted
- */
- function _getMx($host)
- {
- $mx = array();
-
- if ($this->withNetDns) {
- $res = $this->_loadNetDns();
- if (is_a($res, 'PEAR_Error')) {
- return $res;
- }
-
- $response = $this->resolver->query($host, 'MX');
- if (!$response) {
- return false;
- }
-
- foreach ($response->answer as $rr) {
- if ($rr->type == 'MX') {
- $mx[$rr->exchange] = $rr->preference;
- }
- }
- } else {
- $mxHost = array();
- $mxWeight = array();
-
- if (!getmxrr($host, $mxHost, $mxWeight)) {
- return false;
- }
- for ($i = 0; $i < count($mxHost); ++$i) {
- $mx[$mxHost[$i]] = $mxWeight[$i];
- }
- }
-
- asort($mx);
- return $mx;
- }
-
- /**
- * initialize PEAR:Net_DNS_Resolver
- *
- * @access private
- * @return boolean true on success
- */
- function _loadNetDns()
- {
- if (is_object($this->resolver)) {
- return true;
- }
-
- if (!include_once 'Net/DNS.php') {
- return $this->_raiseError('no_resolver');
- }
-
- $this->resolver = new Net_DNS_Resolver();
- if ($this->debug) {
- $this->resolver->test = 1;
- }
-
- return true;
- }
-
- /**
- * raise standardized error
- *
- * include additional information in error message
- *
- * @access private
- * @param string $id maps error ids to codes and message
- * @param array $info optional information in associative array
- * @see _errorCode
- */
- function _raiseError($id, $info = array())
- {
- $code = $this->errorCode[$id]['code'];
- $msg = $this->errorCode[$id]['msg'];
-
- // include info to messages
- if (!empty($info)) {
- $search = array();
- $replace = array();
-
- foreach ($info as $key => $value) {
- array_push($search, '{' . strtoupper($key) . '}');
- array_push($replace, $value);
- }
-
- $msg = str_replace($search, $replace, $msg);
- }
-
- return PEAR::raiseError($msg, $code);
- }
-
-}
+
+ * @copyright 2010-2017 gERD Schaufelberger
+ * @license http://opensource.org/licenses/BSD-3-Clause New BSD License
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/Mail/
+ */
+
+require_once 'Net/SMTP.php';
+
+/**
+ * SMTP MX implementation of the PEAR Mail interface. Requires the Net_SMTP class.
+ *
+ *
+ * @access public
+ * @author gERD Schaufelberger
+ * @package Mail
+ * @version $Revision$
+ */
+class Mail_smtpmx extends Mail {
+
+ /**
+ * SMTP connection object.
+ *
+ * @var object
+ * @access private
+ */
+ var $_smtp = null;
+
+ /**
+ * The port the SMTP server is on.
+ * @var integer
+ * @see getservicebyname()
+ */
+ var $port = 25;
+
+ /**
+ * Hostname or domain that will be sent to the remote SMTP server in the
+ * HELO / EHLO message.
+ *
+ * @var string
+ * @see posix_uname()
+ */
+ var $mailname = 'localhost';
+
+ /**
+ * SMTP connection timeout value. NULL indicates no timeout.
+ *
+ * @var integer
+ */
+ var $timeout = 10;
+
+ /**
+ * use either PEAR:Net_DNS or getmxrr
+ *
+ * @var boolean
+ */
+ var $withNetDns = true;
+
+ /**
+ * PEAR:Net_DNS_Resolver
+ *
+ * @var object
+ */
+ var $resolver;
+
+ /**
+ * Whether to use VERP or not. If not a boolean, the string value
+ * will be used as the VERP separators.
+ *
+ * @var mixed boolean or string
+ */
+ var $verp = false;
+
+ /**
+ * Whether to use VRFY or not.
+ *
+ * @var boolean $vrfy
+ */
+ var $vrfy = false;
+
+ /**
+ * Switch to test mode - don't send emails for real
+ *
+ * @var boolean $test
+ */
+ var $test = false;
+
+ /**
+ * Turn on Net_SMTP debugging?
+ *
+ * @var boolean $debug
+ */
+ var $debug = false;
+
+ /**
+ * Set debug_handler on Net_SMTP
+ *
+ * @var string $debug_handler
+ */
+ var $debug_handler = null;
+
+ /**
+ * internal error codes
+ *
+ * translate internal error identifier to PEAR-Error codes and human
+ * readable messages.
+ *
+ * @var array $errorCode
+ * @todo as I need unique error-codes to identify what exactly went wrond
+ * I did not use intergers as it should be. Instead I added a "namespace"
+ * for each code. This avoids conflicts with error codes from different
+ * classes. How can I use unique error codes and stay conform with PEAR?
+ */
+ var $errorCode = array(
+ 'not_connected' => array(
+ 'code' => 1,
+ 'msg' => 'Could not connect to any mail server ({HOST}) at port {PORT} to send mail to {RCPT}.'
+ ),
+ 'failed_vrfy_rcpt' => array(
+ 'code' => 2,
+ 'msg' => 'Recipient "{RCPT}" could not be veryfied.'
+ ),
+ 'failed_set_from' => array(
+ 'code' => 3,
+ 'msg' => 'Failed to set sender: {FROM}.'
+ ),
+ 'failed_set_rcpt' => array(
+ 'code' => 4,
+ 'msg' => 'Failed to set recipient: {RCPT}.'
+ ),
+ 'failed_send_data' => array(
+ 'code' => 5,
+ 'msg' => 'Failed to send mail to: {RCPT}.'
+ ),
+ 'no_from' => array(
+ 'code' => 5,
+ 'msg' => 'No from address has be provided.'
+ ),
+ 'send_data' => array(
+ 'code' => 7,
+ 'msg' => 'Failed to create Net_SMTP object.'
+ ),
+ 'no_mx' => array(
+ 'code' => 8,
+ 'msg' => 'No MX-record for {RCPT} found.'
+ ),
+ 'no_resolver' => array(
+ 'code' => 9,
+ 'msg' => 'Could not start resolver! Install PEAR:Net_DNS or switch off "netdns"'
+ ),
+ 'failed_rset' => array(
+ 'code' => 10,
+ 'msg' => 'RSET command failed, SMTP-connection corrupt.'
+ ),
+ );
+
+ /**
+ * Constructor.
+ *
+ * Instantiates a new Mail_smtp:: object based on the parameters
+ * passed in. It looks for the following parameters:
+ * mailname The name of the local mail system (a valid hostname which matches the reverse lookup)
+ * port smtp-port - the default comes from getservicebyname() and should work fine
+ * timeout The SMTP connection timeout. Defaults to 30 seconds.
+ * vrfy Whether to use VRFY or not. Defaults to false.
+ * verp Whether to use VERP or not. Defaults to false.
+ * test Activate test mode? Defaults to false.
+ * debug Activate SMTP and Net_DNS debug mode? Defaults to false.
+ * debug_handler Set SMTP debug handler function. Defaults to null.
+ * netdns whether to use PEAR:Net_DNS or the PHP build in function getmxrr, default is true
+ *
+ * If a parameter is present in the $params array, it replaces the
+ * default.
+ *
+ * @access public
+ * @param array Hash containing any parameters different from the
+ * defaults.
+ * @see _Mail_smtpmx()
+ */
+ function __construct($params)
+ {
+ if (isset($params['mailname'])) {
+ $this->mailname = $params['mailname'];
+ } else {
+ // try to find a valid mailname
+ if (function_exists('posix_uname')) {
+ $uname = posix_uname();
+ $this->mailname = $uname['nodename'];
+ }
+ }
+
+ // port number
+ if (isset($params['port'])) {
+ $this->port = $params['port'];
+ } else {
+ $this->port = getservbyname('smtp', 'tcp');
+ }
+
+ if (isset($params['timeout'])) $this->timeout = $params['timeout'];
+ if (isset($params['vrfy'])) $this->vrfy = (bool)$params['vrfy'];
+ if (isset($params['verp'])) $this->verp = $params['verp'];
+ if (isset($params['test'])) $this->test = (bool)$params['test'];
+ if (isset($params['peardebug'])) $this->debug = (bool)$params['peardebug'];
+ if (isset($params['debug'])) $this->debug = (bool)$params['debug'];
+ if (isset($params['debug_handler'])) $this->debug_handler = $params['debug_handler'];
+ if (isset($params['netdns'])) $this->withNetDns = $params['netdns'];
+ }
+
+ /**
+ * Constructor wrapper for PHP4
+ *
+ * @access public
+ * @param array Hash containing any parameters different from the defaults
+ * @see __construct()
+ */
+ function Mail_smtpmx($params)
+ {
+ $this->__construct($params);
+ register_shutdown_function(array(&$this, '__destruct'));
+ }
+
+ /**
+ * Destructor implementation to ensure that we disconnect from any
+ * potentially-alive persistent SMTP connections.
+ */
+ function __destruct()
+ {
+ if (is_object($this->_smtp)) {
+ $this->_smtp->disconnect();
+ $this->_smtp = null;
+ }
+ }
+
+ /**
+ * Implements Mail::send() function using SMTP direct delivery
+ *
+ * @access public
+ * @param mixed $recipients in RFC822 style or array
+ * @param array $headers The array of headers to send with the mail.
+ * @param string $body The full text of the message body,
+ * @return mixed Returns true on success, or a PEAR_Error
+ */
+ function send($recipients, $headers, $body)
+ {
+ if (!is_array($headers)) {
+ return PEAR::raiseError('$headers must be an array');
+ }
+
+ $result = $this->_sanitizeHeaders($headers);
+ if (is_a($result, 'PEAR_Error')) {
+ return $result;
+ }
+
+ // Prepare headers
+ $headerElements = $this->prepareHeaders($headers);
+ if (is_a($headerElements, 'PEAR_Error')) {
+ return $headerElements;
+ }
+ list($from, $textHeaders) = $headerElements;
+
+ // use 'Return-Path' if possible
+ if (!empty($headers['Return-Path'])) {
+ $from = $headers['Return-Path'];
+ }
+ if (!isset($from)) {
+ return $this->_raiseError('no_from');
+ }
+
+ // Prepare recipients
+ $recipients = $this->parseRecipients($recipients);
+ if (is_a($recipients, 'PEAR_Error')) {
+ return $recipients;
+ }
+
+ foreach ($recipients as $rcpt) {
+ list($user, $host) = explode('@', $rcpt);
+
+ $mx = $this->_getMx($host);
+ if (is_a($mx, 'PEAR_Error')) {
+ return $mx;
+ }
+
+ if (empty($mx)) {
+ $info = array('rcpt' => $rcpt);
+ return $this->_raiseError('no_mx', $info);
+ }
+
+ $connected = false;
+ foreach ($mx as $mserver => $mpriority) {
+ $this->_smtp = new Net_SMTP($mserver, $this->port, $this->mailname);
+
+ // configure the SMTP connection.
+ if ($this->debug) {
+ $this->_smtp->setDebug(true, $this->debug_handler);
+ }
+
+ // attempt to connect to the configured SMTP server.
+ $res = $this->_smtp->connect($this->timeout);
+ if (is_a($res, 'PEAR_Error')) {
+ $this->_smtp = null;
+ continue;
+ }
+
+ // connection established
+ if ($res) {
+ $connected = true;
+ break;
+ }
+ }
+
+ if (!$connected) {
+ $info = array(
+ 'host' => implode(', ', array_keys($mx)),
+ 'port' => $this->port,
+ 'rcpt' => $rcpt,
+ );
+ return $this->_raiseError('not_connected', $info);
+ }
+
+ // Verify recipient
+ if ($this->vrfy) {
+ $res = $this->_smtp->vrfy($rcpt);
+ if (is_a($res, 'PEAR_Error')) {
+ $info = array('rcpt' => $rcpt);
+ return $this->_raiseError('failed_vrfy_rcpt', $info);
+ }
+ }
+
+ // mail from:
+ $args['verp'] = $this->verp;
+ $res = $this->_smtp->mailFrom($from, $args);
+ if (is_a($res, 'PEAR_Error')) {
+ $info = array('from' => $from);
+ return $this->_raiseError('failed_set_from', $info);
+ }
+
+ // rcpt to:
+ $res = $this->_smtp->rcptTo($rcpt);
+ if (is_a($res, 'PEAR_Error')) {
+ $info = array('rcpt' => $rcpt);
+ return $this->_raiseError('failed_set_rcpt', $info);
+ }
+
+ // Don't send anything in test mode
+ if ($this->test) {
+ $result = $this->_smtp->rset();
+ $res = $this->_smtp->rset();
+ if (is_a($res, 'PEAR_Error')) {
+ return $this->_raiseError('failed_rset');
+ }
+
+ $this->_smtp->disconnect();
+ $this->_smtp = null;
+ return true;
+ }
+
+ // Send data
+ $res = $this->_smtp->data($body, $textHeaders);
+ if (is_a($res, 'PEAR_Error')) {
+ $info = array('rcpt' => $rcpt);
+ return $this->_raiseError('failed_send_data', $info);
+ }
+
+ $this->_smtp->disconnect();
+ $this->_smtp = null;
+ }
+
+ return true;
+ }
+
+ /**
+ * Recieve mx rexords for a spciefied host
+ *
+ * The MX records
+ *
+ * @access private
+ * @param string $host mail host
+ * @return mixed sorted
+ */
+ function _getMx($host)
+ {
+ $mx = array();
+
+ if ($this->withNetDns) {
+ $res = $this->_loadNetDns();
+ if (is_a($res, 'PEAR_Error')) {
+ return $res;
+ }
+
+ $response = $this->resolver->query($host, 'MX');
+ if (!$response) {
+ return false;
+ }
+
+ foreach ($response->answer as $rr) {
+ if ($rr->type == 'MX') {
+ $mx[$rr->exchange] = $rr->preference;
+ }
+ }
+ } else {
+ $mxHost = array();
+ $mxWeight = array();
+
+ if (!getmxrr($host, $mxHost, $mxWeight)) {
+ return false;
+ }
+ for ($i = 0; $i < count($mxHost); ++$i) {
+ $mx[$mxHost[$i]] = $mxWeight[$i];
+ }
+ }
+
+ asort($mx);
+ return $mx;
+ }
+
+ /**
+ * initialize PEAR:Net_DNS_Resolver
+ *
+ * @access private
+ * @return boolean true on success
+ */
+ function _loadNetDns()
+ {
+ if (is_object($this->resolver)) {
+ return true;
+ }
+
+ if (!include_once 'Net/DNS.php') {
+ return $this->_raiseError('no_resolver');
+ }
+
+ $this->resolver = new Net_DNS_Resolver();
+ if ($this->debug) {
+ $this->resolver->debug = 1;
+ }
+
+ return true;
+ }
+
+ /**
+ * raise standardized error
+ *
+ * include additional information in error message
+ *
+ * @access private
+ * @param string $id maps error ids to codes and message
+ * @param array $info optional information in associative array
+ * @see _errorCode
+ */
+ function _raiseError($id, $info = array())
+ {
+ $code = $this->errorCode[$id]['code'];
+ $msg = $this->errorCode[$id]['msg'];
+
+ // include info to messages
+ if (!empty($info)) {
+ $search = array();
+ $replace = array();
+
+ foreach ($info as $key => $value) {
+ array_push($search, '{' . strtoupper($key) . '}');
+ array_push($replace, $value);
+ }
+
+ $msg = str_replace($search, $replace, $msg);
+ }
+
+ return PEAR::raiseError($msg, $code);
+ }
+
+}
diff --git a/WEB-INF/lib/pear/Net/SMTP.php b/WEB-INF/lib/pear/Net/SMTP.php
old mode 100644
new mode 100755
index dd822a565..a2ccaeb9f
--- a/WEB-INF/lib/pear/Net/SMTP.php
+++ b/WEB-INF/lib/pear/Net/SMTP.php
@@ -3,15 +3,33 @@
// +----------------------------------------------------------------------+
// | PHP Version 5 and 7 |
// +----------------------------------------------------------------------+
-// | Copyright (c) 1997-2015 Jon Parise and Chuck Hagenbuch |
-// +----------------------------------------------------------------------+
-// | This source file is subject to version 3.01 of the PHP license, |
-// | that is bundled with this package in the file LICENSE, and is |
-// | available at through the world-wide-web at |
-// | http://www.php.net/license/3_01.txt. |
-// | If you did not receive a copy of the PHP license and are unable to |
-// | obtain it through the world-wide-web, please send a note to |
-// | license@php.net so we can mail you a copy immediately. |
+// | Copyright (c) 1997-2021 Jon Parise and Chuck Hagenbuch |
+// | All rights reserved. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | 1. Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | |
+// | 2. Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in |
+// | the documentation and/or other materials provided with the |
+// | distribution. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
+// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
+// | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
+// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
+// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
+// | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
+// | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
+// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
+// | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
+// | POSSIBILITY OF SUCH DAMAGE. |
// +----------------------------------------------------------------------+
// | Authors: Chuck Hagenbuch |
// | Jon Parise |
@@ -29,6 +47,7 @@
* @author Chuck Hagenbuch
* @author Jon Parise
* @author Damian Alejandro Fernandez Sosa
+ * @license http://opensource.org/licenses/bsd-license.php BSD-2-Clause
*
* @example basic.php A basic implementation of the Net_SMTP package.
*/
@@ -131,6 +150,25 @@ class Net_SMTP
*/
protected $esmtp = array();
+ /**
+ * GSSAPI principal.
+ * @var string
+ */
+ protected $gssapi_principal = null;
+
+ /**
+ * GSSAPI principal.
+ * @var string
+ */
+ protected $gssapi_cname = null;
+
+ /**
+ * SCRAM SHA-Hash algorithm.
+ *
+ * @var string
+ */
+ protected $scram_sha_hash_algorithm = null;
+
/**
* Instantiates a new Net_SMTP object, overriding any defaults
* with parameters that are passed in.
@@ -142,17 +180,20 @@ class Net_SMTP
* $smtp = new Net_SMTP('ssl://mail.host.com', 465);
* $smtp->connect();
*
- * @param string $host The server to connect to.
- * @param integer $port The port to connect to.
- * @param string $localhost The value to give when sending EHLO or HELO.
- * @param boolean $pipelining Use SMTP command pipelining
- * @param integer $timeout Socket I/O timeout in seconds.
- * @param array $socket_options Socket stream_context_create() options.
+ * @param string $host The server to connect to.
+ * @param integer $port The port to connect to.
+ * @param string $localhost The value to give when sending EHLO or HELO.
+ * @param boolean $pipelining Use SMTP command pipelining
+ * @param integer $timeout Socket I/O timeout in seconds.
+ * @param array $socket_options Socket stream_context_create() options.
+ * @param string $gssapi_principal GSSAPI service principal name
+ * @param string $gssapi_cname GSSAPI credentials cache
*
* @since 1.0
*/
public function __construct($host = null, $port = null, $localhost = null,
- $pipelining = false, $timeout = 0, $socket_options = null
+ $pipelining = false, $timeout = 0, $socket_options = null,
+ $gssapi_principal = null, $gssapi_cname = null
) {
if (isset($host)) {
$this->host = $host;
@@ -164,21 +205,35 @@ public function __construct($host = null, $port = null, $localhost = null,
$this->localhost = $localhost;
}
- $this->pipelining = $pipelining;
- $this->socket = new Net_Socket();
- $this->socket_options = $socket_options;
- $this->timeout = $timeout;
+ $this->pipelining = $pipelining;
+ $this->socket = new Net_Socket();
+ $this->socket_options = $socket_options;
+ $this->timeout = $timeout;
+ $this->gssapi_principal = $gssapi_principal;
+ $this->gssapi_cname = $gssapi_cname;
+
+ /* If PHP krb5 extension is loaded, we enable GSSAPI method. */
+ if (isset($gssapi_principal) && extension_loaded('krb5')) {
+ $this->setAuthMethod('GSSAPI', array($this, 'authGSSAPI'));
+ }
/* Include the Auth_SASL package. If the package is available, we
* enable the authentication methods that depend upon it. */
if (@include_once 'Auth/SASL.php') {
$this->setAuthMethod('CRAM-MD5', array($this, 'authCramMD5'));
$this->setAuthMethod('DIGEST-MD5', array($this, 'authDigestMD5'));
+ $this->setAuthMethod('SCRAM-SHA-1', array($this, 'authScramSHA1'));
+ $this->setAuthMethod('SCRAM-SHA-224', array($this, 'authScramSHA224'));
+ $this->setAuthMethod('SCRAM-SHA-256', array($this, 'authScramSHA256'));
+ $this->setAuthMethod('SCRAM-SHA-384', array($this, 'authScramSHA384'));
+ $this->setAuthMethod('SCRAM-SHA-512', array($this, 'authScramSHA512'));
}
/* These standard authentication methods are always available. */
$this->setAuthMethod('LOGIN', array($this, 'authLogin'), false);
$this->setAuthMethod('PLAIN', array($this, 'authPlain'), false);
+ $this->setAuthMethod('XOAUTH2', array($this, 'authXOAuth2'), false);
+ $this->setAuthMethod('OAUTHBEARER', array($this, 'authOAuthBearer'), false);
}
/**
@@ -384,7 +439,7 @@ public function command($command, $valid)
*/
public function getResponse()
{
- return array($this->code, join("\n", $this->arguments));
+ return array($this->code, implode("\n", $this->arguments));
}
/**
@@ -455,22 +510,32 @@ public function connect($timeout = null, $persistent = false)
/**
* Attempt to disconnect from the SMTP server.
*
+ * @param bool $force Forces a disconnection of the socket even if
+ * the QUIT command fails
+ *
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @since 1.0
*/
- public function disconnect()
+ public function disconnect($force = false)
{
- if (PEAR::isError($error = $this->put('QUIT'))) {
- return $error;
+ /* parseResponse is only needed if put QUIT is successful */
+ if (!PEAR::isError($error = $this->put('QUIT'))) {
+ $error = $this->parseResponse(221);
}
- if (PEAR::isError($error = $this->parseResponse(221))) {
- return $error;
+
+ /* disconnecting socket if there is no error on the QUIT
+ * command or force disconnecting is requested */
+ if (!PEAR::isError($error) || $force) {
+ if (PEAR::isError($error_socket = $this->socket->disconnect())) {
+ return PEAR::raiseError(
+ 'Failed to disconnect socket: ' . $error_socket->getMessage()
+ );
+ }
}
- if (PEAR::isError($error = $this->socket->disconnect())) {
- return PEAR::raiseError(
- 'Failed to disconnect socket: ' . $error->getMessage()
- );
+
+ if (PEAR::isError($error)) {
+ return $error;
}
return true;
@@ -538,14 +603,123 @@ protected function getBestAuthMethod()
return PEAR::raiseError('No supported authentication methods');
}
+
+ /**
+ * Establish STARTTLS Connection.
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, true on success, or false if SSL/TLS
+ * isn't available.
+ * @since 1.10.0
+ */
+ public function starttls()
+ {
+ /* We can only attempt a TLS connection if one has been requested,
+ * we're running PHP 5.1.0 or later, have access to the OpenSSL
+ * extension, are connected to an SMTP server which supports the
+ * STARTTLS extension, and aren't already connected over a secure
+ * (SSL) socket connection. */
+ if (version_compare(PHP_VERSION, '5.1.0', '>=')
+ && extension_loaded('openssl') && isset($this->esmtp['STARTTLS'])
+ && strncasecmp($this->host, 'ssl://', 6) !== 0
+ ) {
+ /* Start the TLS connection attempt. */
+ if (PEAR::isError($result = $this->put('STARTTLS'))) {
+ return $result;
+ }
+ if (PEAR::isError($result = $this->parseResponse(220))) {
+ return $result;
+ }
+ if (isset($this->socket_options['ssl']['crypto_method'])) {
+ $crypto_method = $this->socket_options['ssl']['crypto_method'];
+ } else {
+ /* STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT constant does not exist
+ * and STREAM_CRYPTO_METHOD_SSLv23_CLIENT constant is
+ * inconsistent across PHP versions. */
+ $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
+
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) {
+ $crypto_method |= @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
+ }
+
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
+ $crypto_method |= @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
+ }
+
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT')) {
+ $crypto_method |= @STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT;
+ }
+ }
+
+ for ($attempts = 1; $attempts < 15; $attempts++) {
+ if(PEAR::isError(
+ $result = $this->socket->enableCrypto(
+ true, $crypto_method)
+ )
+ ) {
+ return $result;
+ }
+ if ($this->socket->isBlocking() !== true) {
+ usleep($attempts);
+ }
+ if ($result !== 0) {
+ break;
+ }
+ }
+
+ if ($result !== true) {
+ $last_error = error_get_last();
+ $crypto_types_arr = $this->getDefinedConstantsKeyFilter(
+ 'STREAM_CRYPTO_METHOD_'
+ );
+ $error_types_arr = $this->getDefinedConstantsKeyFilter(
+ 'E_'
+ );
+
+ $resultErrorString = "STARTTLS failed ";
+ //{enableCrypto: false;
+ $resultErrorString .= "{enableCrypto: %s; ";
+ //crypto_method: STREAM_CRYPTO_METHOD_TLS_CLIENT (3);
+ $resultErrorString .= "crypto_method: %s (%s); ";
+ //attempts: 1;
+ $resultErrorString .= "attempts: %d; ";
+ //E_ERROR (1): ErrorMessage}
+ $resultErrorString .= "%s (%s): %s}";
+
+ return PEAR::raiseError(
+ sprintf(
+ $resultErrorString,
+ var_export($result, true),
+ array_search($crypto_method, $crypto_types_arr),
+ var_export($crypto_method, true),
+ $attempts,
+ array_search($last_error['type'], $error_types_arr),
+ $last_error['type'],
+ $last_error['message']
+ )
+ );
+ }
+
+ /* Send EHLO again to recieve the AUTH string from the
+ * SMTP server. */
+ $this->negotiate();
+ } else {
+ return false;
+ }
+
+ return true;
+ }
/**
* Attempt to do SMTP authentication.
*
* @param string $uid The userid to authenticate as.
* @param string $pwd The password to authenticate with.
- * @param string $method The requested authentication method. If none is
+ * @param string $method The requested authentication method. If none is
* specified, the best supported method will be used.
+ * If you use the special method `OAUTH`, library
+ * will choose between OAUTHBEARER or XOAUTH2
+ * according the server's capabilities.
* @param bool $tls Flag indicating whether or not TLS should be attempted.
* @param string $authz An optional authorization identifier. If specified, this
* identifier will be used as the authorization proxy.
@@ -561,36 +735,11 @@ public function auth($uid, $pwd , $method = '', $tls = true, $authz = '')
* extension, are connected to an SMTP server which supports the
* STARTTLS extension, and aren't already connected over a secure
* (SSL) socket connection. */
- if ($tls && version_compare(PHP_VERSION, '5.1.0', '>=')
- && extension_loaded('openssl') && isset($this->esmtp['STARTTLS'])
- && strncasecmp($this->host, 'ssl://', 6) !== 0
- ) {
+ if ($tls) {
/* Start the TLS connection attempt. */
- if (PEAR::isError($result = $this->put('STARTTLS'))) {
- return $result;
- }
- if (PEAR::isError($result = $this->parseResponse(220))) {
- return $result;
+ if (PEAR::isError($starttls = $this->starttls())) {
+ return $starttls;
}
- if (isset($this->socket_options['ssl']['crypto_method'])) {
- $crypto_method = $this->socket_options['ssl']['crypto_method'];
- } else {
- /* STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT constant does not exist
- * and STREAM_CRYPTO_METHOD_SSLv23_CLIENT constant is
- * inconsistent across PHP versions. */
- $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT
- | @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
- | @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
- }
- if (PEAR::isError($result = $this->socket->enableCrypto(true, $crypto_method))) {
- return $result;
- } elseif ($result !== true) {
- return PEAR::raiseError('STARTTLS failed');
- }
-
- /* Send EHLO again to recieve the AUTH string from the
- * SMTP server. */
- $this->negotiate();
}
if (empty($this->esmtp['AUTH'])) {
@@ -604,6 +753,19 @@ public function auth($uid, $pwd , $method = '', $tls = true, $authz = '')
/* Return the PEAR_Error object from _getBestAuthMethod(). */
return $method;
}
+ } elseif ($method === 'OAUTH') {
+ // special case of OAUTH, use the supported method
+ $found = false;
+ $available_methods = explode(' ', $this->esmtp['AUTH']);
+ foreach (['OAUTHBEARER', 'XOAUTH2'] as $method) {
+ if (in_array($method, $available_methods)) {
+ $found = true;
+ break;
+ }
+ }
+ if (!$found) {
+ return PEAR::raiseError("neither OAUTHBEARER nor XOAUTH2 is a supported authentication method");
+ }
} else {
$method = strtoupper($method);
if (!array_key_exists($method, $this->auth_methods)) {
@@ -686,9 +848,15 @@ public function setAuthMethod($name, $callback, $prepend = true)
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @since 1.1.0
+ * @deprecated 1.11.0
*/
protected function authDigestMD5($uid, $pwd, $authz = '')
{
+ /* TODO trigger deprecation error in 2.0.0 and remove authDigestMD5() in 3.0.0
+ trigger_error(__CLASS__ . ' (' . $this->host . '): Authentication method DIGEST-MD5' .
+ ' is no longer secure and should be avoided.', E_USER_DEPRECATED);
+ */
+
if (PEAR::isError($error = $this->put('AUTH', 'DIGEST-MD5'))) {
return $error;
}
@@ -737,9 +905,15 @@ protected function authDigestMD5($uid, $pwd, $authz = '')
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @since 1.1.0
+ * @deprecated 1.11.0
*/
protected function authCRAMMD5($uid, $pwd, $authz = '')
{
+ /* TODO trigger deprecation error in 2.0.0 and remove authCRAMMD5() in 3.0.0
+ trigger_error(__CLASS__ . ' (' . $this->host . '): Authentication method CRAM-MD5' .
+ ' is no longer secure and should be avoided.', E_USER_DEPRECATED);
+ */
+
if (PEAR::isError($error = $this->put('AUTH', 'CRAM-MD5'))) {
return $error;
}
@@ -776,9 +950,15 @@ protected function authCRAMMD5($uid, $pwd, $authz = '')
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @since 1.1.0
+ * @deprecated 1.11.0
*/
protected function authLogin($uid, $pwd, $authz = '')
{
+ /* TODO trigger deprecation error in 2.0.0 and remove authLogin() in 3.0.0
+ trigger_error(__CLASS__ . ' (' . $this->host . '): Authentication method LOGIN' .
+ ' is no longer secure and should be avoided.', E_USER_DEPRECATED);
+ */
+
if (PEAR::isError($error = $this->put('AUTH', 'LOGIN'))) {
return $error;
}
@@ -850,6 +1030,341 @@ protected function authPlain($uid, $pwd, $authz = '')
return true;
}
+ /**
+ * Authenticates the user using the GSSAPI method.
+ *
+ * PHP krb5 extension is required,
+ * service principal and credentials cache must be set.
+ *
+ * @param string $uid The userid to authenticate as.
+ * @param string $pwd The password to authenticate with.
+ * @param string $authz The optional authorization proxy identifier.
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, or true on success.
+ */
+ protected function authGSSAPI($uid, $pwd, $authz = '')
+ {
+ if (PEAR::isError($error = $this->put('AUTH', 'GSSAPI'))) {
+ return $error;
+ }
+ /* 334: Continue authentication request */
+ if (PEAR::isError($error = $this->parseResponse(334))) {
+ /* 503: Error: already authenticated */
+ if ($this->code === 503) {
+ return true;
+ }
+ return $error;
+ }
+
+ if (!$this->gssapi_principal) {
+ return PEAR::raiseError('No Kerberos service principal set', 2);
+ }
+
+ if (!empty($this->gssapi_cname)) {
+ putenv('KRB5CCNAME=' . $this->gssapi_cname);
+ }
+
+ try {
+ $ccache = new KRB5CCache();
+ if (!empty($this->gssapi_cname)) {
+ $ccache->open($this->gssapi_cname);
+ }
+
+ $gssapicontext = new GSSAPIContext();
+ $gssapicontext->acquireCredentials($ccache);
+
+ $token = '';
+ $success = $gssapicontext->initSecContext($this->gssapi_principal, null, null, null, $token);
+ $token = base64_encode($token);
+ }
+ catch (Exception $e) {
+ return PEAR::raiseError('GSSAPI authentication failed: ' . $e->getMessage());
+ }
+
+ if (PEAR::isError($error = $this->put($token))) {
+ return $error;
+ }
+
+ /* 334: Continue authentication request */
+ if (PEAR::isError($error = $this->parseResponse(334))) {
+ return $error;
+ }
+
+ $response = $this->arguments[0];
+
+ try {
+ $challenge = base64_decode($response);
+ $gssapicontext->unwrap($challenge, $challenge);
+ $gssapicontext->wrap($challenge, $challenge, true);
+ }
+ catch (Exception $e) {
+ return PEAR::raiseError('GSSAPI authentication failed: ' . $e->getMessage());
+ }
+
+ if (PEAR::isError($error = $this->put(base64_encode($challenge)))) {
+ return $error;
+ }
+
+ /* 235: Authentication successful */
+ if (PEAR::isError($error = $this->parseResponse(235))) {
+ return $error;
+ }
+
+ return true;
+ }
+
+ /**
+ * Authenticates the user using the XOAUTH2 method.
+ *
+ * @param string $uid The userid to authenticate as.
+ * @param string $token The access token prefixed by it's type
+ * example: "Bearer $access_token".
+ * @param string $authz The optional authorization proxy identifier.
+ * @param object $conn The current object
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, or true on success.
+ * @since 1.9.0
+ */
+ //FIXME: to switch into protected method on next major release
+ public function authXOAuth2($uid, $token, $authz, $conn)
+ {
+ $auth = base64_encode("user=$uid\1auth=$token\1\1");
+ return $this->authenticateOAuth('XOAUTH2', $auth, $authz, $conn);
+ }
+
+ /**
+ * Authenticates the user using the OAUTHBEARER method.
+ *
+ * @param string $uid The userid to authenticate as.
+ * @param string $token The access token prefixed by it's type
+ * example: "Bearer $access_token".
+ * @param string $authz The optional authorization proxy identifier.
+ * @param object $conn The current object
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, or true on success.
+ * @since 1.9.3
+ * @see https://www.rfc-editor.org/rfc/rfc7628.html
+ */
+ protected function authOAuthBearer($uid, $token, $authz, $conn)
+ {
+ $auth = base64_encode("n,a=$uid\1auth=$token\1\1");
+ return $this->authenticateOAuth('OAUTHBEARER', $auth, $authz, $conn);
+ }
+
+ /**
+ * Authenticates the user using the OAUTHBEARER or XOAUTH2 method.
+ *
+ * @param string $method The method (OAUTHBEARER or XOAUTH2)
+ * @param string $auth The authentication string (base64 coded)
+ * @param string $authz The optional authorization proxy identifier.
+ * @param object $conn The current object
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, or true on success.
+ */
+ protected function authenticateOAuth( $method, $auth, $authz, $conn)
+ {
+ // Maximum length of the base64-encoded token to be sent in the initial response is 504 - strlen($method) bytes,
+ // according to RFC 4954 (https://datatracker.ietf.org/doc/html/rfc4954); for longer tokens an empty initial
+ // response MUST be sent and the token must be sent separately
+ // (504 bytes = /SMTP command length limit/ - 6 bytes /"AUTH "/ -strlen($method) - 1 byte /" "/ - 2 bytes /CRLF/)
+ if (strlen($auth) <= (504-strlen($method))) {
+ if (PEAR::isError($error = $this->put('AUTH', $method . ' ' . $auth))) {
+ return $error;
+ }
+ } else {
+ if (PEAR::isError($error = $this->put('AUTH', $method))) {
+ return $error;
+ }
+
+ // server is expected to respond with 334
+ if (PEAR::isError($error = $this->parseResponse(334))) {
+ return $error;
+ }
+
+ // then follows the token
+ if (PEAR::isError($error = $this->put($auth))) {
+ return $error;
+ }
+ }
+
+ /* 235: Authentication successful or 334: Continue authentication */
+ if (PEAR::isError($error = $this->parseResponse([235, 334]))) {
+ return $error;
+ }
+
+ /* 334: Continue authentication request */
+ if ($this->code === 334) {
+ /* Send an empty line as response to 334 */
+ if (PEAR::isError($error = $this->put(''))) {
+ return $error;
+ }
+
+ /* Expect 235: Authentication successful */
+ if (PEAR::isError($error = $this->parseResponse(235))) {
+ return $error;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Authenticates the user using the SCRAM-SHA-1 method.
+ *
+ * @param string $uid The userid to authenticate as.
+ * @param string $pwd The password to authenticate with.
+ * @param string $authz The optional authorization proxy identifier.
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, or true on success.
+ * @since 1.11.0
+ */
+ protected function authScramSHA1($uid, $pwd, $authz = '')
+ {
+ $this->scram_sha_hash_algorithm = 'SCRAM-SHA-1';
+ return $this->authScramSHA($uid, $pwd, $authz);
+ }
+
+ /**
+ * Authenticates the user using the SCRAM-SHA-224 method.
+ *
+ * @param string $uid The userid to authenticate as.
+ * @param string $pwd The password to authenticate with.
+ * @param string $authz The optional authorization proxy identifier.
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, or true on success.
+ * @since 1.11.0
+ */
+ protected function authScramSHA224($uid, $pwd, $authz = '')
+ {
+ $this->scram_sha_hash_algorithm = 'SCRAM-SHA-224';
+ return $this->authScramSHA($uid, $pwd, $authz);
+ }
+
+ /**
+ * Authenticates the user using the SCRAM-SHA-256 method.
+ *
+ * @param string $uid The userid to authenticate as.
+ * @param string $pwd The password to authenticate with.
+ * @param string $authz The optional authorization proxy identifier.
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, or true on success.
+ * @since 1.11.0
+ */
+ protected function authScramSHA256($uid, $pwd, $authz = '')
+ {
+ $this->scram_sha_hash_algorithm = 'SCRAM-SHA-256';
+ return $this->authScramSHA($uid, $pwd, $authz);
+ }
+
+ /**
+ * Authenticates the user using the SCRAM-SHA-384 method.
+ *
+ * @param string $uid The userid to authenticate as.
+ * @param string $pwd The password to authenticate with.
+ * @param string $authz The optional authorization proxy identifier.
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, or true on success.
+ * @since 1.11.0
+ */
+ protected function authScramSHA384($uid, $pwd, $authz = '')
+ {
+ $this->scram_sha_hash_algorithm = 'SCRAM-SHA-384';
+ return $this->authScramSHA($uid, $pwd, $authz);
+ }
+
+ /**
+ * Authenticates the user using the SCRAM-SHA-512 method.
+ *
+ * @param string $uid The userid to authenticate as.
+ * @param string $pwd The password to authenticate with.
+ * @param string $authz The optional authorization proxy identifier.
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, or true on success.
+ * @since 1.11.0
+ */
+ protected function authScramSHA512($uid, $pwd, $authz = '')
+ {
+ $this->scram_sha_hash_algorithm = 'SCRAM-SHA-512';
+ return $this->authScramSHA($uid, $pwd, $authz);
+ }
+
+ /**
+ * Authenticates the user using the SCRAM-SHA method.
+ *
+ * @param string $uid The userid to authenticate as.
+ * @param string $pwd The password to authenticate with.
+ * @param string $authz The optional authorization proxy identifier.
+ *
+ * @return mixed Returns a PEAR_Error with an error message on any
+ * kind of failure, or true on success.
+ * @since 1.11.0
+ */
+ protected function authScramSHA($uid, $pwd, $authz = '')
+ {
+ if (PEAR::isError($error = $this->put('AUTH', $this->scram_sha_hash_algorithm))) {
+ return $error;
+ }
+ /* 334: Continue authentication request */
+ if (PEAR::isError($error = $this->parseResponse(334))) {
+ /* 503: Error: already authenticated */
+ if ($this->code === 503) {
+ return true;
+ }
+ return $error;
+ }
+
+ $cram = Auth_SASL::factory($this->scram_sha_hash_algorithm);
+ $auth_str = base64_encode($cram->getResponse($uid, $pwd));
+
+ /* Step 1: Send first authentication request */
+ if (PEAR::isError($error = $this->put($auth_str))) {
+ return $error;
+ }
+
+ /* 334: Continue authentication request with password salt */
+ if (PEAR::isError($error = $this->parseResponse(334))) {
+ return $error;
+ }
+
+ $challenge = base64_decode($this->arguments[0]);
+ $auth_str = base64_encode($cram->getResponse($uid, $pwd, $challenge));
+
+ /* Step 2: Send salted authentication request */
+ if (PEAR::isError($error = $this->put($auth_str))) {
+ return $error;
+ }
+
+ /* 334: Continue authentication request with password salt */
+ if (PEAR::isError($error = $this->parseResponse(334))) {
+ return $error;
+ }
+
+ /* Verify server signature */
+ $verification = $cram->processOutcome(base64_decode($this->arguments[0]));
+ if ($verification == false) {
+ return PEAR::raiseError("SCRAM Server verification on step 3 not successful");
+ }
+
+ /* Step 3: Send a request to acknowledge verification */
+ if (PEAR::isError($error = $this->put("NOOP"))) {
+ return $error;
+ }
+
+ /* 235: Authentication successful */
+ if (PEAR::isError($error = $this->parseResponse(235))) {
+ return $error;
+ }
+ }
+
/**
* Send the HELO command.
*
@@ -998,7 +1513,7 @@ public function data($data, $headers = null)
/* Start by considering the size of the optional headers string. We
* also account for the addition 4 character "\r\n\r\n" separator
* sequence. */
- $size = (is_null($headers)) ? 0 : strlen($headers) + 4;
+ $size = $headers_size = (is_null($headers)) ? 0 : strlen($headers) + 4;
if (is_resource($data)) {
$stat = fstat($data);
@@ -1016,7 +1531,6 @@ public function data($data, $headers = null)
* about the server's fixed maximum message size". */
$limit = (isset($this->esmtp['SIZE'])) ? $this->esmtp['SIZE'] : 0;
if ($limit > 0 && $size >= $limit) {
- $this->disconnect();
return PEAR::raiseError('Message size exceeds server limit');
}
@@ -1036,7 +1550,7 @@ public function data($data, $headers = null)
}
/* Subtract the headers size now that they've been sent. */
- $size -= strlen($headers) + 4;
+ $size -= $headers_size;
}
/* Now we can send the message body data. */
@@ -1251,4 +1765,25 @@ public function identifySender()
{
return true;
}
+
+ /**
+ * Backwards-compatibility method.
+ * array_filter alternative in PHP5.4 for using
+ * key filter because array_filter mode parameter
+ * is only available since PHP5.6.
+ *
+ * @param string $filter The string to filter
+ * @return array Filtered constants array.
+ */
+ private function getDefinedConstantsKeyFilter($filter) {
+ $constants_filtered = array();
+ $filter_length = strlen($filter);
+ $constants = get_defined_constants();
+ foreach ($constants as $key=>$value){
+ if (substr($key, 0, $filter_length) == $filter) {
+ $constants_filtered[$key] = $value;
+ }
+ }
+ return $constants_filtered;
+ }
}
diff --git a/WEB-INF/lib/pear/Net/Socket.php b/WEB-INF/lib/pear/Net/Socket.php
index bf1d1bbcd..5a057cf78 100644
--- a/WEB-INF/lib/pear/Net/Socket.php
+++ b/WEB-INF/lib/pear/Net/Socket.php
@@ -2,27 +2,41 @@
/**
* Net_Socket
*
- * PHP Version 4
+ * PHP Version 5
*
- * Copyright (c) 1997-2013 The PHP Group
+ * LICENSE:
*
- * This source file is subject to version 2.0 of the PHP license,
- * that is bundled with this package in the file LICENSE, and is
- * available at through the world-wide-web at
- * http://www.php.net/license/2_02.txt.
- * If you did not receive a copy of the PHP license and are unable to
- * obtain it through the world-wide-web, please send a note to
- * license@php.net so we can mail you a copy immediately.
+ * Copyright (c) 1997-2017 The PHP Group
+ * All rights reserved.
*
- * Authors: Stig Bakken
- * Chuck Hagenbuch
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * o Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * o Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category Net
* @package Net_Socket
* @author Stig Bakken
* @author Chuck Hagenbuch
- * @copyright 1997-2003 The PHP Group
- * @license http://www.php.net/license/2_02.txt PHP 2.02
+ * @copyright 1997-2017 The PHP Group
+ * @license http://opensource.org/licenses/bsd-license.php BSD-2-Clause
* @link http://pear.php.net/packages/Net_Socket
*/
@@ -39,8 +53,8 @@
* @package Net_Socket
* @author Stig Bakken
* @author Chuck Hagenbuch
- * @copyright 1997-2003 The PHP Group
- * @license http://www.php.net/license/2_02.txt PHP 2.02
+ * @copyright 1997-2017 The PHP Group
+ * @license http://opensource.org/licenses/bsd-license.php BSD-2-Clause
* @link http://pear.php.net/packages/Net_Socket
*/
class Net_Socket extends PEAR
@@ -49,71 +63,75 @@ class Net_Socket extends PEAR
* Socket file pointer.
* @var resource $fp
*/
- var $fp = null;
+ public $fp = null;
/**
* Whether the socket is blocking. Defaults to true.
* @var boolean $blocking
*/
- var $blocking = true;
+ public $blocking = true;
/**
* Whether the socket is persistent. Defaults to false.
* @var boolean $persistent
*/
- var $persistent = false;
+ public $persistent = false;
/**
* The IP address to connect to.
* @var string $addr
*/
- var $addr = '';
+ public $addr = '';
/**
* The port number to connect to.
* @var integer $port
*/
- var $port = 0;
+ public $port = 0;
/**
* Number of seconds to wait on socket operations before assuming
* there's no more data. Defaults to no timeout.
* @var integer|float $timeout
*/
- var $timeout = null;
+ public $timeout = null;
/**
* Number of bytes to read at a time in readLine() and
* readAll(). Defaults to 2048.
* @var integer $lineLength
*/
- var $lineLength = 2048;
+ public $lineLength = 2048;
/**
* The string to use as a newline terminator. Usually "\r\n" or "\n".
* @var string $newline
*/
- var $newline = "\r\n";
+ public $newline = "\r\n";
/**
* Connect to the specified port. If called when the socket is
* already connected, it disconnects and connects again.
*
- * @param string $addr IP address or host name (may be with protocol prefix).
- * @param integer $port TCP port number.
+ * @param string $addr IP address or host name (may be with protocol prefix).
+ * @param integer $port TCP port number.
* @param boolean $persistent (optional) Whether the connection is
* persistent (kept open between requests
* by the web server).
- * @param integer $timeout (optional) Connection socket timeout.
- * @param array $options See options for stream_context_create.
+ * @param integer $timeout (optional) Connection socket timeout.
+ * @param array $options See options for stream_context_create.
*
* @access public
*
* @return boolean|PEAR_Error True on success or a PEAR_Error on failure.
*/
- function connect($addr, $port = 0, $persistent = null,
- $timeout = null, $options = null)
- {
+ public function connect(
+ $addr,
+ $port = 0,
+ $persistent = null,
+ $timeout = null,
+ $options = null
+ ) {
if (is_resource($this->fp)) {
@fclose($this->fp);
$this->fp = null;
@@ -121,10 +139,12 @@ function connect($addr, $port = 0, $persistent = null,
if (!$addr) {
return $this->raiseError('$addr cannot be empty');
- } else if (strspn($addr, ':.0123456789') == strlen($addr)) {
- $this->addr = strpos($addr, ':') !== false ? '['.$addr.']' : $addr;
} else {
- $this->addr = $addr;
+ if (strspn($addr, ':.0123456789') === strlen($addr)) {
+ $this->addr = strpos($addr, ':') !== false ? '[' . $addr . ']' : $addr;
+ } else {
+ $this->addr = $addr;
+ }
}
$this->port = $port % 65536;
@@ -134,10 +154,14 @@ function connect($addr, $port = 0, $persistent = null,
}
$openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen';
- $errno = 0;
- $errstr = '';
+ $errno = 0;
+ $errstr = '';
- $old_track_errors = @ini_set('track_errors', 1);
+ if (function_exists('error_clear_last')) {
+ error_clear_last();
+ } else {
+ $old_track_errors = @ini_set('track_errors', 1);
+ }
if ($timeout <= 0) {
$timeout = @ini_get('default_socket_timeout');
@@ -155,27 +179,40 @@ function connect($addr, $port = 0, $persistent = null,
}
$addr = $this->addr . ':' . $this->port;
- $fp = stream_socket_client($addr, $errno, $errstr,
- $timeout, $flags, $context);
+ $fp = @stream_socket_client($addr, $errno, $errstr,
+ $timeout, $flags, $context);
} else {
$fp = @$openfunc($this->addr, $this->port, $errno,
- $errstr, $timeout, $context);
+ $errstr, $timeout, $context);
}
} else {
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout);
}
if (!$fp) {
- if ($errno == 0 && !strlen($errstr) && isset($php_errormsg)) {
- $errstr = $php_errormsg;
+ if ($errno === 0 && !strlen($errstr)) {
+ $errstr = '';
+ if (isset($old_track_errors)) {
+ $errstr = $php_errormsg ?: '';
+ @ini_set('track_errors', $old_track_errors);
+ } else {
+ $lastError = error_get_last();
+ if (isset($lastError['message'])) {
+ $errstr = $lastError['message'];
+ }
+ }
}
- @ini_set('track_errors', $old_track_errors);
+
return $this->raiseError($errstr, $errno);
}
- @ini_set('track_errors', $old_track_errors);
+ if (isset($old_track_errors)) {
+ @ini_set('track_errors', $old_track_errors);
+ }
+
$this->fp = $fp;
$this->setTimeout();
+
return $this->setBlocking($this->blocking);
}
@@ -185,7 +222,7 @@ function connect($addr, $port = 0, $persistent = null,
* @access public
* @return mixed true on success or a PEAR_Error instance otherwise
*/
- function disconnect()
+ public function disconnect()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
@@ -193,18 +230,20 @@ function disconnect()
@fclose($this->fp);
$this->fp = null;
+
return true;
}
/**
* Set the newline character/sequence to use.
*
- * @param string $newline Newline character(s)
+ * @param string $newline Newline character(s)
* @return boolean True
*/
- function setNewline($newline)
+ public function setNewline($newline)
{
$this->newline = $newline;
+
return true;
}
@@ -214,7 +253,7 @@ function setNewline($newline)
* @access public
* @return boolean The current blocking mode.
*/
- function isBlocking()
+ public function isBlocking()
{
return $this->blocking;
}
@@ -230,7 +269,7 @@ function isBlocking()
* @access public
* @return mixed true on success or a PEAR_Error instance otherwise
*/
- function setBlocking($mode)
+ public function setBlocking($mode)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
@@ -238,6 +277,7 @@ function setBlocking($mode)
$this->blocking = $mode;
stream_set_blocking($this->fp, (int)$this->blocking);
+
return true;
}
@@ -245,30 +285,29 @@ function setBlocking($mode)
* Sets the timeout value on socket descriptor,
* expressed in the sum of seconds and microseconds
*
- * @param integer $seconds Seconds.
+ * @param integer $seconds Seconds.
* @param integer $microseconds Microseconds, optional.
*
* @access public
* @return mixed True on success or false on failure or
* a PEAR_Error instance when not connected
*/
- function setTimeout($seconds = null, $microseconds = null)
+ public function setTimeout($seconds = null, $microseconds = null)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
if ($seconds === null && $microseconds === null) {
- $seconds = (int) $this->timeout;
- $microseconds = (int) (($this->timeout - $seconds) * 1000000);
+ $seconds = (int)$this->timeout;
+ $microseconds = (int)(($this->timeout - $seconds) * 1000000);
} else {
- $this->timeout = $seconds + $microseconds/1000000;
+ $this->timeout = $seconds + $microseconds / 1000000;
}
if ($this->timeout > 0) {
- return stream_set_timeout($this->fp, (int) $seconds, (int) $microseconds);
- }
- else {
+ return stream_set_timeout($this->fp, (int)$seconds, (int)$microseconds);
+ } else {
return false;
}
}
@@ -282,16 +321,17 @@ function setTimeout($seconds = null, $microseconds = null)
* @access public
* @return mixed on success or an PEAR_Error object otherwise
*/
- function setWriteBuffer($size)
+ public function setWriteBuffer($size)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$returned = stream_set_write_buffer($this->fp, $size);
- if ($returned == 0) {
+ if ($returned === 0) {
return true;
}
+
return $this->raiseError('Cannot set write buffer.');
}
@@ -310,7 +350,7 @@ function setWriteBuffer($size)
* @return mixed Array containing information about existing socket
* resource or a PEAR_Error instance otherwise
*/
- function getStatus()
+ public function getStatus()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
@@ -331,13 +371,13 @@ function getStatus()
* @return mixed $size bytes of data from the socket, or a PEAR_Error if
* not connected. If an error occurs, FALSE is returned.
*/
- function gets($size = null)
+ public function gets($size = null)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
- if (is_null($size)) {
+ if (null === $size) {
return @fgets($this->fp);
} else {
return @fgets($this->fp, $size);
@@ -353,10 +393,10 @@ function gets($size = null)
* @param integer $size The number of bytes to read from the socket.
*
* @access public
- * @return $size bytes of data from the socket, or a PEAR_Error if
+ * @return string $size bytes of data from the socket, or a PEAR_Error if
* not connected.
*/
- function read($size)
+ public function read($size)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
@@ -368,7 +408,7 @@ function read($size)
/**
* Write a specified amount of data.
*
- * @param string $data Data to write.
+ * @param string $data Data to write.
* @param integer $blocksize Amount of data to write at once.
* NULL means all at once.
*
@@ -379,17 +419,17 @@ function read($size)
* If the write fails, returns false.
* If the socket times out, returns an instance of PEAR_Error.
*/
- function write($data, $blocksize = null)
+ public function write($data, $blocksize = null)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
- if (is_null($blocksize) && !OS_WINDOWS) {
+ if (null === $blocksize && !OS_WINDOWS) {
$written = @fwrite($this->fp, $data);
// Check for timeout or lost connection
- if (!$written) {
+ if ($written === false) {
$meta_data = $this->getStatus();
if (!is_array($meta_data)) {
@@ -403,17 +443,17 @@ function write($data, $blocksize = null)
return $written;
} else {
- if (is_null($blocksize)) {
+ if (null === $blocksize) {
$blocksize = 1024;
}
- $pos = 0;
+ $pos = 0;
$size = strlen($data);
while ($pos < $size) {
$written = @fwrite($this->fp, substr($data, $pos, $blocksize));
// Check for timeout or lost connection
- if (!$written) {
+ if ($written === false) {
$meta_data = $this->getStatus();
if (!is_array($meta_data)) {
@@ -442,7 +482,7 @@ function write($data, $blocksize = null)
* @access public
* @return mixed fwrite() result, or PEAR_Error when not connected
*/
- function writeLine($data)
+ public function writeLine($data)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
@@ -459,7 +499,7 @@ function writeLine($data)
* @access public
* @return bool
*/
- function eof()
+ public function eof()
{
return (!is_resource($this->fp) || feof($this->fp));
}
@@ -468,10 +508,10 @@ function eof()
* Reads a byte of data
*
* @access public
- * @return 1 byte of data from the socket, or a PEAR_Error if
+ * @return integer 1 byte of data from the socket, or a PEAR_Error if
* not connected.
*/
- function readByte()
+ public function readByte()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
@@ -484,16 +524,17 @@ function readByte()
* Reads a word of data
*
* @access public
- * @return 1 word of data from the socket, or a PEAR_Error if
+ * @return integer 1 word of data from the socket, or a PEAR_Error if
* not connected.
*/
- function readWord()
+ public function readWord()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$buf = @fread($this->fp, 2);
+
return (ord($buf[0]) + (ord($buf[1]) << 8));
}
@@ -504,15 +545,16 @@ function readWord()
* @return integer 1 int of data from the socket, or a PEAR_Error if
* not connected.
*/
- function readInt()
+ public function readInt()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$buf = @fread($this->fp, 4);
+
return (ord($buf[0]) + (ord($buf[1]) << 8) +
- (ord($buf[2]) << 16) + (ord($buf[3]) << 24));
+ (ord($buf[2]) << 16) + (ord($buf[3]) << 24));
}
/**
@@ -522,16 +564,17 @@ function readInt()
* @return string, or a PEAR_Error if
* not connected.
*/
- function readString()
+ public function readString()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$string = '';
- while (($char = @fread($this->fp, 1)) != "\x00") {
+ while (($char = @fread($this->fp, 1)) !== "\x00") {
$string .= $char;
}
+
return $string;
}
@@ -539,18 +582,19 @@ function readString()
* Reads an IP Address and returns it in a dot formatted string
*
* @access public
- * @return Dot formatted string, or a PEAR_Error if
+ * @return string Dot formatted string, or a PEAR_Error if
* not connected.
*/
- function readIPAddress()
+ public function readIPAddress()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$buf = @fread($this->fp, 4);
+
return sprintf('%d.%d.%d.%d', ord($buf[0]), ord($buf[1]),
- ord($buf[2]), ord($buf[3]));
+ ord($buf[2]), ord($buf[3]));
}
/**
@@ -558,11 +602,11 @@ function readIPAddress()
* comes first. Strips the trailing newline from the returned data.
*
* @access public
- * @return All available data up to a newline, without that
+ * @return string All available data up to a newline, without that
* newline, or until the end of the socket, or a PEAR_Error if
* not connected.
*/
- function readLine()
+ public function readLine()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
@@ -578,6 +622,7 @@ function readLine()
return rtrim($line, $this->newline);
}
}
+
return $line;
}
@@ -594,16 +639,19 @@ function readLine()
* @return string All data until the socket closes, or a PEAR_Error if
* not connected.
*/
- function readAll()
+ public function readAll()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$data = '';
- while (!feof($this->fp)) {
+ $timeout = time() + $this->timeout;
+
+ while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) {
$data .= @fread($this->fp, $this->lineLength);
}
+
return $data;
}
@@ -611,22 +659,22 @@ function readAll()
* Runs the equivalent of the select() system call on the socket
* with a timeout specified by tv_sec and tv_usec.
*
- * @param integer $state Which of read/write/error to check for.
- * @param integer $tv_sec Number of seconds for timeout.
+ * @param integer $state Which of read/write/error to check for.
+ * @param integer $tv_sec Number of seconds for timeout.
* @param integer $tv_usec Number of microseconds for timeout.
*
* @access public
* @return False if select fails, integer describing which of read/write/error
* are ready, or PEAR_Error if not connected.
*/
- function select($state, $tv_sec, $tv_usec = 0)
+ public function select($state, $tv_sec, $tv_usec = 0)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
- $read = null;
- $write = null;
+ $read = null;
+ $write = null;
$except = null;
if ($state & NET_SOCKET_READ) {
$read[] = $this->fp;
@@ -638,7 +686,8 @@ function select($state, $tv_sec, $tv_usec = 0)
$except[] = $this->fp;
}
if (false === ($sr = stream_select($read, $write, $except,
- $tv_sec, $tv_usec))) {
+ $tv_sec, $tv_usec))
+ ) {
return false;
}
@@ -652,15 +701,16 @@ function select($state, $tv_sec, $tv_usec = 0)
if (count($except)) {
$result |= NET_SOCKET_ERROR;
}
+
return $result;
}
/**
* Turns encryption on/off on a connected socket.
*
- * @param bool $enabled Set this parameter to true to enable encryption
+ * @param bool $enabled Set this parameter to true to enable encryption
* and false to disable encryption.
- * @param integer $type Type of encryption. See stream_socket_enable_crypto()
+ * @param integer $type Type of encryption. See stream_socket_enable_crypto()
* for values.
*
* @see http://se.php.net/manual/en/function.stream-socket-enable-crypto.php
@@ -670,15 +720,17 @@ function select($state, $tv_sec, $tv_usec = 0)
* A PEAR_Error object is returned if the socket is not
* connected
*/
- function enableCrypto($enabled, $type)
+ public function enableCrypto($enabled, $type)
{
- if (version_compare(phpversion(), "5.1.0", ">=")) {
+ if (version_compare(phpversion(), '5.1.0', '>=')) {
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
+
return @stream_socket_enable_crypto($this->fp, $enabled, $type);
} else {
$msg = 'Net_Socket::enableCrypto() requires php version >= 5.1.0';
+
return $this->raiseError($msg);
}
}
diff --git a/WEB-INF/lib/pear/OS/Guess.php b/WEB-INF/lib/pear/OS/Guess.php
index 4c9254a26..f240bb499 100644
--- a/WEB-INF/lib/pear/OS/Guess.php
+++ b/WEB-INF/lib/pear/OS/Guess.php
@@ -4,14 +4,14 @@
*
* PHP versions 4 and 5
*
- * @category pear
- * @package PEAR
- * @author Stig Bakken
- * @author Gregory Beaver
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @link http://pear.php.net/package/PEAR
- * @since File available since PEAR 0.1
+ * @category pear
+ * @package PEAR
+ * @author Stig Bakken
+ * @author Gregory Beaver
+ * @copyright 1997-2009 The Authors
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @link http://pear.php.net/package/PEAR
+ * @since File available since PEAR 0.1
*/
// {{{ uname examples
@@ -80,15 +80,15 @@
*
* This class uses php_uname() to grok information about the current OS
*
- * @category pear
- * @package PEAR
- * @author Stig Bakken
- * @author Gregory Beaver
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 0.1
+ * @category pear
+ * @package PEAR
+ * @author Stig Bakken
+ * @author Gregory Beaver
+ * @copyright 1997-2020 The Authors
+ * @license http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version Release: 1.10.15
+ * @link http://pear.php.net/package/PEAR
+ * @since Class available since Release 0.1
*/
class OS_Guess
{
@@ -138,13 +138,9 @@ function parseSignature($uname = null)
$release = "$parts[3].$parts[2]";
break;
case 'Windows' :
- switch ($parts[1]) {
- case '95/98':
- $release = '9x';
- break;
- default:
- $release = $parts[1];
- break;
+ $release = $parts[1];
+ if ($release == '95/98') {
+ $release = '9x';
}
$cpu = 'i386';
break;
@@ -157,18 +153,10 @@ function parseSignature($uname = null)
$sysname = 'darwin';
$nodename = $parts[2];
$release = $parts[3];
- if ($cpu == 'Macintosh') {
- if ($parts[$n - 2] == 'Power') {
- $cpu = 'powerpc';
- }
- }
+ $cpu = $this->_determineIfPowerpc($cpu, $parts);
break;
case 'Darwin' :
- if ($cpu == 'Macintosh') {
- if ($parts[$n - 2] == 'Power') {
- $cpu = 'powerpc';
- }
- }
+ $cpu = $this->_determineIfPowerpc($cpu, $parts);
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
break;
default:
@@ -187,6 +175,15 @@ function parseSignature($uname = null)
return array($sysname, $release, $cpu, $extra, $nodename);
}
+ function _determineIfPowerpc($cpu, $parts)
+ {
+ $n = count($parts);
+ if ($cpu == 'Macintosh' && $parts[$n - 2] == 'Power') {
+ $cpu = 'powerpc';
+ }
+ return $cpu;
+ }
+
function _detectGlibcVersion()
{
static $glibc = false;
@@ -195,75 +192,132 @@ function _detectGlibcVersion()
}
$major = $minor = 0;
include_once "System.php";
+
+ // Let's try reading possible libc.so.6 symlinks
+ $libcs = array(
+ '/lib64/libc.so.6',
+ '/lib/libc.so.6',
+ '/lib/i386-linux-gnu/libc.so.6'
+ );
+ $versions = array();
+ foreach ($libcs as $file) {
+ $versions = $this->_readGlibCVersionFromSymlink($file);
+ if ($versions != []) {
+ list($major, $minor) = $versions;
+ break;
+ }
+ }
+
// Use glibc's header file to
// get major and minor version number:
- if (@file_exists('/usr/include/features.h') &&
- @is_readable('/usr/include/features.h')) {
- if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) {
- $features_file = fopen('/usr/include/features.h', 'rb');
- while (!feof($features_file)) {
- $line = fgets($features_file, 8192);
- if (!$line || (strpos($line, '#define') === false)) {
- continue;
- }
- if (strpos($line, '__GLIBC__')) {
- // major version number #define __GLIBC__ version
- $line = preg_split('/\s+/', $line);
- $glibc_major = trim($line[2]);
- if (isset($glibc_minor)) {
- break;
- }
- continue;
- }
-
- if (strpos($line, '__GLIBC_MINOR__')) {
- // got the minor version number
- // #define __GLIBC_MINOR__ version
- $line = preg_split('/\s+/', $line);
- $glibc_minor = trim($line[2]);
- if (isset($glibc_major)) {
- break;
- }
- continue;
- }
- }
- fclose($features_file);
- if (!isset($glibc_major) || !isset($glibc_minor)) {
- return $glibc = '';
- }
- return $glibc = 'glibc' . trim($glibc_major) . "." . trim($glibc_minor) ;
- } // no cpp
-
- $tmpfile = System::mktemp("glibctest");
- $fp = fopen($tmpfile, "w");
- fwrite($fp, "#include \n__GLIBC__ __GLIBC_MINOR__\n");
- fclose($fp);
- $cpp = popen("/usr/bin/cpp $tmpfile", "r");
- while ($line = fgets($cpp, 1024)) {
- if ($line{0} == '#' || trim($line) == '') {
- continue;
- }
+ if (!($major && $minor)) {
+ $versions = $this->_readGlibCVersionFromFeaturesHeaderFile();
+ }
+ if (is_array($versions) && $versions != []) {
+ list($major, $minor) = $versions;
+ }
+
+ if (!($major && $minor)) {
+ return $glibc = '';
+ }
+
+ return $glibc = "glibc{$major}.{$minor}";
+ }
- if (list($major, $minor) = explode(' ', trim($line))) {
+ function _readGlibCVersionFromSymlink($file)
+ {
+ $versions = array();
+ if (@is_link($file)
+ && (preg_match('/^libc-(.*)\.so$/', basename(readlink($file)), $matches))
+ ) {
+ $versions = explode('.', $matches[1]);
+ }
+ return $versions;
+ }
+
+
+ function _readGlibCVersionFromFeaturesHeaderFile()
+ {
+ $features_header_file = '/usr/include/features.h';
+ if (!(@file_exists($features_header_file)
+ && @is_readable($features_header_file))
+ ) {
+ return array();
+ }
+ if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) {
+ return $this->_parseFeaturesHeaderFile($features_header_file);
+ } // no cpp
+
+ return $this->_fromGlibCTest();
+ }
+
+ function _parseFeaturesHeaderFile($features_header_file)
+ {
+ $features_file = fopen($features_header_file, 'rb');
+ while (!feof($features_file)) {
+ $line = fgets($features_file, 8192);
+ if (!$this->_IsADefinition($line)) {
+ continue;
+ }
+ if (strpos($line, '__GLIBC__')) {
+ // major version number #define __GLIBC__ version
+ $line = preg_split('/\s+/', $line);
+ $glibc_major = trim($line[2]);
+ if (isset($glibc_minor)) {
break;
}
+ continue;
}
- pclose($cpp);
- unlink($tmpfile);
- } // features.h
-
- if (!($major && $minor) && @is_link('/lib/libc.so.6')) {
- // Let's try reading the libc.so.6 symlink
- if (preg_match('/^libc-(.*)\.so$/', basename(readlink('/lib/libc.so.6')), $matches)) {
- list($major, $minor) = explode('.', $matches[1]);
+
+ if (strpos($line, '__GLIBC_MINOR__')) {
+ // got the minor version number
+ // #define __GLIBC_MINOR__ version
+ $line = preg_split('/\s+/', $line);
+ $glibc_minor = trim($line[2]);
+ if (isset($glibc_major)) {
+ break;
+ }
}
}
+ fclose($features_file);
+ if (!isset($glibc_major) || !isset($glibc_minor)) {
+ return array();
+ }
+ return array(trim($glibc_major), trim($glibc_minor));
+ }
- if (!($major && $minor)) {
- return $glibc = '';
+ function _IsADefinition($line)
+ {
+ if ($line === false) {
+ return false;
}
+ return strpos(trim($line), '#define') !== false;
+ }
- return $glibc = "glibc{$major}.{$minor}";
+ function _fromGlibCTest()
+ {
+ $major = null;
+ $minor = null;
+
+ $tmpfile = System::mktemp("glibctest");
+ $fp = fopen($tmpfile, "w");
+ fwrite($fp, "#include \n__GLIBC__ __GLIBC_MINOR__\n");
+ fclose($fp);
+ $cpp = popen("/usr/bin/cpp $tmpfile", "r");
+ while ($line = fgets($cpp, 1024)) {
+ if ($line[0] == '#' || trim($line) == '') {
+ continue;
+ }
+
+ if (list($major, $minor) = explode(' ', trim($line))) {
+ break;
+ }
+ }
+ pclose($cpp);
+ unlink($tmpfile);
+ if ($major !== null && $minor !== null) {
+ return [$major, $minor];
+ }
}
function getSignature()
@@ -322,12 +376,16 @@ function matchSignature($match)
function _matchFragment($fragment, $value)
{
if (strcspn($fragment, '*?') < strlen($fragment)) {
- $reg = '/^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '\\z/';
+ $expression = str_replace(
+ array('*', '?', '/'),
+ array('.*', '.', '\\/'),
+ $fragment
+ );
+ $reg = '/^' . $expression . '\\z/';
return preg_match($reg, $value);
}
return ($fragment == '*' || !strcasecmp($fragment, $value));
}
-
}
/*
* Local Variables:
diff --git a/WEB-INF/lib/pear/PEAR.php b/WEB-INF/lib/pear/PEAR.php
index d661cc212..38ffedf29 100644
--- a/WEB-INF/lib/pear/PEAR.php
+++ b/WEB-INF/lib/pear/PEAR.php
@@ -75,7 +75,7 @@
* @author Greg Beaver
* @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @see PEAR_Error
* @since Class available since PHP 4.0.2
@@ -170,7 +170,7 @@ function __construct($error_class = null)
$destructor = "_$classname";
if (method_exists($this, $destructor)) {
global $_PEAR_destructor_object_list;
- $_PEAR_destructor_object_list[] = &$this;
+ $_PEAR_destructor_object_list[] = $this;
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
register_shutdown_function("_PEAR_call_destructors");
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
@@ -219,7 +219,7 @@ public function __call($method, $arguments)
);
}
return call_user_func_array(
- array(get_class(), '_' . $method),
+ array(__CLASS__, '_' . $method),
array_merge(array($this), $arguments)
);
}
@@ -232,7 +232,7 @@ public static function __callStatic($method, $arguments)
);
}
return call_user_func_array(
- array(get_class(), '_' . $method),
+ array(__CLASS__, '_' . $method),
array_merge(array(null), $arguments)
);
}
@@ -450,7 +450,7 @@ function _checkDelExpect($error_code)
}
/**
- * This method deletes all occurences of the specified element from
+ * This method deletes all occurrences of the specified element from
* the expected error codes stack.
*
* @param mixed $error_code error code that should be deleted
@@ -542,7 +542,7 @@ protected static function _raiseError($object,
count($object->_expected_errors) > 0 &&
count($exp = end($object->_expected_errors))
) {
- if ($exp[0] == "*" ||
+ if ($exp[0] === "*" ||
(is_int(reset($exp)) && in_array($code, $exp)) ||
(is_string(reset($exp)) && in_array($message, $exp))
) {
@@ -598,11 +598,11 @@ protected static function _raiseError($object,
protected static function _throwError($object, $message = null, $code = null, $userinfo = null)
{
if ($object !== null) {
- $a = &$object->raiseError($message, $code, null, null, $userinfo);
+ $a = $object->raiseError($message, $code, null, null, $userinfo);
return $a;
}
- $a = &PEAR::raiseError($message, $code, null, null, $userinfo);
+ $a = PEAR::raiseError($message, $code, null, null, $userinfo);
return $a;
}
@@ -766,6 +766,28 @@ function_exists('dl') === false ||
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
}
+
+ /**
+ * Get SOURCE_DATE_EPOCH environment variable
+ * See https://reproducible-builds.org/specs/source-date-epoch/
+ *
+ * @return int
+ * @access public
+ */
+ static function getSourceDateEpoch()
+ {
+ if ($source_date_epoch = getenv('SOURCE_DATE_EPOCH')) {
+ if (preg_match('/^\d+$/', $source_date_epoch)) {
+ return (int) $source_date_epoch;
+ } else {
+ // "If the value is malformed, the build process SHOULD exit with a non-zero error code."
+ self::raiseError("Invalid SOURCE_DATE_EPOCH: $source_date_epoch");
+ exit(1);
+ }
+ } else {
+ return time();
+ }
+ }
}
function _PEAR_call_destructors()
@@ -782,7 +804,7 @@ function _PEAR_call_destructors()
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
}
- while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
+ foreach ($_PEAR_destructor_object_list as $k => $objref) {
$classname = get_class($objref);
while ($classname) {
$destructor = "_$classname";
@@ -823,7 +845,7 @@ function _PEAR_call_destructors()
* @author Gregory Beaver
* @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/manual/en/core.pear.pear-error.php
* @see PEAR::raiseError(), PEAR::throwError()
* @since Class available since PHP 4.0.2
@@ -837,6 +859,7 @@ class PEAR_Error
var $message = '';
var $userinfo = '';
var $backtrace = null;
+ var $callback = null;
/**
* PEAR_Error constructor
@@ -914,7 +937,8 @@ function __construct($message = 'unknown error', $code = null,
} else {
$format = $options;
}
- die(sprintf($format, $msg));
+ printf($format, $msg);
+ exit($code);
}
if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) {
diff --git a/WEB-INF/lib/pear/PEAR/Autoloader.php b/WEB-INF/lib/pear/PEAR/Autoloader.php
deleted file mode 100644
index bcb57f65b..000000000
--- a/WEB-INF/lib/pear/PEAR/Autoloader.php
+++ /dev/null
@@ -1,217 +0,0 @@
-
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
- * @since File available since Release 0.1
- * @deprecated File deprecated in Release 1.4.0a1
- */
-
-// /* vim: set expandtab tabstop=4 shiftwidth=4: */
-
-if (!extension_loaded("overload")) {
- // die hard without ext/overload
- die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader");
-}
-
-/**
- * Include for PEAR_Error and PEAR classes
- */
-require_once "PEAR.php";
-
-/**
- * This class is for objects where you want to separate the code for
- * some methods into separate classes. This is useful if you have a
- * class with not-frequently-used methods that contain lots of code
- * that you would like to avoid always parsing.
- *
- * The PEAR_Autoloader class provides autoloading and aggregation.
- * The autoloading lets you set up in which classes the separated
- * methods are found. Aggregation is the technique used to import new
- * methods, an instance of each class providing separated methods is
- * stored and called every time the aggregated method is called.
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
- * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
- * @since File available since Release 0.1
- * @deprecated File deprecated in Release 1.4.0a1
- */
-class PEAR_Autoloader extends PEAR
-{
- // {{{ properties
-
- /**
- * Map of methods and classes where they are defined
- *
- * @var array
- *
- * @access private
- */
- var $_autoload_map = array();
-
- /**
- * Map of methods and aggregate objects
- *
- * @var array
- *
- * @access private
- */
- var $_method_map = array();
-
- // }}}
- // {{{ addAutoload()
-
- /**
- * Add one or more autoload entries.
- *
- * @param string $method which method to autoload
- *
- * @param string $classname (optional) which class to find the method in.
- * If the $method parameter is an array, this
- * parameter may be omitted (and will be ignored
- * if not), and the $method parameter will be
- * treated as an associative array with method
- * names as keys and class names as values.
- *
- * @return void
- *
- * @access public
- */
- function addAutoload($method, $classname = null)
- {
- if (is_array($method)) {
- array_walk($method, create_function('$a,&$b', '$b = strtolower($b);'));
- $this->_autoload_map = array_merge($this->_autoload_map, $method);
- } else {
- $this->_autoload_map[strtolower($method)] = $classname;
- }
- }
-
- // }}}
- // {{{ removeAutoload()
-
- /**
- * Remove an autoload entry.
- *
- * @param string $method which method to remove the autoload entry for
- *
- * @return bool TRUE if an entry was removed, FALSE if not
- *
- * @access public
- */
- function removeAutoload($method)
- {
- $method = strtolower($method);
- $ok = isset($this->_autoload_map[$method]);
- unset($this->_autoload_map[$method]);
- return $ok;
- }
-
- // }}}
- // {{{ addAggregateObject()
-
- /**
- * Add an aggregate object to this object. If the specified class
- * is not defined, loading it will be attempted following PEAR's
- * file naming scheme. All the methods in the class will be
- * aggregated, except private ones (name starting with an
- * underscore) and constructors.
- *
- * @param string $classname what class to instantiate for the object.
- *
- * @return void
- *
- * @access public
- */
- function addAggregateObject($classname)
- {
- $classname = strtolower($classname);
- if (!class_exists($classname)) {
- $include_file = preg_replace('/[^a-z0-9]/i', '_', $classname);
- include_once $include_file;
- }
- $obj = new $classname;
- $methods = get_class_methods($classname);
- foreach ($methods as $method) {
- // don't import priviate methods and constructors
- if ($method{0} != '_' && $method != $classname) {
- $this->_method_map[$method] = $obj;
- }
- }
- }
-
- // }}}
- // {{{ removeAggregateObject()
-
- /**
- * Remove an aggregate object.
- *
- * @param string $classname the class of the object to remove
- *
- * @return bool TRUE if an object was removed, FALSE if not
- *
- * @access public
- */
- function removeAggregateObject($classname)
- {
- $ok = false;
- $classname = strtolower($classname);
- reset($this->_method_map);
- while (list($method, $obj) = each($this->_method_map)) {
- if (is_a($obj, $classname)) {
- unset($this->_method_map[$method]);
- $ok = true;
- }
- }
- return $ok;
- }
-
- // }}}
- // {{{ __call()
-
- /**
- * Overloaded object call handler, called each time an
- * undefined/aggregated method is invoked. This method repeats
- * the call in the right aggregate object and passes on the return
- * value.
- *
- * @param string $method which method that was called
- *
- * @param string $args An array of the parameters passed in the
- * original call
- *
- * @return mixed The return value from the aggregated method, or a PEAR
- * error if the called method was unknown.
- */
- function __call($method, $args, &$retval)
- {
- $method = strtolower($method);
- if (empty($this->_method_map[$method]) && isset($this->_autoload_map[$method])) {
- $this->addAggregateObject($this->_autoload_map[$method]);
- }
- if (isset($this->_method_map[$method])) {
- $retval = call_user_func_array(array($this->_method_map[$method], $method), $args);
- return true;
- }
- return false;
- }
-
- // }}}
-}
-
-overload("PEAR_Autoloader");
-
-?>
diff --git a/WEB-INF/lib/pear/PEAR/Builder.php b/WEB-INF/lib/pear/PEAR/Builder.php
index 94b09f08d..de44a2df0 100644
--- a/WEB-INF/lib/pear/PEAR/Builder.php
+++ b/WEB-INF/lib/pear/PEAR/Builder.php
@@ -33,7 +33,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since PHP 4.0.2
* @see http://pear.php.net/manual/en/core.ppm.pear-builder.php
@@ -56,17 +56,72 @@ class PEAR_Builder extends PEAR_Common
var $_lastline = null;
var $_firstline = null;
+ /**
+ * Parsed --configureoptions.
+ *
+ * @var mixed[]
+ */
+ var $_parsed_configure_options;
+
/**
* PEAR_Builder constructor.
*
+ * @param mixed[] $configureoptions
* @param object $ui user interface object (instance of PEAR_Frontend_*)
*
* @access public
*/
- function __construct(&$ui)
+ function __construct($configureoptions, &$ui)
{
parent::__construct();
$this->setFrontendObject($ui);
+ $this->_parseConfigureOptions($configureoptions);
+ }
+
+ /**
+ * Parse --configureoptions string.
+ *
+ * @param string Options, in the form "X=1 Y=2 Z='there\'s always one'"
+ */
+ function _parseConfigureOptions($options)
+ {
+ $data = '';
+ $parser = xml_parser_create('ISO-8859-1');
+ xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+ xml_set_element_handler(
+ $parser, array($this, '_parseConfigureOptionsStartElement'),
+ array($this, '_parseConfigureOptionsEndElement'));
+ xml_parse($parser, $data, true);
+ xml_parser_free($parser);
+ }
+
+ /**
+ * Handle element start.
+ *
+ * @see PEAR_Builder::_parseConfigureOptions()
+ *
+ * @param resource $parser
+ * @param string $tagName
+ * @param mixed[] $attribs
+ */
+ function _parseConfigureOptionsStartElement($parser, $tagName, $attribs)
+ {
+ if ($tagName !== 'PROPERTIES') {
+ return;
+ }
+ $this->_parsed_configure_options = $attribs;
+ }
+
+ /**
+ * Handle element end.
+ *
+ * @see PEAR_Builder::_parseConfigureOptions()
+ *
+ * @param resource
+ * @param string $element
+ */
+ function _parseConfigureOptionsEndElement($parser, $element)
+ {
}
/**
@@ -136,7 +191,7 @@ function _build_win32($descfile, $callback = null)
// msdev doesn't tell us the output directory :/
// open the dsp, find /out and use that directory
- $dsptext = join(file($dsp),'');
+ $dsptext = join('', file($dsp));
// this regex depends on the build platform and type having been
// correctly identified above.
@@ -191,7 +246,7 @@ function _harvestInstDir($dest_prefix, $dirname, &$built_files)
$ret = true;
while (($ent = readdir($d)) !== false) {
- if ($ent{0} == '.')
+ if ($ent[0] == '.')
continue;
$full = $dirname . DIRECTORY_SEPARATOR . $ent;
@@ -276,7 +331,7 @@ function build($descfile, $callback = null)
} else {
$dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName();
// automatically delete at session end
- $this->addTempFile($dir);
+ self::addTempFile($dir);
}
} else {
$pf = new PEAR_PackageFile($this->config);
@@ -307,7 +362,10 @@ function build($descfile, $callback = null)
$dir = getcwd();
$this->log(2, "building in $dir");
- putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH'));
+ $binDir = $this->config->get('bin_dir');
+ if (!preg_match('@(^|:)' . preg_quote($binDir, '@') . '(:|$)@', getenv('PATH'))) {
+ putenv('PATH=' . $binDir . ':' . getenv('PATH'));
+ }
$err = $this->_runCommand($this->config->get('php_prefix')
. "phpize" .
$this->config->get('php_suffix'),
@@ -334,17 +392,19 @@ function build($descfile, $callback = null)
$configure_options = $pkg->getConfigureOptions();
if ($configure_options) {
- foreach ($configure_options as $o) {
- $default = array_key_exists('default', $o) ? $o['default'] : null;
- list($r) = $this->ui->userDialog('build',
- array($o['prompt']),
- array('text'),
- array($default));
- if (substr($o['name'], 0, 5) == 'with-' &&
- ($r == 'yes' || $r == 'autodetect')) {
- $configure_command .= " --$o[name]";
+ foreach ($configure_options as $option) {
+ $default = array_key_exists('default', $option) ? $option['default'] : null;
+ if (array_key_exists($option['name'], $this->_parsed_configure_options)) {
+ $response = $this->_parsed_configure_options[$option['name']];
+ } else {
+ list($response) = $this->ui->userDialog(
+ 'build', [$option['prompt']], ['text'], [$default]);
+ }
+ if (substr($option['name'], 0, 5) === 'with-' &&
+ ($response === 'yes' || $response === 'autodetect')) {
+ $configure_command .= " --{$option['name']}";
} else {
- $configure_command .= " --$o[name]=".trim($r);
+ $configure_command .= " --{$option['name']}=".trim($response);
}
}
}
@@ -368,11 +428,11 @@ function build($descfile, $callback = null)
return $this->raiseError("could not create build dir: $build_dir");
}
- $this->addTempFile($build_dir);
+ self::addTempFile($build_dir);
if (!System::mkDir(array('-p', $inst_dir))) {
return $this->raiseError("could not create temporary install dir: $inst_dir");
}
- $this->addTempFile($inst_dir);
+ self::addTempFile($inst_dir);
$make_command = getenv('MAKE') ? getenv('MAKE') : 'make';
@@ -385,7 +445,7 @@ function build($descfile, $callback = null)
if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) {
return $this->raiseError("could not chdir to $build_dir");
}
- putenv('PHP_PEAR_VERSION=1.10.1');
+ putenv('PHP_PEAR_VERSION=1.10.15');
foreach ($to_run as $cmd) {
$err = $this->_runCommand($cmd, $callback);
if (PEAR::isError($err)) {
diff --git a/WEB-INF/lib/pear/PEAR/ChannelFile.php b/WEB-INF/lib/pear/PEAR/ChannelFile.php
index f993764c8..1a36045c9 100644
--- a/WEB-INF/lib/pear/PEAR/ChannelFile.php
+++ b/WEB-INF/lib/pear/PEAR/ChannelFile.php
@@ -145,7 +145,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/ChannelFile/Parser.php b/WEB-INF/lib/pear/PEAR/ChannelFile/Parser.php
index a27e8fd06..1903b9752 100644
--- a/WEB-INF/lib/pear/PEAR/ChannelFile/Parser.php
+++ b/WEB-INF/lib/pear/PEAR/ChannelFile/Parser.php
@@ -25,7 +25,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Command.php b/WEB-INF/lib/pear/PEAR/Command.php
index 9ec55507d..246cedc6b 100644
--- a/WEB-INF/lib/pear/PEAR/Command.php
+++ b/WEB-INF/lib/pear/PEAR/Command.php
@@ -93,7 +93,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -233,7 +233,7 @@ public static function registerCommands($merge = false, $dir = null)
}
while ($file = readdir($dp)) {
- if ($file{0} == '.' || substr($file, -4) != '.xml') {
+ if ($file[0] == '.' || substr($file, -4) != '.xml') {
continue;
}
diff --git a/WEB-INF/lib/pear/PEAR/Command/Auth.php b/WEB-INF/lib/pear/PEAR/Command/Auth.php
index aa021ec26..1f6b0dcf3 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Auth.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Auth.php
@@ -29,7 +29,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
* @deprecated since 1.8.0alpha1
diff --git a/WEB-INF/lib/pear/PEAR/Command/Build.php b/WEB-INF/lib/pear/PEAR/Command/Build.php
index 7f851932d..bb6f0b6c5 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Build.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Build.php
@@ -30,7 +30,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -41,7 +41,13 @@ class PEAR_Command_Build extends PEAR_Command_Common
'summary' => 'Build an Extension From C Source',
'function' => 'doBuild',
'shortcut' => 'b',
- 'options' => array(),
+ 'options' => array(
+ 'configureoptions' => array(
+ 'shortopt' => 'D',
+ 'arg' => 'OPTION1=VALUE[ OPTION2=VALUE]',
+ 'doc' => 'space-delimited list of configure options',
+ ),
+ ),
'doc' => '[package.xml]
Builds one or more extensions contained in a package.'
),
@@ -64,7 +70,8 @@ function doBuild($command, $options, $params)
$params[0] = 'package.xml';
}
- $builder = new PEAR_Builder($this->ui);
+ $configureoptions = empty($options['configureoptions']) ? '' : $options['configureoptions'];
+ $builder = new PEAR_Builder($configureoptions, $this->ui);
$this->debug = $this->config->get('verbose');
$err = $builder->build($params[0], array(&$this, 'buildCallback'));
if (PEAR::isError($err)) {
diff --git a/WEB-INF/lib/pear/PEAR/Command/Build.xml b/WEB-INF/lib/pear/PEAR/Command/Build.xml
index ec4e6f554..507f17926 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Build.xml
+++ b/WEB-INF/lib/pear/PEAR/Command/Build.xml
@@ -3,7 +3,12 @@
Build an Extension From C Source
doBuild
b
-
+
+
+ D
+ OPTION1=VALUE[ OPTION2=VALUE]
+
+
[package.xml]
Builds one or more extensions contained in a package.
diff --git a/WEB-INF/lib/pear/PEAR/Command/Channels.php b/WEB-INF/lib/pear/PEAR/Command/Channels.php
index 690483d1d..4ccd83155 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Channels.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Channels.php
@@ -31,7 +31,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -673,7 +673,7 @@ function doAlias($command, $options, $params)
return $this->raiseError('No channel alias specified');
}
- if (count($params) !== 2 || (!empty($params[1]) && $params[1]{0} == '-')) {
+ if (count($params) !== 2 || (!empty($params[1]) && $params[1][0] == '-')) {
return $this->raiseError(
'Invalid format, correct is: channel-alias channel alias');
}
diff --git a/WEB-INF/lib/pear/PEAR/Command/Common.php b/WEB-INF/lib/pear/PEAR/Command/Common.php
index 4be537629..3356bbcd4 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Common.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Common.php
@@ -28,7 +28,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -143,10 +143,10 @@ function getGetoptArgs($command, &$short_args, &$long_args)
}
reset($this->commands[$command]['options']);
- while (list($option, $info) = each($this->commands[$command]['options'])) {
+ foreach ($this->commands[$command]['options'] as $option => $info) {
$larg = $sarg = '';
if (isset($info['arg'])) {
- if ($info['arg']{0} == '(') {
+ if ($info['arg'][0] == '(') {
$larg = '==';
$sarg = '::';
$arg = substr($info['arg'], 1, -1);
@@ -193,7 +193,7 @@ function getHelp($command)
$help = $this->commands[$command]['summary'];
}
- if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) {
+ if (preg_match_all('/{config\s+([^\}]+)}/', $help, $matches)) {
foreach($matches[0] as $k => $v) {
$help = preg_replace("/$v/", $config->get($matches[1][$k]), $help);
}
diff --git a/WEB-INF/lib/pear/PEAR/Command/Config.php b/WEB-INF/lib/pear/PEAR/Command/Config.php
index 705a7cbb8..122a48e5e 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Config.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Config.php
@@ -28,7 +28,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -315,7 +315,7 @@ function doConfigCreate($command, $options, $params)
$root = preg_replace(array('!\\\\+!', '!/+!', "!$ds2+!"),
array('/', '/', '/'),
$root);
- if ($root{0} != '/') {
+ if ($root[0] != '/') {
if (!isset($options['windows'])) {
return PEAR::raiseError('Root directory must be an absolute path beginning ' .
'with "/", was: "' . $root . '"');
@@ -338,7 +338,7 @@ function doConfigCreate($command, $options, $params)
$params[1] = realpath($params[1]);
$config = new PEAR_Config($params[1], '#no#system#config#', false, false);
- if ($root{strlen($root) - 1} == '/') {
+ if ($root[strlen($root) - 1] == '/') {
$root = substr($root, 0, strlen($root) - 1);
}
diff --git a/WEB-INF/lib/pear/PEAR/Command/Install.php b/WEB-INF/lib/pear/PEAR/Command/Install.php
index 9d572eda8..8146060d6 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Install.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Install.php
@@ -29,7 +29,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -67,6 +67,11 @@ class PEAR_Command_Install extends PEAR_Command_Common
'shortopt' => 'B',
'doc' => 'don\'t build C extensions',
),
+ 'configureoptions' => array(
+ 'shortopt' => 'D',
+ 'arg' => 'OPTION1=VALUE[ OPTION2=VALUE]',
+ 'doc' => 'space-delimited list of configure options',
+ ),
'nocompress' => array(
'shortopt' => 'Z',
'doc' => 'request uncompressed files when downloading',
@@ -717,8 +722,7 @@ function doInstall($command, $options, $params)
$pkg = &$param->getPackageFile();
if ($info->getCode() != PEAR_INSTALLER_NOBINARY) {
if (!($info = $pkg->installBinary($this->installer))) {
- $this->ui->outputData('ERROR: ' .$oldinfo->getMessage());
- continue;
+ return $this->raiseError('ERROR: ' .$oldinfo->getMessage());
}
// we just installed a different package than requested,
diff --git a/WEB-INF/lib/pear/PEAR/Command/Install.xml b/WEB-INF/lib/pear/PEAR/Command/Install.xml
index 1b1e933c2..d163bd581 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Install.xml
+++ b/WEB-INF/lib/pear/PEAR/Command/Install.xml
@@ -28,6 +28,10 @@
B
don't build C extensions
+
+ D
+ OPTION1=VALUE[ OPTION2=VALUE]
+
Z
request uncompressed files when downloading
diff --git a/WEB-INF/lib/pear/PEAR/Command/Mirror.php b/WEB-INF/lib/pear/PEAR/Command/Mirror.php
index bae7ad13e..52eace535 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Mirror.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Mirror.php
@@ -26,7 +26,7 @@
* @author Alexander Merz
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.2.0
*/
diff --git a/WEB-INF/lib/pear/PEAR/Command/Package.php b/WEB-INF/lib/pear/PEAR/Command/Package.php
index c62948f1e..fa51f004d 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Package.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Package.php
@@ -872,7 +872,6 @@ function doPackageDependencies($command, $options, $params)
$deps = $info->getDependencies();
$reg = &$this->config->getRegistry();
if (is_array($deps)) {
- $d = new PEAR_Dependency2($this->config, array(), '');
$data = array(
'caption' => 'Dependencies for ' . $info->getPackage(),
'border' => true,
@@ -929,7 +928,7 @@ function doPackageDependencies($command, $options, $params)
if (isset($inf['conflicts'])) {
$ver = 'conflicts';
} else {
- $ver = $d->_getExtraString($inf);
+ $ver = PEAR_Dependency2::_getExtraString($inf);
}
$data['data'][] = array($req, ucfirst($deptype), $name,
diff --git a/WEB-INF/lib/pear/PEAR/Command/Pickle.php b/WEB-INF/lib/pear/PEAR/Command/Pickle.php
index af6079b69..fe84137cd 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Pickle.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Pickle.php
@@ -26,7 +26,7 @@
* @author Greg Beaver
* @copyright 2005-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Command/Registry.php b/WEB-INF/lib/pear/PEAR/Command/Registry.php
index 37ee48bea..cb39f551d 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Registry.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Registry.php
@@ -28,7 +28,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -585,8 +585,9 @@ function doInfo($command, $options, $params)
case 'configure_options' : {
foreach ($info[$key] as $i => $p) {
$info[$key][$i] = array_map(null, array_keys($p), array_values($p));
- $info[$key][$i] = array_map(create_function('$a',
- 'return join(" = ",$a);'), $info[$key][$i]);
+ $info[$key][$i] = array_map(
+ function($a) { return join(" = ", $a); },
+ $info[$key][$i]);
$info[$key][$i] = implode(', ', $info[$key][$i]);
}
$info[$key] = implode("\n", $info[$key]);
diff --git a/WEB-INF/lib/pear/PEAR/Command/Remote.php b/WEB-INF/lib/pear/PEAR/Command/Remote.php
index f73db24f8..da47b8e73 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Remote.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Remote.php
@@ -30,7 +30,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -222,7 +222,7 @@ function doRemoteInfo($command, $options, $params)
}
$installed = $reg->packageInfo($info['name'], null, $channel);
- $info['installed'] = $installed['version'] ? $installed['version'] : '- no -';
+ $info['installed'] = $installed ? $installed['version'] : '- no -';
if (is_array($info['installed'])) {
$info['installed'] = $info['installed']['release'];
}
@@ -351,7 +351,7 @@ function doListAll($command, $options, $params)
foreach ($available as $name => $info) {
$installed = $reg->packageInfo($name, null, $channel);
- if (is_array($installed['version'])) {
+ if ($installed && is_array($installed['version'])) {
$installed['version'] = $installed['version']['release'];
}
$desc = $info['summary'];
@@ -589,7 +589,7 @@ function doDownload($command, $options, $params)
// eliminate error messages for preferred_state-related errors
/* TODO: Should be an option, but until now download does respect
- prefered state */
+ preferred state */
/* $options['ignorepreferred_state'] = 1; */
// eliminate error messages for preferred_state-related errors
diff --git a/WEB-INF/lib/pear/PEAR/Command/Test.php b/WEB-INF/lib/pear/PEAR/Command/Test.php
index a59b1cf81..18f533cde 100644
--- a/WEB-INF/lib/pear/PEAR/Command/Test.php
+++ b/WEB-INF/lib/pear/PEAR/Command/Test.php
@@ -30,7 +30,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Common.php b/WEB-INF/lib/pear/PEAR/Common.php
index 5fe76ad18..5a05e261b 100644
--- a/WEB-INF/lib/pear/PEAR/Common.php
+++ b/WEB-INF/lib/pear/PEAR/Common.php
@@ -117,7 +117,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @deprecated This class will disappear, and its components will be spread
@@ -205,7 +205,7 @@ function _PEAR_Common()
*
* @access public
*/
- function addTempFile($file)
+ static function addTempFile($file)
{
if (!class_exists('PEAR_Frontend')) {
require_once 'PEAR/Frontend.php';
@@ -280,7 +280,7 @@ function mkTempDir($tmpdir = '')
return false;
}
- $this->addTempFile($tmpdir);
+ self::addTempFile($tmpdir);
return $tmpdir;
}
@@ -304,7 +304,7 @@ function setFrontendObject(&$ui)
* @param boolean Determines whether to include $state in the list
* @return false|array False if $state is not a valid release state
*/
- function betterStates($state, $include = false)
+ static function betterStates($state, $include = false)
{
static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
$i = array_search($state, $states);
@@ -686,7 +686,7 @@ function buildProvidesArray($srcinfo)
foreach ($methods as $method) {
$function = "$class::$method";
$key = "function;$function";
- if ($method{0} == '_' || !strcasecmp($method, $class) ||
+ if ($method[0] == '_' || !strcasecmp($method, $class) ||
isset($this->pkginfo['provides'][$key])) {
continue;
}
@@ -698,7 +698,7 @@ function buildProvidesArray($srcinfo)
foreach ($srcinfo['declared_functions'] as $function) {
$key = "function;$function";
- if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) {
+ if ($function[0] == '_' || isset($this->pkginfo['provides'][$key])) {
continue;
}
@@ -718,7 +718,7 @@ function buildProvidesArray($srcinfo)
* @return mixed
* @access public
*/
- function analyzeSourceCode($file)
+ static function analyzeSourceCode($file)
{
if (!class_exists('PEAR_PackageFile_v2_Validator')) {
require_once 'PEAR/PackageFile/v2/Validator.php';
diff --git a/WEB-INF/lib/pear/PEAR/Config.php b/WEB-INF/lib/pear/PEAR/Config.php
index 3856acb10..1e83cb2c8 100644
--- a/WEB-INF/lib/pear/PEAR/Config.php
+++ b/WEB-INF/lib/pear/PEAR/Config.php
@@ -79,11 +79,7 @@
if (getenv('PHP_PEAR_INSTALL_DIR')) {
define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR'));
} else {
- if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) {
- define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
- } else {
- define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
- }
+ define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
}
// Default for metadata_dir
@@ -264,7 +260,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -727,7 +723,7 @@ public static function &singleton($user_file = '', $system_file = '', $strict =
$t_conf = new PEAR_Config($user_file, $system_file, false, $strict);
if ($t_conf->_errorsFound > 0) {
- return $t_conf->lastError;
+ return $t_conf->_lastError;
}
$GLOBALS['_PEAR_Config_instance'] = &$t_conf;
@@ -775,7 +771,7 @@ function readConfigFile($file = null, $layer = 'user', $strict = true)
}
$this->_errorsFound++;
- $this->lastError = $data;
+ $this->_lastError = $data;
return $data;
}
@@ -928,7 +924,7 @@ function mergeConfigFile($file, $override = true, $layer = 'user', $strict = tru
}
$this->_errorsFound++;
- $this->lastError = $data;
+ $this->_lastError = $data;
return $data;
}
@@ -2086,13 +2082,13 @@ function &getFTP()
return $a;
}
- function _prependPath($path, $prepend)
+ static function _prependPath($path, $prepend)
{
if (strlen($prepend) > 0) {
if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) {
if (preg_match('/^[a-z]:/i', $prepend)) {
$prepend = substr($prepend, 2);
- } elseif ($prepend{0} != '\\') {
+ } elseif ($prepend[0] != '\\') {
$prepend = "\\$prepend";
}
$path = substr($path, 0, 2) . $prepend . substr($path, 2);
diff --git a/WEB-INF/lib/pear/PEAR/Dependency2.php b/WEB-INF/lib/pear/PEAR/Dependency2.php
index 635c551ec..cb0a8178f 100644
--- a/WEB-INF/lib/pear/PEAR/Dependency2.php
+++ b/WEB-INF/lib/pear/PEAR/Dependency2.php
@@ -30,7 +30,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -110,7 +110,7 @@ function __construct(&$config, $installoptions, $package,
$this->_currentPackage = $package;
}
- function _getExtraString($dep)
+ static function _getExtraString($dep)
{
$extra = ' (';
if (isset($dep['uri'])) {
@@ -337,7 +337,7 @@ function validateExtensionDependency($dep, $required = true)
}
$loaded = $this->extension_loaded($dep['name']);
- $extra = $this->_getExtraString($dep);
+ $extra = self::_getExtraString($dep);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
@@ -486,7 +486,7 @@ function validatePhpDependency($dep)
}
$version = $this->phpversion();
- $extra = $this->_getExtraString($dep);
+ $extra = self::_getExtraString($dep);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
@@ -540,13 +540,13 @@ function validatePhpDependency($dep)
*/
function getPEARVersion()
{
- return '1.10.1';
+ return '1.10.15';
}
function validatePearinstallerDependency($dep)
{
$pearversion = $this->getPEARVersion();
- $extra = $this->_getExtraString($dep);
+ $extra = self::_getExtraString($dep);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
@@ -700,7 +700,7 @@ function _validatePackageDownload($dep, $required, $params, $depv1 = false)
}
}
- $extra = $this->_getExtraString($dep);
+ $extra = self::_getExtraString($dep);
if (isset($dep['exclude']) && !is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
@@ -1098,7 +1098,7 @@ function _validatePackageUninstall($dep, $required, $dl)
return true;
}
- $extra = $this->_getExtraString($dep);
+ $extra = self::_getExtraString($dep);
if (isset($dep['exclude']) && !is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
@@ -1232,7 +1232,7 @@ function validateDependency1($dep, $params = array())
$dep['optional'] = 'no';
}
- list($newdep, $type) = $this->normalizeDep($dep);
+ list($newdep, $type) = self::normalizeDep($dep);
if (!$newdep) {
return $this->raiseError("Invalid Dependency");
}
@@ -1246,7 +1246,7 @@ function validateDependency1($dep, $params = array())
/**
* Convert a 1.0 dep into a 2.0 dep
*/
- function normalizeDep($dep)
+ static function normalizeDep($dep)
{
$types = array(
'pkg' => 'Package',
@@ -1325,7 +1325,7 @@ function normalizeDep($dep)
* @param string Operator
* @return string Sign equivalent
*/
- function signOperator($operator)
+ static function signOperator($operator)
{
switch($operator) {
case 'lt': return '<';
diff --git a/WEB-INF/lib/pear/PEAR/DependencyDB.php b/WEB-INF/lib/pear/PEAR/DependencyDB.php
index 1ee604343..ede1fe0ef 100644
--- a/WEB-INF/lib/pear/PEAR/DependencyDB.php
+++ b/WEB-INF/lib/pear/PEAR/DependencyDB.php
@@ -29,7 +29,7 @@
* @author Tomas V.V.Cox
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -174,7 +174,7 @@ function assertDepsDB()
$this->rebuildDB();
}
- if ($depdb['_version']{0} > $this->_version{0}) {
+ if ($depdb['_version'][0] > $this->_version[0]) {
return PEAR::raiseError('Dependency database is version ' .
$depdb['_version'] . ', and we are version ' .
$this->_version . ', cannot continue');
@@ -216,9 +216,11 @@ function getDependentPackageDependencies(&$pkg)
if (is_object($pkg)) {
$channel = strtolower($pkg->getChannel());
$package = strtolower($pkg->getPackage());
- } else {
+ } else if (is_array($pkg)) {
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
+ } else {
+ return false;
}
$depend = $this->getDependentPackages($pkg);
@@ -499,8 +501,9 @@ function _lock($mode = LOCK_EX)
}
if (!is_resource($this->_lockFp)) {
+ $last_errormsg = error_get_last();
return PEAR::raiseError("could not create Dependency lock file" .
- (isset($php_errormsg) ? ": " . $php_errormsg : ""));
+ (isset($last_errormsg) ? ": " . $last_errormsg : ""));
}
if (!(int)flock($this->_lockFp, $mode)) {
diff --git a/WEB-INF/lib/pear/PEAR/Downloader.php b/WEB-INF/lib/pear/PEAR/Downloader.php
index 6d6cdd7a2..9d4f98243 100644
--- a/WEB-INF/lib/pear/PEAR/Downloader.php
+++ b/WEB-INF/lib/pear/PEAR/Downloader.php
@@ -20,6 +20,7 @@
* Needed for constants, extending
*/
require_once 'PEAR/Common.php';
+require_once 'PEAR/Proxy.php';
define('PEAR_INSTALLER_OK', 1);
define('PEAR_INSTALLER_FAILED', 0);
@@ -38,7 +39,7 @@
* @author Martin Jansen
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.3.0
*/
@@ -61,11 +62,12 @@ class PEAR_Downloader extends PEAR_Common
* Options from command-line passed to Install.
*
* Recognized options:
- * - onlyreqdeps : install all required dependencies as well
- * - alldeps : install all dependencies, including optional
- * - installroot : base relative path to install files in
- * - force : force a download even if warnings would prevent it
- * - nocompress : download uncompressed tarballs
+ * - onlyreqdeps : install all required dependencies as well
+ * - alldeps : install all dependencies, including optional
+ * - installroot : base relative path to install files in
+ * - force : force a download even if warnings would prevent it
+ * - nocompress : download uncompressed tarballs
+ * - configureoptions : additional configure options
* @see PEAR_Command_Install
* @access private
* @var array
@@ -167,7 +169,7 @@ function __construct($ui = null, $options = array(), $config = null)
}
$this->ui = &$ui;
if (!$this->_preferredState) {
- // don't inadvertantly use a non-set preferred_state
+ // don't inadvertently use a non-set preferred_state
$this->_preferredState = null;
}
@@ -184,7 +186,7 @@ function __construct($ui = null, $options = array(), $config = null)
if (!count($unused)) {
continue;
}
- $strtolower = create_function('$a','return strtolower($a);');
+ $strtolower = function($a) { return strtolower($a); };
array_walk($this->_installed[$key], $strtolower);
}
}
@@ -786,7 +788,7 @@ function configSet($key, $value, $layer = 'user', $channel = false)
$this->config->set($key, $value, $layer, $channel);
$this->_preferredState = $this->config->get('preferred_state', null, $channel);
if (!$this->_preferredState) {
- // don't inadvertantly use a non-set preferred_state
+ // don't inadvertently use a non-set preferred_state
$this->_preferredState = null;
}
}
@@ -848,7 +850,7 @@ function _getPackageDownloadUrl($parr)
!($base = $chan->getBaseURL('REST1.0', $preferred_mirror))
)
) {
- return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.');
+ return $this->raiseError($parr['channel'] . ' is using an unsupported protocol - This should never happen. Use --force to continue');
}
if ($base2) {
@@ -1155,7 +1157,7 @@ function _prependPath($path, $prepend)
if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) {
if (preg_match('/^[a-z]:/i', $prepend)) {
$prepend = substr($prepend, 2);
- } elseif ($prepend{0} != '\\') {
+ } elseif ($prepend[0] != '\\') {
$prepend = "\\$prepend";
}
$path = substr($path, 0, 2) . $prepend . substr($path, 2);
@@ -1584,20 +1586,10 @@ public static function _downloadHttp(
$config = &PEAR_Config::singleton();
}
- $proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
- if ($config->get('http_proxy') &&
- $proxy = parse_url($config->get('http_proxy'))) {
- $proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
- if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') {
- $proxy_host = 'ssl://' . $proxy_host;
- }
- $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080;
- $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
- $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
+ $proxy = new PEAR_Proxy($config);
- if ($callback) {
- call_user_func($callback, 'message', "Using HTTP proxy $host:$port");
- }
+ if ($proxy->isProxyConfigured() && $callback) {
+ call_user_func($callback, 'message', "Using HTTP proxy $host:$port");
}
if (empty($port)) {
@@ -1605,47 +1597,30 @@ public static function _downloadHttp(
}
$scheme = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http';
+ $secure = ($scheme == 'https');
- if ($proxy_host != '') {
- $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr);
- if (!$fp) {
- if ($callback) {
- call_user_func($callback, 'connfailed', array($proxy_host, $proxy_port,
- $errno, $errstr));
- }
- return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno);
- }
-
- if ($lastmodified === false || $lastmodified) {
- $request = "GET $url HTTP/1.1\r\n";
- $request .= "Host: $host\r\n";
- } else {
- $request = "GET $url HTTP/1.0\r\n";
- $request .= "Host: $host\r\n";
- }
- } else {
- $network_host = $host;
- if (isset($info['scheme']) && $info['scheme'] == 'https') {
- $network_host = 'ssl://' . $host;
+ $fp = $proxy->openSocket($host, $port, $secure);
+ if (PEAR::isError($fp)) {
+ if ($callback) {
+ $errno = $fp->getCode();
+ $errstr = $fp->getMessage();
+ call_user_func($callback, 'connfailed', array($host, $port,
+ $errno, $errstr));
}
+ return $fp;
+ }
- $fp = @fsockopen($network_host, $port, $errno, $errstr);
- if (!$fp) {
- if ($callback) {
- call_user_func($callback, 'connfailed', array($host, $port,
- $errno, $errstr));
- }
- return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
- }
+ $requestPath = $path;
+ if ($proxy->isProxyConfigured()) {
+ $requestPath = $url;
+ }
- if ($lastmodified === false || $lastmodified) {
- $request = "GET $path HTTP/1.1\r\n";
- $request .= "Host: $host\r\n";
- } else {
- $request = "GET $path HTTP/1.0\r\n";
- $request .= "Host: $host\r\n";
- }
+ if ($lastmodified === false || $lastmodified) {
+ $request = "GET $requestPath HTTP/1.1\r\n";
+ } else {
+ $request = "GET $requestPath HTTP/1.0\r\n";
}
+ $request .= "Host: $host\r\n";
$ifmodifiedsince = '';
if (is_array($lastmodified)) {
@@ -1661,7 +1636,7 @@ public static function _downloadHttp(
}
$request .= $ifmodifiedsince .
- "User-Agent: PEAR/1.10.1/PHP/" . PHP_VERSION . "\r\n";
+ "User-Agent: PEAR/1.10.15/PHP/" . PHP_VERSION . "\r\n";
if ($object !== null) { // only pass in authentication for non-static calls
$username = $config->get('username', null, $channel);
@@ -1672,9 +1647,10 @@ public static function _downloadHttp(
}
}
- if ($proxy_host != '' && $proxy_user != '') {
+ $proxyAuth = $proxy->getProxyAuth();
+ if ($proxyAuth) {
$request .= 'Proxy-Authorization: Basic ' .
- base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n";
+ $proxyAuth . "\r\n";
}
if ($accept) {
@@ -1737,7 +1713,8 @@ public static function _downloadHttp(
if (!$wp = @fopen($dest_file, 'wb')) {
fclose($fp);
if ($callback) {
- call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg));
+ call_user_func($callback, 'writefailed',
+ array($dest_file, error_get_last()["message"]));
}
return PEAR::raiseError("could not open $dest_file for writing");
}
@@ -1757,9 +1734,11 @@ public static function _downloadHttp(
if (!@fwrite($wp, $data)) {
fclose($fp);
if ($callback) {
- call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg));
+ call_user_func($callback, 'writefailed',
+ array($dest_file, error_get_last()["message"]));
}
- return PEAR::raiseError("$dest_file: write failed ($php_errormsg)");
+ return PEAR::raiseError(
+ "$dest_file: write failed (" . error_get_last()["message"] . ")");
}
}
diff --git a/WEB-INF/lib/pear/PEAR/Downloader/Package.php b/WEB-INF/lib/pear/PEAR/Downloader/Package.php
index fe979eb67..b47f4935e 100644
--- a/WEB-INF/lib/pear/PEAR/Downloader/Package.php
+++ b/WEB-INF/lib/pear/PEAR/Downloader/Package.php
@@ -49,7 +49,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -1507,7 +1507,7 @@ function &getPackagefileObject(&$c, $d)
function _fromFile(&$param)
{
$saveparam = $param;
- if (is_string($param)) {
+ if (is_string($param) && substr($param, 0, 10) !== 'channel://') {
if (!@file_exists($param)) {
$test = explode('#', $param);
$group = array_pop($test);
diff --git a/WEB-INF/lib/pear/PEAR/ErrorStack.php b/WEB-INF/lib/pear/PEAR/ErrorStack.php
index 7b705bdbb..1085e4421 100644
--- a/WEB-INF/lib/pear/PEAR/ErrorStack.php
+++ b/WEB-INF/lib/pear/PEAR/ErrorStack.php
@@ -131,7 +131,7 @@
* $local_stack = new PEAR_ErrorStack('MyPackage');
*
* @author Greg Beaver
- * @version 1.10.1
+ * @version 1.10.15
* @package PEAR_ErrorStack
* @category Debugging
* @copyright 2004-2008 Greg Beaver
@@ -676,7 +676,7 @@ function pop()
* @return boolean
* @since PEAR1.5.0a1
*/
- function staticPop($package)
+ static function staticPop($package)
{
if ($package) {
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
diff --git a/WEB-INF/lib/pear/PEAR/Exception.php b/WEB-INF/lib/pear/PEAR/Exception.php
index 0aba17104..8ea888106 100644
--- a/WEB-INF/lib/pear/PEAR/Exception.php
+++ b/WEB-INF/lib/pear/PEAR/Exception.php
@@ -88,7 +88,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.3.3
*
diff --git a/WEB-INF/lib/pear/PEAR/Frontend.php b/WEB-INF/lib/pear/PEAR/Frontend.php
index 8c8c8c6b4..43c618e04 100644
--- a/WEB-INF/lib/pear/PEAR/Frontend.php
+++ b/WEB-INF/lib/pear/PEAR/Frontend.php
@@ -38,7 +38,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -160,7 +160,7 @@ function setConfig(&$config)
* needs to be able to sustain a list over many sessions in order to support
* user interaction with install scripts
*/
- function addTempFile($file)
+ static function addTempFile($file)
{
$GLOBALS['_PEAR_Common_tempfiles'][] = $file;
}
@@ -220,4 +220,4 @@ function outputData($data, $command = '_default')
function userDialog($command, $prompts, $types = array(), $defaults = array())
{
}
-}
\ No newline at end of file
+}
diff --git a/WEB-INF/lib/pear/PEAR/Frontend/CLI.php b/WEB-INF/lib/pear/PEAR/Frontend/CLI.php
index f0723d039..3bae041b2 100644
--- a/WEB-INF/lib/pear/PEAR/Frontend/CLI.php
+++ b/WEB-INF/lib/pear/PEAR/Frontend/CLI.php
@@ -26,7 +26,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer.php b/WEB-INF/lib/pear/PEAR/Installer.php
index d5cc7df69..35649e933 100644
--- a/WEB-INF/lib/pear/PEAR/Installer.php
+++ b/WEB-INF/lib/pear/PEAR/Installer.php
@@ -35,7 +35,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -225,7 +225,7 @@ function _installFile($file, $atts, $tmp_path, $options)
$os = new OS_Guess();
}
- if (strlen($atts['platform']) && $atts['platform']{0} == '!') {
+ if (strlen($atts['platform']) && $atts['platform'][0] == '!') {
$negate = true;
$platform = substr($atts['platform'], 1);
} else {
@@ -323,8 +323,9 @@ function _installFile($file, $atts, $tmp_path, $options)
}
if (!@copy($orig_file, $dest_file)) {
- return $this->raiseError("failed to write $dest_file: $php_errormsg",
- PEAR_INSTALLER_FAILED);
+ return $this->raiseError(
+ "failed to write $dest_file: " . error_get_last()["message"],
+ PEAR_INSTALLER_FAILED);
}
$this->log(3, "+ cp $orig_file $dest_file");
@@ -399,13 +400,15 @@ function _installFile($file, $atts, $tmp_path, $options)
$wp = @fopen($dest_file, "wb");
if (!is_resource($wp)) {
- return $this->raiseError("failed to create $dest_file: $php_errormsg",
- PEAR_INSTALLER_FAILED);
+ return $this->raiseError(
+ "failed to create $dest_file: " . error_get_last()["message"],
+ PEAR_INSTALLER_FAILED);
}
if (@fwrite($wp, $contents) === false) {
- return $this->raiseError("failed writing to $dest_file: $php_errormsg",
- PEAR_INSTALLER_FAILED);
+ return $this->raiseError(
+ "failed writing to $dest_file: " . error_get_last()["message"],
+ PEAR_INSTALLER_FAILED);
}
fclose($wp);
@@ -452,7 +455,8 @@ function _installFile($file, $atts, $tmp_path, $options)
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
- $this->log(0, "failed to change mode of $dest_file: $php_errormsg");
+ $this->log(0, "failed to change mode of $dest_file: " .
+ error_get_last()["message"]);
}
}
}
@@ -562,8 +566,9 @@ function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options)
}
if (!@copy($orig_file, $dest_file)) {
- return $this->raiseError("failed to write $dest_file: $php_errormsg",
- PEAR_INSTALLER_FAILED);
+ return $this->raiseError(
+ "failed to write $dest_file: " . error_get_last()["message"],
+ PEAR_INSTALLER_FAILED);
}
$this->log(3, "+ cp $orig_file $dest_file");
@@ -605,13 +610,15 @@ function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options)
$wp = @fopen($dest_file, "wb");
if (!is_resource($wp)) {
- return $this->raiseError("failed to create $dest_file: $php_errormsg",
- PEAR_INSTALLER_FAILED);
+ return $this->raiseError(
+ "failed to create $dest_file: " . error_get_last()["message"],
+ PEAR_INSTALLER_FAILED);
}
if (fwrite($wp, $contents) === false) {
- return $this->raiseError("failed writing to $dest_file: $php_errormsg",
- PEAR_INSTALLER_FAILED);
+ return $this->raiseError(
+ "failed writing to $dest_file: " . error_get_last()["message"],
+ PEAR_INSTALLER_FAILED);
}
fclose($wp);
@@ -667,7 +674,8 @@ function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options)
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
- $this->log(0, "failed to change mode of $dest_file: $php_errormsg");
+ $this->log(0, "failed to change mode of $dest_file: " .
+ error_get_last()["message"]);
}
}
}
@@ -854,7 +862,7 @@ function commitFileTransaction()
if (!@copy($data[0], $data[0] . '.bak')) {
$this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] .
- '.bak ' . $php_errormsg);
+ '.bak ' . error_get_last()["message"]);
return false;
}
$this->log(3, "+ backup $data[0] to $data[0].bak");
@@ -889,7 +897,7 @@ function commitFileTransaction()
$perms = @fileperms($data[0]);
if (!@copy($data[0], $data[1])) {
$this->log(1, 'Could not rename ' . $data[0] . ' to ' . $data[1] .
- ' ' . $php_errormsg);
+ ' ' . error_get_last()["message"]);
return false;
}
@@ -901,7 +909,7 @@ function commitFileTransaction()
case 'chmod':
if (!@chmod($data[1], $data[0])) {
$this->log(1, 'Could not chmod ' . $data[1] . ' to ' .
- decoct($data[0]) . ' ' . $php_errormsg);
+ decoct($data[0]) . ' ' . error_get_last()["message"]);
return false;
}
@@ -912,7 +920,7 @@ function commitFileTransaction()
if (file_exists($data[0])) {
if (!@unlink($data[0])) {
$this->log(1, 'Could not delete ' . $data[0] . ' ' .
- $php_errormsg);
+ error_get_last()["message"]);
return false;
}
$this->log(3, "+ rm $data[0]");
@@ -934,7 +942,7 @@ function commitFileTransaction()
closedir($testme);
if (!@rmdir($data[0])) {
$this->log(1, 'Could not rmdir ' . $data[0] . ' ' .
- $php_errormsg);
+ error_get_last()["message"]);
return false;
}
$this->log(3, "+ rmdir $data[0]");
@@ -1263,7 +1271,7 @@ function install($pkgfile, $options = array())
if (count($test)) {
$msg = "$channel/$pkgname: conflicting files found:\n";
$longest = max(array_map("strlen", array_keys($test)));
- $fmt = "%${longest}s (%s)\n";
+ $fmt = "%{$longest}s (%s)\n";
foreach ($test as $file => $info) {
if (!is_array($info)) {
$info = array('pear.php.net', $info);
@@ -1403,8 +1411,9 @@ function install($pkgfile, $options = array())
// {{{ compile and install source files
if ($this->source_files > 0 && empty($options['nobuild'])) {
+ $configureoptions = empty($options['configureoptions']) ? '' : $options['configureoptions'];
if (PEAR::isError($err =
- $this->_compileSourceFiles($savechannel, $pkg))) {
+ $this->_compileSourceFiles($savechannel, $pkg, $configureoptions))) {
return $err;
}
}
@@ -1501,12 +1510,13 @@ function install($pkgfile, $options = array())
/**
* @param string
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+ * @param mixed[] $configureoptions
*/
- function _compileSourceFiles($savechannel, &$filelist)
+ function _compileSourceFiles($savechannel, &$filelist, $configureoptions)
{
require_once 'PEAR/Builder.php';
$this->log(1, "$this->source_files source files, building");
- $bob = new PEAR_Builder($this->ui);
+ $bob = new PEAR_Builder($configureoptions, $this->ui);
$bob->debug = $this->debug;
$built = $bob->build($filelist, array(&$this, '_buildCallback'));
if (PEAR::isError($built)) {
@@ -1519,11 +1529,11 @@ function _compileSourceFiles($savechannel, &$filelist)
foreach ($built as $ext) {
$bn = basename($ext['file']);
list($_ext_name, $_ext_suff) = explode('.', $bn);
- if ($_ext_suff == '.so' || $_ext_suff == '.dll') {
+ if ($_ext_suff == 'so' || $_ext_suff == 'dll') {
if (extension_loaded($_ext_name)) {
- $this->raiseError("Extension '$_ext_name' already loaded. " .
- 'Please unload it in your php.ini file ' .
- 'prior to install or upgrade');
+ return $this->raiseError("Extension '$_ext_name' already loaded. " .
+ 'Please unload it in your php.ini file ' .
+ 'prior to install or upgrade');
}
$role = 'ext';
} else {
@@ -1553,7 +1563,9 @@ function _compileSourceFiles($savechannel, &$filelist)
}
if (!@copy($ext['file'], $copyto)) {
- return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED);
+ return $this->raiseError(
+ "failed to write $copyto (" . error_get_last()["message"] . ")",
+ PEAR_INSTALLER_FAILED);
}
$this->log(3, "+ cp $ext[file] $copyto");
@@ -1562,7 +1574,8 @@ function _compileSourceFiles($savechannel, &$filelist)
$mode = 0666 & ~(int)octdec($this->config->get('umask'));
$this->addFileOperation('chmod', array($mode, $copyto));
if (!@chmod($copyto, $mode)) {
- $this->log(0, "failed to change mode of $copyto ($php_errormsg)");
+ $this->log(0, "failed to change mode of $copyto (" .
+ error_get_last()["message"] . ")");
}
}
}
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role.php b/WEB-INF/lib/pear/PEAR/Installer/Role.php
index 0623424a2..e03ba96f7 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role.php
@@ -24,7 +24,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -237,7 +237,7 @@ public static function registerRoles($dir = null)
}
while ($entry = readdir($dp)) {
- if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
+ if ($entry[0] == '.' || substr($entry, -4) != '.xml') {
continue;
}
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Cfg.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Cfg.php
index 903b1d641..f6c4c3783 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Cfg.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Cfg.php
@@ -19,7 +19,7 @@
* @author Greg Beaver
* @copyright 2007-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.7.0
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Common.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Common.php
index df0b3c66c..8d6be6a8e 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Common.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Common.php
@@ -23,7 +23,7 @@
* @author Greg Beaver
* @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Data.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Data.php
index 1a2c9c30c..b87c08fb3 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Data.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Data.php
@@ -19,7 +19,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Doc.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Doc.php
index 675cc8777..989e58549 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Doc.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Doc.php
@@ -19,7 +19,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Ext.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Ext.php
index 6224e2b89..5c1f225ee 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Ext.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Ext.php
@@ -19,7 +19,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Man.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Man.php
index 5c3a842b8..e478e45c2 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Man.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Man.php
@@ -20,7 +20,7 @@
* @author Hannes Magnusson
* @copyright 2011 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.10.0
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Php.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Php.php
index d1b97a863..ff2df61eb 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Php.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Php.php
@@ -19,7 +19,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Script.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Script.php
index f1eeda0b6..fbf0a2675 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Script.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Script.php
@@ -19,7 +19,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Src.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Src.php
index 2c7ae2142..6b20e4182 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Src.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Src.php
@@ -19,7 +19,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Test.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Test.php
index c19c5dc06..43f352687 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Test.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Test.php
@@ -19,7 +19,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Installer/Role/Www.php b/WEB-INF/lib/pear/PEAR/Installer/Role/Www.php
index 42b197a90..2799f7bd0 100644
--- a/WEB-INF/lib/pear/PEAR/Installer/Role/Www.php
+++ b/WEB-INF/lib/pear/PEAR/Installer/Role/Www.php
@@ -19,7 +19,7 @@
* @author Greg Beaver
* @copyright 2007-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.7.0
*/
diff --git a/WEB-INF/lib/pear/PEAR/PackageFile.php b/WEB-INF/lib/pear/PEAR/PackageFile.php
index 8fb6e41fa..cd279c338 100644
--- a/WEB-INF/lib/pear/PEAR/PackageFile.php
+++ b/WEB-INF/lib/pear/PEAR/PackageFile.php
@@ -34,7 +34,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -94,13 +94,13 @@ function setLogger(&$l)
*/
function &parserFactory($version)
{
- if (!in_array($version{0}, array('1', '2'))) {
+ if (!in_array($version[0], array('1', '2'))) {
$a = false;
return $a;
}
- include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php';
- $version = $version{0};
+ include_once 'PEAR/PackageFile/Parser/v' . $version[0] . '.php';
+ $version = $version[0];
$class = "PEAR_PackageFile_Parser_v$version";
$a = new $class;
return $a;
@@ -122,13 +122,13 @@ function getClassPrefix()
*/
function &factory($version)
{
- if (!in_array($version{0}, array('1', '2'))) {
+ if (!in_array($version[0], array('1', '2'))) {
$a = false;
return $a;
}
- include_once 'PEAR/PackageFile/v' . $version{0} . '.php';
- $version = $version{0};
+ include_once 'PEAR/PackageFile/v' . $version[0] . '.php';
+ $version = $version[0];
$class = $this->getClassPrefix() . $version;
$a = new $class;
return $a;
@@ -283,13 +283,13 @@ function &fromXmlString($data, $state, $file, $archive = false)
* @param string $file name of file or directory
* @return void
*/
- function addTempFile($file)
+ static function addTempFile($file)
{
$GLOBALS['_PEAR_Common_tempfiles'][] = $file;
}
/**
- * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file.
+ * Create a PEAR_PackageFile_v* from a compressed Tar or Tgz file.
* @access public
* @param string contents of package.xml file
* @param int package state (one of PEAR_VALIDATE_* constants)
@@ -315,7 +315,7 @@ function &fromTgzFile($file, $state)
}
if (!is_array($content)) {
- if (is_string($file) && strlen($file < 255) &&
+ if (is_string($file) && strlen($file) < 255 &&
(!file_exists($file) || !@is_file($file))) {
$ret = PEAR::raiseError("could not open file \"$file\"");
return $ret;
diff --git a/WEB-INF/lib/pear/PEAR/PackageFile/Generator/v1.php b/WEB-INF/lib/pear/PEAR/PackageFile/Generator/v1.php
index 5a963787c..4b92695e2 100644
--- a/WEB-INF/lib/pear/PEAR/PackageFile/Generator/v1.php
+++ b/WEB-INF/lib/pear/PEAR/PackageFile/Generator/v1.php
@@ -28,7 +28,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -45,7 +45,7 @@ function __construct(&$packagefile)
function getPackagerVersion()
{
- return '1.10.1';
+ return '1.10.15';
}
/**
@@ -196,7 +196,7 @@ function toXml($state = PEAR_VALIDATE_NORMAL, $nofilevalidation = false)
);
$ret = "\n";
$ret .= "\n";
- $ret .= "\n" .
+ $ret .= "\n" .
" $pkginfo[package]";
if (isset($pkginfo['extends'])) {
$ret .= "\n$pkginfo[extends]";
@@ -738,8 +738,10 @@ function _convertDependencies2_0(&$release, $internal = false)
$php = $this->_processPhpDeps($deps['php']);
} else {
if (!isset($deps['php'][0])) {
- list($key, $blah) = each ($deps['php']); // stupid buggy versions
- $deps['php'] = array($blah[0]);
+ // Buggy versions
+ $key = key($deps['php']);
+ $info = current($deps['php']);
+ $deps['php'] = array($info[0]);
}
$php = $this->_processDep($deps['php'][0]);
if (!$php) {
@@ -887,13 +889,13 @@ function _convertRelease2_0(&$release, $package)
}
//o tags for
if (isset($package['platform'][$file]) &&
- $package['platform'][$file]{0} == '!') {
+ $package['platform'][$file][0] == '!') {
$generic[] = $file;
continue;
}
//o tags for
if (isset($package['platform'][$file]) &&
- $package['platform'][$file]{0} != '!') {
+ $package['platform'][$file][0] != '!') {
$genericIgnore[] = $file;
continue;
}
@@ -902,7 +904,7 @@ function _convertRelease2_0(&$release, $package)
if (isset($package['install-as'][$file])) {
continue;
}
- if ($platform{0} != '!') {
+ if ($platform[0] != '!') {
//o tags for
$genericIgnore[] = $file;
}
@@ -911,7 +913,7 @@ function _convertRelease2_0(&$release, $package)
$oses = $notplatform = $platform = array();
foreach ($package['platform'] as $file => $os) {
// get a list of oses
- if ($os{0} == '!') {
+ if ($os[0] == '!') {
if (isset($oses[substr($os, 1)])) {
continue;
}
@@ -957,7 +959,7 @@ function _convertRelease2_0(&$release, $package)
//
if (isset($package['platform'][$file]) &&
$package['platform'][$file] != "!$os" &&
- $package['platform'][$file]{0} == '!') {
+ $package['platform'][$file][0] == '!') {
$release[$releaseNum]['filelist']['install'][] =
array(
'attribs' => array(
@@ -982,7 +984,7 @@ function _convertRelease2_0(&$release, $package)
//o tags for
//
if (isset($package['platform'][$file]) &&
- $package['platform'][$file]{0} != '!' &&
+ $package['platform'][$file][0] != '!' &&
$package['platform'][$file] != $os) {
$release[$releaseNum]['filelist']['ignore'][] =
array(
@@ -1008,7 +1010,7 @@ function _convertRelease2_0(&$release, $package)
continue;
}
//o tags for
- if ($platform{0} != '!' && $platform != $os) {
+ if ($platform[0] != '!' && $platform != $os) {
$release[$releaseNum]['filelist']['ignore'][] =
array(
'attribs' => array(
diff --git a/WEB-INF/lib/pear/PEAR/PackageFile/Generator/v2.php b/WEB-INF/lib/pear/PEAR/PackageFile/Generator/v2.php
index 24e89f3aa..3866bd509 100644
--- a/WEB-INF/lib/pear/PEAR/PackageFile/Generator/v2.php
+++ b/WEB-INF/lib/pear/PEAR/PackageFile/Generator/v2.php
@@ -30,7 +30,7 @@
* @author Stephan Schmidt (original XML_Serializer code)
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -112,7 +112,7 @@ function __construct(&$packagefile)
*/
function getPackagerVersion()
{
- return '1.10.1';
+ return '1.10.15';
}
/**
@@ -397,7 +397,7 @@ function toXml($state = PEAR_VALIDATE_NORMAL, $options = array())
$this->options['beautifyFilelist'] = true;
}
- $arr['attribs']['packagerversion'] = '1.10.1';
+ $arr['attribs']['packagerversion'] = '1.10.15';
if ($this->serialize($arr, $options)) {
return $this->_serializedData . "\n";
}
@@ -781,7 +781,7 @@ function _serializeArray(&$array, $tagName = null, $attributes = array())
}
}
- if (is_string($value) && $value && ($value{strlen($value) - 1} == "\n")) {
+ if (is_string($value) && $value && ($value[strlen($value) - 1] == "\n")) {
$value .= str_repeat($this->options['indent'], $this->_tagDepth);
}
$tmp .= $this->_createXMLTag(array(
diff --git a/WEB-INF/lib/pear/PEAR/PackageFile/v1.php b/WEB-INF/lib/pear/PEAR/PackageFile/v1.php
index 413db67d1..69cdedad7 100644
--- a/WEB-INF/lib/pear/PEAR/PackageFile/v1.php
+++ b/WEB-INF/lib/pear/PEAR/PackageFile/v1.php
@@ -274,7 +274,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -1420,8 +1420,8 @@ function _analyzeSourceCode($file)
}
}
switch ($token) {
- case T_WHITESPACE :
- continue;
+ case T_WHITESPACE:
+ break;
case ';':
if ($interface) {
$current_function = '';
@@ -1575,7 +1575,7 @@ function _buildProvidesArray($srcinfo)
foreach ($methods as $method) {
$function = "$class::$method";
$key = "function;$function";
- if ($method{0} == '_' || !strcasecmp($method, $class) ||
+ if ($method[0] == '_' || !strcasecmp($method, $class) ||
isset($this->_packageInfo['provides'][$key])) {
continue;
}
@@ -1586,7 +1586,7 @@ function _buildProvidesArray($srcinfo)
foreach ($srcinfo['declared_functions'] as $function) {
$key = "function;$function";
- if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) {
+ if ($function[0] == '_' || isset($this->_packageInfo['provides'][$key])) {
continue;
}
if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
diff --git a/WEB-INF/lib/pear/PEAR/PackageFile/v2.php b/WEB-INF/lib/pear/PEAR/PackageFile/v2.php
index ae0a1fa89..b7cac639c 100644
--- a/WEB-INF/lib/pear/PEAR/PackageFile/v2.php
+++ b/WEB-INF/lib/pear/PEAR/PackageFile/v2.php
@@ -22,7 +22,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -423,12 +423,12 @@ function _differentName($handle, $name, $selfname)
function _unmatchedMaintainers($my, $yours)
{
if ($my) {
- array_walk($my, create_function('&$i, $k', '$i = $i["handle"];'));
+ array_walk($my, function(&$i, $k) { $i = $i["handle"]; });
$this->_stack->push(__FUNCTION__, 'error', array('handles' => $my),
'package.xml 2.0 has unmatched extra maintainers "%handles%"');
}
if ($yours) {
- array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];'));
+ array_walk($yours, function(&$i, $k) { $i = $i["handle"]; });
$this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours),
'package.xml 1.0 has unmatched extra maintainers "%handles%"');
}
@@ -625,15 +625,14 @@ function initPostinstallScripts()
$lastversion = isset($this->_packageInfo['_lastversion']) ?
$this->_packageInfo['_lastversion'] : null;
$task->init($raw, $atts, $lastversion);
- $res = $task->startSession($this, $atts['installed_as']);
+ $res = $task->startSession($this, $atts['installed_as'], null);
if (!$res) {
continue; // skip this file
}
if (PEAR::isError($res)) {
return $res;
}
- $assign = &$task;
- $this->_scripts[] = &$assign;
+ $this->_scripts[] = $task;
}
}
if (count($this->_scripts)) {
@@ -1669,7 +1668,7 @@ function getDeps($raw = false, $nopearinstaller = false)
if ($dtype == 'pearinstaller' && $nopearinstaller) {
continue;
}
- if (!isset($deps[0])) {
+ if ((is_array($deps) && !isset($deps[0])) || !is_array($deps)) {
$deps = array($deps);
}
foreach ($deps as $dep) {
@@ -2047,7 +2046,7 @@ function _mergeTag($manip, $contents, $order)
if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) {
$manip[$tag][] = $contents;
} else {
- if (!count($manip[$tag])) {
+ if (is_array($manip[$tag]) && !count($manip[$tag])) {
$manip[$tag] = $contents;
} else {
$manip[$tag] = array($manip[$tag]);
diff --git a/WEB-INF/lib/pear/PEAR/PackageFile/v2/Validator.php b/WEB-INF/lib/pear/PEAR/PackageFile/v2/Validator.php
index eff9d03ca..bbf3e523d 100644
--- a/WEB-INF/lib/pear/PEAR/PackageFile/v2/Validator.php
+++ b/WEB-INF/lib/pear/PEAR/PackageFile/v2/Validator.php
@@ -20,7 +20,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a8
* @access private
@@ -111,8 +111,8 @@ function validate(&$pf, $state = PEAR_VALIDATE_NORMAL)
isset($test['dependencies']['required']) &&
isset($test['dependencies']['required']['pearinstaller']) &&
isset($test['dependencies']['required']['pearinstaller']['min']) &&
- '1.10.1' != '@package' . '_version@' &&
- version_compare('1.10.1',
+ '1.10.15' != '@package' . '_version@' &&
+ version_compare('1.10.15',
$test['dependencies']['required']['pearinstaller']['min'], '<')
) {
$this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']);
@@ -419,7 +419,7 @@ function _processAttribs($choice, $tag, $context)
foreach ($tags as $i => $tag) {
if (!is_array($tag) || !isset($tag['attribs'])) {
foreach ($choice['attribs'] as $attrib) {
- if ($attrib{0} != '?') {
+ if ($attrib[0] != '?') {
$ret &= $this->_tagHasNoAttribs($choice['tag'],
$context);
continue 2;
@@ -427,7 +427,7 @@ function _processAttribs($choice, $tag, $context)
}
}
foreach ($choice['attribs'] as $attrib) {
- if ($attrib{0} != '?') {
+ if ($attrib[0] != '?') {
if (!isset($tag['attribs'][$attrib])) {
$ret &= $this->_tagMissingAttribute($choice['tag'],
$attrib, $context);
@@ -450,9 +450,9 @@ function _processStructure($key)
}
return $ret;
}
- $multi = $key{0};
+ $multi = $key[0];
if ($multi == '+' || $multi == '*') {
- $ret['multiple'] = $key{0};
+ $ret['multiple'] = $key[0];
$key = substr($key, 1);
}
if (count($attrs = explode('->', $key)) > 1) {
@@ -1080,8 +1080,8 @@ function _validateFilelist($list = false, $allowignore = false, $dirs = '')
foreach ($list['file'] as $i => $file)
{
if (isset($file['attribs']) && isset($file['attribs']['name'])) {
- if ($file['attribs']['name']{0} == '.' &&
- $file['attribs']['name']{1} == '/') {
+ if ($file['attribs']['name'][0] == '.' &&
+ $file['attribs']['name'][1] == '/') {
// name is something like "./doc/whatever.txt"
$this->_invalidFileName($file['attribs']['name'], $dirname);
}
@@ -1350,7 +1350,7 @@ function _pearVersionTooLow($version)
$this->_stack->push(__FUNCTION__, 'error',
array('version' => $version),
'This package.xml requires PEAR version %version% to parse properly, we are ' .
- 'version 1.10.1');
+ 'version 1.10.15');
}
function _invalidTagOrder($oktags, $actual, $root)
@@ -1930,7 +1930,7 @@ function analyzeSourceCode($file, $string = false)
switch ($token) {
case T_WHITESPACE :
- continue;
+ continue 2;
case ';':
if ($interface) {
$current_function = '';
@@ -2106,7 +2106,7 @@ function _buildProvidesArray($srcinfo)
foreach ($methods as $method) {
$function = "$class::$method";
$key = "function;$function";
- if ($method{0} == '_' || !strcasecmp($method, $class) ||
+ if ($method[0] == '_' || !strcasecmp($method, $class) ||
isset($providesret[$key])) {
continue;
}
@@ -2118,7 +2118,7 @@ function _buildProvidesArray($srcinfo)
foreach ($srcinfo['declared_functions'] as $function) {
$key = "function;$function";
- if ($function{0} == '_' || isset($providesret[$key])) {
+ if ($function[0] == '_' || isset($providesret[$key])) {
continue;
}
diff --git a/WEB-INF/lib/pear/PEAR/PackageFile/v2/rw.php b/WEB-INF/lib/pear/PEAR/PackageFile/v2/rw.php
index f2b58e396..0e007ef17 100644
--- a/WEB-INF/lib/pear/PEAR/PackageFile/v2/rw.php
+++ b/WEB-INF/lib/pear/PEAR/PackageFile/v2/rw.php
@@ -22,7 +22,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a8
*/
diff --git a/WEB-INF/lib/pear/PEAR/Packager.php b/WEB-INF/lib/pear/PEAR/Packager.php
index 3303f4c10..eb52f4a4f 100644
--- a/WEB-INF/lib/pear/PEAR/Packager.php
+++ b/WEB-INF/lib/pear/PEAR/Packager.php
@@ -30,7 +30,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Proxy.php b/WEB-INF/lib/pear/PEAR/Proxy.php
new file mode 100644
index 000000000..2f74631ff
--- /dev/null
+++ b/WEB-INF/lib/pear/PEAR/Proxy.php
@@ -0,0 +1,191 @@
+config = $config;
+ $this->_parseProxyInfo();
+ }
+
+ /**
+ * @access private
+ */
+ function _parseProxyInfo()
+ {
+ $this->proxy_host = $this->proxy_port = $this->proxy_user = $this->proxy_pass = '';
+ if ($this->config->get('http_proxy')&&
+ $proxy = parse_url($this->config->get('http_proxy'))
+ ) {
+ $this->proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
+
+ $this->proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080;
+ $this->proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
+ $this->proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
+ $this->proxy_schema = (isset($proxy['scheme']) && $proxy['scheme'] == 'https') ? 'https' : 'http';
+ }
+ }
+
+ /**
+ * @access private
+ */
+ function _httpConnect($fp, $host, $port)
+ {
+ fwrite($fp, "CONNECT $host:$port HTTP/1.1\r\n");
+ fwrite($fp, "Host: $host:$port\r\n");
+ if ($this->getProxyAuth()) {
+ fwrite($fp, 'Proxy-Authorization: Basic ' . $this->getProxyAuth() . "\r\n");
+ }
+ fwrite($fp, "\r\n");
+
+ while ($line = trim(fgets($fp, 1024))) {
+ if (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
+ $code = (int)$matches[1];
+
+ /* as per RFC 2817 */
+ if ($code < 200 || $code >= 300) {
+ return PEAR::raiseError("Establishing a CONNECT tunnel through proxy failed with response code $code");
+ }
+ }
+ }
+
+ // connection was successful -- establish SSL through
+ // the tunnel
+ $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
+
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
+ $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
+ $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
+ }
+
+ // set the correct hostname for working hostname
+ // verification
+ stream_context_set_option($fp, 'ssl', 'peer_name', $host);
+
+ // blocking socket needed for
+ // stream_socket_enable_crypto()
+ // see
+ //
+ stream_set_blocking ($fp, true);
+ $crypto_res = stream_socket_enable_crypto($fp, true, $crypto_method);
+ if (!$crypto_res) {
+ return PEAR::raiseError("Could not establish SSL connection through proxy: $crypto_res");
+ }
+
+ return true;
+ }
+
+ /**
+ * get the authorization information for the proxy, encoded to be
+ * passed in the Proxy-Authentication HTTP header.
+ * @return null|string the encoded authentication information if a
+ * proxy and authentication is configured, null
+ * otherwise.
+ */
+ function getProxyAuth()
+ {
+ if ($this->isProxyConfigured() && $this->proxy_user != '') {
+ return base64_encode($this->proxy_user . ':' . $this->proxy_pass);
+ }
+ return null;
+ }
+
+ function getProxyUser()
+ {
+ return $this->proxy_user;
+ }
+
+ /**
+ * Check if we are configured to use a proxy.
+ *
+ * @return boolean true if we are configured to use a proxy, false
+ * otherwise.
+ * @access public
+ */
+ function isProxyConfigured()
+ {
+ return $this->proxy_host != '';
+ }
+
+ /**
+ * Open a socket to a remote server, possibly involving a HTTP
+ * proxy.
+ *
+ * If an HTTP proxy has been configured (http_proxy PEAR_Config
+ * setting), the proxy will be used.
+ *
+ * @param string $host the host to connect to
+ * @param string $port the port to connect to
+ * @param boolean $secure if true, establish a secure connection
+ * using TLS.
+ * @access public
+ */
+ function openSocket($host, $port, $secure = false)
+ {
+ if ($this->isProxyConfigured()) {
+ $fp = @fsockopen(
+ $this->proxy_host, $this->proxy_port,
+ $errno, $errstr, 15
+ );
+
+ if (!$fp) {
+ return PEAR::raiseError("Connection to the proxy failed: $errstr", -9276);
+ }
+
+ /* HTTPS is to be used and we have a proxy, use CONNECT verb */
+ if ($secure) {
+ $res = $this->_httpConnect($fp, $host, $port);
+
+ if (PEAR::isError($res)) {
+ return $res;
+ }
+ }
+ } else {
+ if ($secure) {
+ $host = 'ssl://' . $host;
+ }
+
+ $fp = @fsockopen($host, $port, $errno, $errstr);
+ if (!$fp) {
+ return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
+ }
+ }
+
+ return $fp;
+ }
+}
diff --git a/WEB-INF/lib/pear/PEAR/REST.php b/WEB-INF/lib/pear/PEAR/REST.php
index c0dfeaa69..1c0b0a828 100644
--- a/WEB-INF/lib/pear/PEAR/REST.php
+++ b/WEB-INF/lib/pear/PEAR/REST.php
@@ -18,6 +18,7 @@
*/
require_once 'PEAR.php';
require_once 'PEAR/XMLParser.php';
+require_once 'PEAR/Proxy.php';
/**
* Intelligently retrieve data, following hyperlinks if necessary, and re-directing
@@ -27,7 +28,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -171,25 +172,24 @@ function retrieveData($url, $accept = false, $forcestring = false, $channel = fa
function useLocalCache($url, $cacheid = null)
{
- if ($cacheid === null) {
- $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
- md5($url) . 'rest.cacheid';
- if (!file_exists($cacheidfile)) {
- return false;
- }
-
- $cacheid = unserialize(implode('', file($cacheidfile)));
+ if (!is_array($cacheid)) {
+ $cacheid = $this->getCacheId($url);
}
$cachettl = $this->config->get('cache_ttl');
// If cache is newer than $cachettl seconds, we use the cache!
- if (time() - $cacheid['age'] < $cachettl) {
+ if (is_array($cacheid) && time() - $cacheid['age'] < $cachettl) {
return $this->getCache($url);
}
return false;
}
+ /**
+ * @param string $url
+ *
+ * @return bool|mixed
+ */
function getCacheId($url)
{
$cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
@@ -356,26 +356,13 @@ function downloadHttp($url, $lastmodified = null, $accept = false, $channel = fa
$path = isset($info['path']) ? $info['path'] : null;
$schema = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http';
- $proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
- if ($this->config->get('http_proxy')&&
- $proxy = parse_url($this->config->get('http_proxy'))
- ) {
- $proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
- if ($schema === 'https') {
- $proxy_host = 'ssl://' . $proxy_host;
- }
-
- $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080;
- $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
- $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
- $proxy_schema = (isset($proxy['scheme']) && $proxy['scheme'] == 'https') ? 'https' : 'http';
- }
+ $proxy = new PEAR_Proxy($this->config);
if (empty($port)) {
$port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80;
}
- if (isset($proxy['host'])) {
+ if ($proxy->isProxyConfigured() && $schema === 'http') {
$request = "GET $url HTTP/1.1\r\n";
} else {
$request = "GET $path HTTP/1.1\r\n";
@@ -396,7 +383,7 @@ function downloadHttp($url, $lastmodified = null, $accept = false, $channel = fa
}
$request .= $ifmodifiedsince .
- "User-Agent: PEAR/1.10.1/PHP/" . PHP_VERSION . "\r\n";
+ "User-Agent: PEAR/1.10.15/PHP/" . PHP_VERSION . "\r\n";
$username = $this->config->get('username', null, $channel);
$password = $this->config->get('password', null, $channel);
@@ -406,9 +393,10 @@ function downloadHttp($url, $lastmodified = null, $accept = false, $channel = fa
$request .= "Authorization: Basic $tmp\r\n";
}
- if ($proxy_host != '' && $proxy_user != '') {
+ $proxyAuth = $proxy->getProxyAuth();
+ if ($proxyAuth) {
$request .= 'Proxy-Authorization: Basic ' .
- base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n";
+ $proxyAuth . "\r\n";
}
if ($accept) {
@@ -419,20 +407,10 @@ function downloadHttp($url, $lastmodified = null, $accept = false, $channel = fa
$request .= "Connection: close\r\n";
$request .= "\r\n";
- if ($proxy_host != '') {
- $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 15);
- if (!$fp) {
- return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", -9276);
- }
- } else {
- if ($schema === 'https') {
- $host = 'ssl://' . $host;
- }
-
- $fp = @fsockopen($host, $port, $errno, $errstr);
- if (!$fp) {
- return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
- }
+ $secure = ($schema == 'https');
+ $fp = $proxy->openSocket($host, $port, $secure);
+ if (PEAR::isError($fp)) {
+ return $fp;
}
fwrite($fp, $request);
diff --git a/WEB-INF/lib/pear/PEAR/REST/10.php b/WEB-INF/lib/pear/PEAR/REST/10.php
index affcc18ee..79932ae72 100644
--- a/WEB-INF/lib/pear/PEAR/REST/10.php
+++ b/WEB-INF/lib/pear/PEAR/REST/10.php
@@ -26,7 +26,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a12
*/
diff --git a/WEB-INF/lib/pear/PEAR/REST/11.php b/WEB-INF/lib/pear/PEAR/REST/11.php
index 9bd51ba6f..7b5cbcffb 100644
--- a/WEB-INF/lib/pear/PEAR/REST/11.php
+++ b/WEB-INF/lib/pear/PEAR/REST/11.php
@@ -26,7 +26,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.3
*/
diff --git a/WEB-INF/lib/pear/PEAR/REST/13.php b/WEB-INF/lib/pear/PEAR/REST/13.php
index 3855c6e05..312ebe80d 100644
--- a/WEB-INF/lib/pear/PEAR/REST/13.php
+++ b/WEB-INF/lib/pear/PEAR/REST/13.php
@@ -27,7 +27,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a12
*/
diff --git a/WEB-INF/lib/pear/PEAR/Registry.php b/WEB-INF/lib/pear/PEAR/Registry.php
index c22d82f4a..b615b55f6 100644
--- a/WEB-INF/lib/pear/PEAR/Registry.php
+++ b/WEB-INF/lib/pear/PEAR/Registry.php
@@ -36,7 +36,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -780,7 +780,8 @@ function _readFileMap()
$fp = @fopen($this->filemap, 'r');
if (!$fp) {
- return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg);
+ $last_errormsg = error_get_last();
+ return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $last_errormsg);
}
clearstatcache();
@@ -906,7 +907,7 @@ function _channelExists($channel, $noaliases = false)
}
/**
- * Determine whether a mirror exists within the deafult channel in the registry
+ * Determine whether a mirror exists within the default channel in the registry
*
* @param string Channel name
* @param string Mirror name
@@ -1008,7 +1009,7 @@ function _addChannel($channel, $update = false, $lastmodified = false)
if ($lastmodified) {
$info['_lastmodified'] = $lastmodified;
} else {
- $info['_lastmodified'] = date('r');
+ $info['_lastmodified'] = self::getSourceDateEpoch();
}
fwrite($fp, serialize($info));
@@ -1187,7 +1188,7 @@ function _listChannels()
$dp = opendir($this->channelsdir);
while ($ent = readdir($dp)) {
- if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
+ if ($ent[0] == '.' || substr($ent, -4) != '.reg') {
continue;
}
@@ -1238,13 +1239,14 @@ function _listPackages($channel = false)
}
while ($ent = readdir($dp)) {
- if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
+ if ($ent[0] == '.' || substr($ent, -4) != '.reg') {
continue;
}
$pkglist[] = substr($ent, 0, -4);
}
closedir($dp);
+ sort($pkglist);
return $pkglist;
}
@@ -1262,7 +1264,7 @@ function _listChannelPackages($channel)
}
while ($ent = readdir($dp)) {
- if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
+ if ($ent[0] == '.' || substr($ent, -4) != '.reg') {
continue;
}
$pkglist[] = substr($ent, 0, -4);
@@ -1300,7 +1302,7 @@ function _addPackage($package, $info)
return false;
}
- $info['_lastmodified'] = time();
+ $info['_lastmodified'] = self::getSourceDateEpoch();
fwrite($fp, serialize($info));
$this->_closePackageFile($fp);
if (isset($info['filelist'])) {
@@ -1354,7 +1356,7 @@ function _addPackage2($info)
return false;
}
- $info['_lastmodified'] = time();
+ $info['_lastmodified'] = self::getSourceDateEpoch();
fwrite($fp, serialize($info));
$this->_closePackageFile($fp);
$this->_rebuildFileMap();
@@ -1382,7 +1384,7 @@ function _updatePackage($package, $info, $merge = true)
if (is_object($info)) {
$info = $info->toArray();
}
- $info['_lastmodified'] = time();
+ $info['_lastmodified'] = self::getSourceDateEpoch();
$newinfo = $info;
if ($merge) {
@@ -1418,7 +1420,7 @@ function _updatePackage2($info)
$save = $info;
$info = $save->getArray(true);
- $info['_lastmodified'] = time();
+ $info['_lastmodified'] = self::getSourceDateEpoch();
fwrite($fp, serialize($info));
$this->_closePackageFile($fp);
$this->_rebuildFileMap();
@@ -2064,7 +2066,7 @@ function checkFileMap($path, $package = false, $api = '1.0', $attrs = false)
if (!class_exists('PEAR_Installer_Role')) {
require_once 'PEAR/Installer/Role.php';
}
- $notempty = create_function('$a','return !empty($a);');
+ $notempty = function($a) { return !empty($a); };
}
$package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1]))
: strtolower($package);
@@ -2204,7 +2206,7 @@ function parsePackageName($param, $defaultchannel = 'pear.php.net')
}
if (!isset($components['scheme'])) {
if (strpos($components['path'], '/') !== false) {
- if ($components['path']{0} == '/') {
+ if ($components['path'][0] == '/') {
return PEAR::raiseError('parsePackageName(): this is not ' .
'a package name, it begins with "/" in "' . $param . '"',
'invalid', null, null, $param);
diff --git a/WEB-INF/lib/pear/PEAR/RunTest.php b/WEB-INF/lib/pear/PEAR/RunTest.php
index 59dedbf9b..ee3629f64 100644
--- a/WEB-INF/lib/pear/PEAR/RunTest.php
+++ b/WEB-INF/lib/pear/PEAR/RunTest.php
@@ -37,7 +37,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.3.3
*/
@@ -64,7 +64,6 @@ class PEAR_RunTest
'display_errors=1',
'log_errors=0',
'html_errors=0',
- 'track_errors=1',
'report_memleaks=0',
'report_zend_debug=0',
'docref_root=',
@@ -130,7 +129,8 @@ function system_with_timeout($commandline, $env = null, $stdin = null)
while (true) {
/* hide errors from interrupted syscalls */
$r = $pipes;
- $e = $w = null;
+ unset($r[0]);
+ $e = $w = [];
$n = @stream_select($r, $w, $e, 60);
if ($n === 0) {
@@ -343,7 +343,7 @@ function run($file, $ini_settings = array(), $test_number = 1)
// Check if test should be skipped.
$res = $this->_runSkipIf($section_text, $temp_skipif, $tested, $ini_settings);
- if (count($res) != 2) {
+ if ($res == 'SKIPPED' || count($res) != 2) {
return $res;
}
$info = $res['info'];
@@ -512,6 +512,7 @@ function run($file, $ini_settings = array(), $test_number = 1)
$wanted_re = preg_quote($wanted_re, '/');
// Stick to basics
$wanted_re = str_replace("%s", ".+?", $wanted_re); //not greedy
+ $wanted_re = str_replace("%S", ".*?", $wanted_re); //not greedy
$wanted_re = str_replace("%i", "[+\-]?[0-9]+", $wanted_re);
$wanted_re = str_replace("%d", "[0-9]+", $wanted_re);
$wanted_re = str_replace("%x", "[0-9a-fA-F]+", $wanted_re);
diff --git a/WEB-INF/lib/pear/PEAR/Task/Common.php b/WEB-INF/lib/pear/PEAR/Task/Common.php
index ebb71dc8a..e8b2adfdd 100644
--- a/WEB-INF/lib/pear/PEAR/Task/Common.php
+++ b/WEB-INF/lib/pear/PEAR/Task/Common.php
@@ -47,7 +47,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @abstract
diff --git a/WEB-INF/lib/pear/PEAR/Task/Postinstallscript.php b/WEB-INF/lib/pear/PEAR/Task/Postinstallscript.php
index 950deb5ce..3ba3ed7d6 100644
--- a/WEB-INF/lib/pear/PEAR/Task/Postinstallscript.php
+++ b/WEB-INF/lib/pear/PEAR/Task/Postinstallscript.php
@@ -27,7 +27,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -292,11 +292,12 @@ public function _stripNamespace($params = null)
*
* @param mixed $pkg PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param string $contents file name
+ * @param string $dest the eventual final file location (informational only)
*
* @return bool|PEAR_Error false to skip this file, PEAR_Error to fail
* (use $this->throwError)
*/
- public function startSession($pkg, $contents)
+ public function startSession($pkg, $contents, $dest)
{
if ($this->installphase != PEAR_TASK_INSTALL) {
return false;
@@ -343,7 +344,7 @@ public function startSession($pkg, $contents)
* @param string install or upgrade
* @access protected
*/
- public static function run()
+ public static function run($tasks)
{
}
}
diff --git a/WEB-INF/lib/pear/PEAR/Task/Postinstallscript/rw.php b/WEB-INF/lib/pear/PEAR/Task/Postinstallscript/rw.php
index 662960062..7f89ef9bc 100644
--- a/WEB-INF/lib/pear/PEAR/Task/Postinstallscript/rw.php
+++ b/WEB-INF/lib/pear/PEAR/Task/Postinstallscript/rw.php
@@ -23,7 +23,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
*/
@@ -159,7 +159,7 @@ public function getXml()
*
* @return array
*/
- public static function getParam(
+ public function getParam(
$name, $prompt, $type = 'string', $default = null
) {
if ($default !== null) {
diff --git a/WEB-INF/lib/pear/PEAR/Task/Replace.php b/WEB-INF/lib/pear/PEAR/Task/Replace.php
index 7483282bb..7b69fa198 100644
--- a/WEB-INF/lib/pear/PEAR/Task/Replace.php
+++ b/WEB-INF/lib/pear/PEAR/Task/Replace.php
@@ -23,7 +23,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Task/Replace/rw.php b/WEB-INF/lib/pear/PEAR/Task/Replace/rw.php
index ace1e9ea2..5f426dbcf 100644
--- a/WEB-INF/lib/pear/PEAR/Task/Replace/rw.php
+++ b/WEB-INF/lib/pear/PEAR/Task/Replace/rw.php
@@ -23,7 +23,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
*/
diff --git a/WEB-INF/lib/pear/PEAR/Task/Unixeol.php b/WEB-INF/lib/pear/PEAR/Task/Unixeol.php
index 6ef7174bb..093cf557a 100644
--- a/WEB-INF/lib/pear/PEAR/Task/Unixeol.php
+++ b/WEB-INF/lib/pear/PEAR/Task/Unixeol.php
@@ -23,7 +23,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Task/Unixeol/rw.php b/WEB-INF/lib/pear/PEAR/Task/Unixeol/rw.php
index 9134e2c93..621385473 100644
--- a/WEB-INF/lib/pear/PEAR/Task/Unixeol/rw.php
+++ b/WEB-INF/lib/pear/PEAR/Task/Unixeol/rw.php
@@ -23,7 +23,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
*/
diff --git a/WEB-INF/lib/pear/PEAR/Task/Windowseol.php b/WEB-INF/lib/pear/PEAR/Task/Windowseol.php
index 620c940fe..100637865 100644
--- a/WEB-INF/lib/pear/PEAR/Task/Windowseol.php
+++ b/WEB-INF/lib/pear/PEAR/Task/Windowseol.php
@@ -24,7 +24,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/PEAR/Task/Windowseol/rw.php b/WEB-INF/lib/pear/PEAR/Task/Windowseol/rw.php
index e3cf0052b..5c60fbe87 100644
--- a/WEB-INF/lib/pear/PEAR/Task/Windowseol/rw.php
+++ b/WEB-INF/lib/pear/PEAR/Task/Windowseol/rw.php
@@ -24,7 +24,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
*/
diff --git a/WEB-INF/lib/pear/PEAR/Validate.php b/WEB-INF/lib/pear/PEAR/Validate.php
index 8e29b7cd2..9326e521a 100644
--- a/WEB-INF/lib/pear/PEAR/Validate.php
+++ b/WEB-INF/lib/pear/PEAR/Validate.php
@@ -31,7 +31,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -209,7 +209,7 @@ function validatePackageName()
}
$vlen = strlen($test);
$majver = substr($name, strlen($name) - $vlen);
- while ($majver && !is_numeric($majver{0})) {
+ while ($majver && !is_numeric($majver[0])) {
$majver = substr($majver, 1);
}
if ($majver != $test) {
@@ -287,7 +287,7 @@ function validateVersion()
}
if (!$this->_packagexml->getExtends()) {
if ($versioncomponents[0] == '1') {
- if ($versioncomponents[2]{0} == '0') {
+ if ($versioncomponents[2][0] == '0') {
if ($versioncomponents[2] == '0') {
// version 1.*.0000
$this->_addWarning('version',
@@ -328,7 +328,7 @@ function validateVersion()
} else {
$vlen = strlen($versioncomponents[0] . '');
$majver = substr($name, strlen($name) - $vlen);
- while ($majver && !is_numeric($majver{0})) {
+ while ($majver && !is_numeric($majver[0])) {
$majver = substr($majver, 1);
}
if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) {
@@ -339,7 +339,7 @@ function validateVersion()
return true;
}
if ($versioncomponents[0] == $majver) {
- if ($versioncomponents[2]{0} == '0') {
+ if ($versioncomponents[2][0] == '0') {
if ($versioncomponents[2] == '0') {
// version 2.*.0000
$this->_addWarning('version',
@@ -398,7 +398,7 @@ function validateVersion()
if ($this->_packagexml->getExtends()) {
$vlen = strlen($versioncomponents[0] . '');
$majver = substr($name, strlen($name) - $vlen);
- while ($majver && !is_numeric($majver{0})) {
+ while ($majver && !is_numeric($majver[0])) {
$majver = substr($majver, 1);
}
if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) {
diff --git a/WEB-INF/lib/pear/PEAR/Validator/PECL.php b/WEB-INF/lib/pear/PEAR/Validator/PECL.php
index 830c8e9b2..a9d16934e 100644
--- a/WEB-INF/lib/pear/PEAR/Validator/PECL.php
+++ b/WEB-INF/lib/pear/PEAR/Validator/PECL.php
@@ -23,7 +23,7 @@
* @author Greg Beaver
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a5
*/
diff --git a/WEB-INF/lib/pear/PEAR/XMLParser.php b/WEB-INF/lib/pear/PEAR/XMLParser.php
index 619743bcd..d16c9535c 100644
--- a/WEB-INF/lib/pear/PEAR/XMLParser.php
+++ b/WEB-INF/lib/pear/PEAR/XMLParser.php
@@ -22,7 +22,7 @@
* @author Stephan Schmidt (original XML_Unserializer code)
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license New BSD License
- * @version Release: 1.10.1
+ * @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
diff --git a/WEB-INF/lib/pear/README.rst b/WEB-INF/lib/pear/README.rst
index ac8e6fd1a..9f5f7940c 100644
--- a/WEB-INF/lib/pear/README.rst
+++ b/WEB-INF/lib/pear/README.rst
@@ -61,28 +61,11 @@ Test dependencies
=========
Releasing
=========
-Create a PEAR package as well as phars for pear-less installation::
-
- $ rm -f PEAR-*.tgz
- $ pear package package2.xml
- $ cd go-pear-tarballs
- $ rm -f PEAR-*
- $ cp ../PEAR-*.tgz .
- $ gunzip PEAR-*.tgz
- $ pear download -Z Archive_Tar Console_Getopt Structures_Graph XML_Util
- $ mkdir src && cd src
- $ for i in ../*.tar; do tar xvf $i; done
- $ mv *\/* .
- $ cd ../../
- $ php make-gopear-phar.php
- $ php make-installpear-nozlib-phar.php
-
-(Or simply run ``build-release.sh``).
-
-``go-pear.phar`` is contains the PEAR installer installer that asks questions
-where to install it.
+Create a PEAR package, as well as phars for pear-less installation,
+simply run ``build-release.sh``).
+
+``go-pear.phar`` contains the PEAR installer installer that asks where to install it.
It is available from http://pear.php.net/go-pear.phar.
-``install-pear-nozlib.phar`` installs PEAR automatically without asking
-anything.
+``install-pear-nozlib.phar`` installs PEAR automatically without asking anything.
It is shipped with PHP itself.
diff --git a/WEB-INF/lib/pear/System.php b/WEB-INF/lib/pear/System.php
index 9ff3fedb9..77944233e 100644
--- a/WEB-INF/lib/pear/System.php
+++ b/WEB-INF/lib/pear/System.php
@@ -22,7 +22,7 @@
$GLOBALS['_System_temp_files'] = array();
/**
-* System offers cross plattform compatible system functions
+* System offers cross platform compatible system functions
*
* Static functions for different operations. Should work under
* Unix and Windows. The names and usage has been taken from its respectively
@@ -50,7 +50,7 @@
* @author Tomas V.V. Cox
* @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License
-* @version Release: 1.10.1
+* @version Release: 1.10.15
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
* @static
@@ -74,7 +74,7 @@ public static function _parseArgs($argv, $short_options, $long_options = null)
$offset = 0;
foreach ($av as $a) {
$b = trim($a[0]);
- if ($b{0} == '"' || $b{0} == "'") {
+ if ($b[0] == '"' || $b[0] == "'") {
continue;
}
@@ -265,7 +265,7 @@ public static function mkDir($args)
} elseif ($opt[0] == 'm') {
// if the mode is clearly an octal number (starts with 0)
// convert it to decimal
- if (strlen($opt[1]) && $opt[1]{0} == '0') {
+ if (strlen($opt[1]) && $opt[1][0] == '0') {
$opt[1] = octdec($opt[1]);
} else {
// convert to int
@@ -315,7 +315,7 @@ public static function mkDir($args)
* 2) System::cat('sample.txt test.txt > final.txt');
* 3) System::cat('sample.txt test.txt >> final.txt');
*
- * Note: as the class use fopen, urls should work also (test that)
+ * Note: as the class use fopen, urls should work also
*
* @param string $args the arguments
* @return boolean true on success
@@ -480,7 +480,7 @@ public static function tmpdir()
if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
return $var;
}
- return realpath('/tmp');
+ return realpath(function_exists('sys_get_temp_dir') ? sys_get_temp_dir() : '/tmp');
}
/**
@@ -527,8 +527,16 @@ public static function which($program, $fallback = false)
foreach ($exe_suffixes as $suff) {
foreach ($path_elements as $dir) {
$file = $dir . DIRECTORY_SEPARATOR . $program . $suff;
- if (is_executable($file)) {
- return $file;
+ // It's possible to run a .bat on Windows that is_executable
+ // would return false for. The is_executable check is meaningless...
+ if (OS_WINDOWS) {
+ if (file_exists($file)) {
+ return $file;
+ }
+ } else {
+ if (is_executable($file)) {
+ return $file;
+ }
}
}
}
@@ -547,7 +555,7 @@ public static function which($program, $fallback = false)
* System::find("$dir -name *.php -name *.htm*");
* System::find("$dir -maxdepth 1");
*
- * Params implmented:
+ * Params implemented:
* $dir -> Start the search at this directory
* -type d -> return only directories
* -type f -> return only files
@@ -619,4 +627,4 @@ public static function find($args)
}
return $files;
}
-}
\ No newline at end of file
+}
diff --git a/WEB-INF/lib/pear/package.dtd b/WEB-INF/lib/pear/package.dtd
index 5b471b7fe..1550ca94c 100644
--- a/WEB-INF/lib/pear/package.dtd
+++ b/WEB-INF/lib/pear/package.dtd
@@ -1,6 +1,4 @@