- Added write support to address book LDAP backend. Patch by David
Hardeman (#1495763).
- Added message copy options.
+ - Removed html formating from address book backend classes. Added
+ fullname() method to addressbook_backend class. Moved
+ htmlspecialchars() sanitizing from address book backend classes to
+ html output code. If third party code displays errors from address
+ book object in html, errors must be sanitized and ASCII line feeds
+ should be converted to html line breaks.
Version 1.5.1 (branched on 2006-02-12)
--------------------------------------
/* test if Pear DB class is available and freak out if it is not */
if (! class_exists('DB')) {
// same error also in db_prefs.php
- $error = _("Could not include PEAR database functions required for the database backend.") . "<br />\n";
+ $error = _("Could not include PEAR database functions required for the database backend.") . "\n";
$error .= sprintf(_("Is PEAR installed, and is the include path set correctly to find %s?"),
- '<tt>DB.php</tt>') . "<br />\n";
+ 'DB.php') . "\n";
$error .= _("Please contact your system administrator and report this error.");
return $this->set_error($error);
}
while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
array_push($ret, array('nickname' => $row['nickname'],
- 'name' => "$row[firstname] $row[lastname]",
+ 'name' => $this->fullname($row['firstname'], $row['lastname']),
'firstname' => $row['firstname'],
'lastname' => $row['lastname'],
'email' => $row['email'],
if ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
return array('nickname' => $row['nickname'],
- 'name' => "$row[firstname] $row[lastname]",
+ 'name' => $this->fullname($row['firstname'], $row['lastname']),
'firstname' => $row['firstname'],
'lastname' => $row['lastname'],
'email' => $row['email'],
while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
array_push($ret, array('nickname' => $row['nickname'],
- 'name' => "$row[firstname] $row[lastname]",
+ 'name' => $this->fullname($row['firstname'], $row['lastname']),
'firstname' => $row['firstname'],
'lastname' => $row['lastname'],
'email' => $row['email'],
*/
function add($userdata) {
if (!$this->writeable) {
- return $this->set_error(_("Addressbook is read-only"));
+ return $this->set_error(_("Address book is read-only"));
}
if (!$this->open()) {
*/
function remove($alias) {
if (!$this->writeable) {
- return $this->set_error(_("Addressbook is read-only"));
+ return $this->set_error(_("Address book is read-only"));
}
if (!$this->open()) {
*/
function modify($alias, $userdata) {
if (!$this->writeable) {
- return $this->set_error(_("Addressbook is read-only"));
+ return $this->set_error(_("Address book is read-only"));
}
if (!$this->open()) {
$surname = trim($this->charset_decode($row['sn'][0]));
}
- // FIXME: Write generic function to handle name order
- $fullname = trim($firstname . " " . $surname);
+ $fullname = $this->fullname($firstname,$surname);
/* Add one row to result for each e-mail address */
if(isset($row['mail']['count'])) {
// errors on eregi call are suppressed in order to prevent display of regexp compilation errors
if(@eregi($expr, $line)) {
array_push($res, array('nickname' => $row[0],
- 'name' => $row[1] . ' ' . $row[2],
+ 'name' => $this->fullname($row[1], $row[2]),
'firstname' => $row[1],
'lastname' => $row[2],
'email' => $row[3],
while ($row = @fgetcsv($this->filehandle, 2048, '|')) {
if(strtolower($row[0]) == $alias) {
return array('nickname' => $row[0],
- 'name' => $row[1] . ' ' . $row[2],
+ 'name' => $this->fullname($row[1], $row[2]),
'firstname' => $row[1],
'lastname' => $row[2],
'email' => $row[3],
while ($row = @fgetcsv($this->filehandle, 2048, '|')) {
array_push($res, array('nickname' => $row[0],
- 'name' => $row[1] . ' ' . $row[2],
+ 'name' => $this->fullname($row[1], $row[2]),
'firstname' => $row[1],
'lastname' => $row[2],
'email' => $row[3],
*/
function add($userdata) {
if(!$this->writeable) {
- return $this->set_error(_("Addressbook is read-only"));
+ return $this->set_error(_("Address book is read-only"));
}
/* See if user exists already */
$ret = $this->lookup($userdata['nickname']);
/* Reopen file, just to be sure */
$this->open(true);
if(!$this->writeable) {
- return $this->set_error(_("Addressbook is read-only"));
+ return $this->set_error(_("Address book is read-only"));
}
/* Lock the file */
/* Test write result */
if($r === FALSE) {
/* Fail */
- $this->set_error(_("Write to addressbook failed"));
+ $this->set_error(_("Write to address book failed"));
return FALSE;
}
*/
function remove($alias) {
if(!$this->writeable) {
- return $this->set_error(_("Addressbook is read-only"));
+ return $this->set_error(_("Address book is read-only"));
}
/* Lock the file to make sure we're the only process working
*/
function modify($alias, $userdata) {
if(!$this->writeable) {
- return $this->set_error(_("Addressbook is read-only"));
+ return $this->set_error(_("Address book is read-only"));
}
/* See if user exists */
'owner' => $username,
'table' => $addrbook_table));
if (!$r && $showerr) {
- $abook_init_error.=_("Error initializing addressbook database.") . "<br />\n" . $abook->error;
+ $abook_init_error.=_("Error initializing address book database.") . "\n" . $abook->error;
}
} else {
/* File */
/* global abook init error is not fatal. add error message and continue */
if (!$r && $showerr) {
- if ($abook_init_error!='') $abook_init_error.="<br />\n";
- $abook_init_error.=_("Error initializing global addressbook.") . "<br />\n" . $abook->error;
+ if ($abook_init_error!='') $abook_init_error.="\n";
+ $abook_init_error.=_("Error initializing global address book.") . "\n" . $abook->error;
}
}
'table' => $addrbook_global_table));
/* global abook init error is not fatal. add error message and continue */
if (!$r && $showerr) {
- if ($abook_init_error!='') $abook_init_error.="<br />\n";
- $abook_init_error.=_("Error initializing global addressbook.") . "<br />\n" . $abook->error;
+ if ($abook_init_error!='') $abook_init_error.="\n";
+ $abook_init_error.=_("Error initializing global address book.") . "\n" . $abook->error;
}
}
$abook = $hookReturn[1];
$r = $hookReturn[2];
if (!$r && $showerr) {
- if ($abook_init_error!='') $abook_init_error.="<br />\n";
- $abook_init_error.=_("Error initializing other address books.") . "<br />\n" . $abook->error;
+ if ($abook_init_error!='') $abook_init_error.="\n";
+ $abook_init_error.=_("Error initializing other address books.") . "\n" . $abook->error;
}
$r = $abook->add_backend('ldap_server', $param);
if (!$r && $showerr) {
- if ($abook_init_error!='') $abook_init_error.="<br />\n";
- $abook_init_error.=sprintf(_("Error initializing LDAP server %s:") .
- "<br />\n", $param['host']);
+ if ($abook_init_error!='') $abook_init_error.="\n";
+ $abook_init_error.=sprintf(_("Error initializing LDAP server %s:"), $param['host'])."\n";
$abook_init_error.= $abook->error;
}
}
* display address book init errors.
*/
if ($abook_init_error!='' && $showerr) {
- error_box($abook_init_error);
+ error_box(nl2br(htmlspecialchars($abook_init_error)));
}
/* Return the initialized object */
* @subpackage addressbook
*/
class AddressBook {
-
- /*
- Cleaning errors from html with htmlspecialchars:
- Errors from the backend are cleaned up in this class because we not always
- have control over it when error output is generated in the backend.
- If this appears to be wrong place then clean it up at the source (the backend)
- */
-
/**
* Enabled address book backends
* @var array
if (is_array($res)) {
$ret = array_merge($ret, $res);
} else {
- $this->error .= "<br />\n" . htmlspecialchars($backend->error);
+ $this->error .= "\n" . $backend->error;
$failed++;
}
}
$ret = $this->backends[$bnum]->search($expression);
if (!is_array($ret)) {
- $this->error .= "<br />\n" . htmlspecialchars($this->backends[$bnum]->error);
+ $this->error .= "\n" . $this->backends[$bnum]->error;
$ret = FALSE;
}
}
if (is_array($res)) {
return $res;
} else {
- $this->error = htmlspecialchars($this->backends[$bnum]->error);
+ $this->error = $this->backends[$bnum]->error;
return false;
}
}
if(!empty($res))
return $res;
} else {
- $this->error = htmlspecialchars($backend->error);
+ $this->error = $backend->error;
return false;
}
}
if (is_array($res)) {
$ret = array_merge($ret, $res);
} else {
- $this->error = htmlspecialchars($backend->error);
+ $this->error = $backend->error;
return false;
}
}
$userdata['nickname'] = $userdata['email'];
}
+ /* Blocks use of space, :, |, #, " and ! in nickname */
if (eregi('[ \\:\\|\\#\\"\\!]', $userdata['nickname'])) {
$this->error = _("Nickname contains illegal characters");
return false;
/* Check that specified backend accept new entries */
if (!$this->backends[$bnum]->writeable) {
- $this->error = _("Addressbook is read-only");
+ $this->error = _("Address book is read-only");
return false;
}
if ($res) {
return $bnum;
} else {
- $this->error = htmlspecialchars($this->backends[$bnum]->error);
+ $this->error = $this->backends[$bnum]->error;
return false;
}
/* Check that specified backend is writable */
if (!$this->backends[$bnum]->writeable) {
- $this->error = _("Addressbook is read-only");
+ $this->error = _("Address book is read-only");
return false;
}
if ($res) {
return $bnum;
} else {
- $this->error = htmlspecialchars($this->backends[$bnum]->error);
+ $this->error = $this->backends[$bnum]->error;
return false;
}
/* Check that specified backend is writable */
if (!$this->backends[$bnum]->writeable) {
- $this->error = _("Addressbook is read-only");;
+ $this->error = _("Address book is read-only");;
return false;
}
if ($res) {
return $bnum;
} else {
- $this->error = htmlspecialchars($this->backends[$bnum]->error);
+ $this->error = $this->backends[$bnum]->error;
return false;
}
* @return bool
*/
function search($expression) {
- $this->set_error('search not implemented');
+ $this->set_error('search is not implemented');
return false;
}
* @return bool
*/
function lookup($alias) {
- $this->set_error('lookup not implemented');
+ $this->set_error('lookup is not implemented');
return false;
}
* @return bool
*/
function list_addr() {
- $this->set_error('list_addr not implemented');
+ $this->set_error('list_addr is not implemented');
return false;
}
* @return bool
*/
function add($userdata) {
- $this->set_error('add not implemented');
+ $this->set_error('add is not implemented');
return false;
}
* @return bool
*/
function remove($alias) {
- $this->set_error('delete not implemented');
+ $this->set_error('delete is not implemented');
return false;
}
* @return bool
*/
function modify($alias, $newuserdata) {
- $this->set_error('modify not implemented');
+ $this->set_error('modify is not implemented');
return false;
}
+
+ /**
+ * Creates full name from given name and surname
+ *
+ * Handles name order differences
+ * @param string $firstname given name
+ * @param string $lastname surname
+ * @return string full name
+ * @since 1.5.2
+ */
+ function fullname($firstname,$lastname) {
+ global $squirrelmail_language;
+ if ($squirrelmail_language=='ja_JP') {
+ return trim($lastname . ' ' . $firstname);
+ } else {
+ return trim($firstname . ' ' . $lastname);
+ }
+ }
}
if (!is_array($res)) {
echo html_tag( 'p', '<b><br />' .
_("Your search failed with the following error(s)") .
- ':<br />' . $abook->error . "</b>\n" ,
+ ':<br />' . nl2br(htmlspecialchars($abook->error)) . "</b>\n" ,
'center' );
} elseif (sizeof($res) == 0) {
echo html_tag( 'p', '<br /><b>' .
} else {
$tr_bgcolor = $color[4];
}
- if ($squirrelmail_language == 'ja_JP')
- {
- echo html_tag( 'tr', '', '', $tr_bgcolor, 'style="white-space: nowrap;"' ) .
- html_tag( 'td',
- '<input type="checkbox" name="send_to_search[T' . $line . ']" value = "' .
- htmlspecialchars($email) . '" /> ' . _("To") . ' ' .
- '<input type="checkbox" name="send_to_search[C' . $line . ']" value = "' .
- htmlspecialchars($email) . '" /> ' . _("Cc") . ' ' .
- '<input type="checkbox" name="send_to_search[B' . $line . ']" value = "' .
- htmlspecialchars($email) . '" /> ' . _("Bcc") . ' ' ,
- 'center', '', 'width="5%" style="white-space: nowrap;"' ) .
- html_tag( 'td', ' ' . htmlspecialchars($row['lastname']) . ' ' . htmlspecialchars($row['firstname']) . ' ', 'left', '', 'style="white-space: nowrap;"' ) .
- html_tag( 'td', ' ' . htmlspecialchars($row['email']) . ' ', 'left', '', 'style="white-space: nowrap;"' ) .
- html_tag( 'td', ' ' . htmlspecialchars($row['label']) . ' ', 'left', '', 'style="white-space: nowrap;"' );
- } else {
+
echo html_tag( 'tr', '', '', $tr_bgcolor, 'style="white-space: nowrap;"' ) .
html_tag( 'td',
addCheckBox('send_to_search[T'.$line.']', FALSE, $email).
html_tag( 'td', ' ' . htmlspecialchars($row['name']) . ' ', 'left', '', 'style="white-space: nowrap;"' ) .
html_tag( 'td', ' ' . htmlspecialchars($row['email']) . ' ', 'left', '', 'style="white-space: nowrap;"' ) .
html_tag( 'td', ' ' . htmlspecialchars($row['label']) . ' ', 'left', '', 'style="white-space: nowrap;"' );
- }
- if ($includesource) {
- echo html_tag( 'td', ' ' . $row['source'] . ' ', 'left', '', 'style="white-space: nowrap;"' );
- }
- echo "</tr>\n";
- $line ++;
+ if ($includesource) {
+ echo html_tag( 'td', ' ' . $row['source'] . ' ', 'left', '', 'style="white-space: nowrap;"' );
+ }
+ echo "</tr>\n";
+ $line ++;
}
if ($includesource) { $td_colspan = '5'; } else { $td_colspan = '4'; }
echo html_tag( 'tr',
if (!is_array($res)) {
echo html_tag( 'p', '<b><br />' .
_("Your search failed with the following error(s)") .
- ':<br />' . $abook->error . "</b>\n" ,
+ ':<br />' . nl2br(htmlspecialchars($abook->error)) . "</b>\n" ,
'center' ) . "\n";
$oTemplate->display('footer.tpl');
} else {
html_tag( 'tr',
html_tag( 'td',
"\n". '<br /><strong><font color="' . $color[2] .
- '">' . _("ERROR") . ': ' . $formerror . '</font></strong>' ."\n",
+ '">' . _("ERROR") . ': ' . nl2br(htmlspecialchars($formerror)) . '</font></strong>' ."\n",
'center' )
),
'center', '', 'width="100%"' );
/* Get and sort address list */
$alist = $abook->list_addr();
if(!is_array($alist)) {
- plain_error_message($abook->error, $color);
+ plain_error_message(nl2br(htmlspecialchars($abook->error)), $color);
exit;
}
' ' . htmlspecialchars($row['nickname']) . ' ',
'left', '', 'valign="top" width="1%" style="white-space: nowrap;"' );
- // different full name display formating for Japanese translation
- if ($squirrelmail_language == 'ja_JP') {
- /*
- * translation uses euc-jp character set internally.
- * htmlspecialchars() should not break any characters.
- */
- echo html_tag( 'td',
- ' ' . htmlspecialchars($row['lastname']) . ' ' . htmlspecialchars($row['firstname']) . ' ',
- 'left', '', 'valign="top" width="1%" style="white-space: nowrap;"' );
- } else {
- echo html_tag( 'td',
- ' ' . htmlspecialchars($row['name']) . ' ',
- 'left', '', 'valign="top" width="1%" style="white-space: nowrap;"' );
- }
+ echo html_tag( 'td',
+ ' ' . htmlspecialchars($row['name']) . ' ',
+ 'left', '', 'valign="top" width="1%" style="white-space: nowrap;"' );
// email address column
echo html_tag( 'td', '', 'left', '', 'valign="top" width="1%" style="white-space: nowrap;"' ) . ' ';