Changeset e999919 in github
- Timestamp:
- Sep 29, 2010 8:36:28 AM (3 years ago)
- Branches:
- master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
- Children:
- a999682
- Parents:
- d7f9eb5
- Files:
-
- 3 added
- 20 edited
-
CHANGELOG (modified) (1 diff)
-
installer/check.php (modified) (2 diffs)
-
installer/test.php (modified) (3 diffs)
-
program/include/main.inc (modified) (1 diff)
-
program/include/rcmail.php (modified) (2 diffs)
-
program/include/rcube_config.php (modified) (2 diffs)
-
program/include/rcube_imap.php (modified) (3 diffs)
-
program/include/rcube_ldap.php (modified) (1 diff)
-
program/include/rcube_shared.inc (modified) (1 diff)
-
program/include/rcube_smtp.php (modified) (2 diffs)
-
program/include/rcube_template.php (modified) (2 diffs)
-
program/include/rcube_user.php (modified) (17 diffs)
-
program/js/common.js (modified) (1 diff)
-
program/lib/Net/IDNA2.php (added)
-
program/lib/Net/IDNA2/Exception.php (added)
-
program/lib/Net/IDNA2/Exception/Nameprep.php (added)
-
program/steps/mail/addcontact.inc (modified) (1 diff)
-
program/steps/mail/compose.inc (modified) (11 diffs)
-
program/steps/mail/func.inc (modified) (10 diffs)
-
program/steps/mail/sendmail.inc (modified) (8 diffs)
-
program/steps/settings/edit_identity.inc (modified) (1 diff)
-
program/steps/settings/func.inc (modified) (1 diff)
-
program/steps/settings/save_identity.inc (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
CHANGELOG
rd7f9eb5 re999919 4 4 - Messages caching: performance improvements, fixed syncing, fixes related with #1486748 5 5 - Add link to identities in compose window (#1486729) 6 - Add Internationalized Domain Name (IDNA) support (#1483894) 6 7 7 8 RELEASE 0.4.1 -
installer/check.php
re019f2d re999919 16 16 'OpenSSL' => 'openssl', 17 17 'Mcrypt' => 'mcrypt', 18 'Intl' => 'intl', 18 19 ); 19 20 … … 45 46 46 47 $source_urls = array( 47 'Sockets' => 'http://www.php.net/manual/en/book.sockets.php',48 'Session' => 'http://www.php.net/manual/en/book.session.php',49 'PCRE' => 'http://www.php.net/manual/en/book.pcre.php',50 'FileInfo' => 'http://www.php.net/manual/en/book.fileinfo.php',51 'Libiconv' => 'http://www.php.net/manual/en/book.iconv.php',48 'Sockets' => 'http://www.php.net/manual/en/book.sockets.php', 49 'Session' => 'http://www.php.net/manual/en/book.session.php', 50 'PCRE' => 'http://www.php.net/manual/en/book.pcre.php', 51 'FileInfo' => 'http://www.php.net/manual/en/book.fileinfo.php', 52 'Libiconv' => 'http://www.php.net/manual/en/book.iconv.php', 52 53 'Multibyte' => 'http://www.php.net/manual/en/book.mbstring.php', 53 'Mcrypt' => 'http://www.php.net/manual/en/book.mcrypt.php', 54 'OpenSSL' => 'http://www.php.net/manual/en/book.openssl.php', 55 'JSON' => 'http://www.php.net/manual/en/book.json.php', 56 'DOM' => 'http://www.php.net/manual/en/book.dom.php', 57 'PEAR' => 'http://pear.php.net', 58 'MDB2' => 'http://pear.php.net/package/MDB2', 59 'Net_SMTP' => 'http://pear.php.net/package/Net_SMTP', 54 'Mcrypt' => 'http://www.php.net/manual/en/book.mcrypt.php', 55 'OpenSSL' => 'http://www.php.net/manual/en/book.openssl.php', 56 'JSON' => 'http://www.php.net/manual/en/book.json.php', 57 'DOM' => 'http://www.php.net/manual/en/book.dom.php', 58 'Intl' => 'http://www.php.net/manual/en/book.intl.php', 59 'PEAR' => 'http://pear.php.net', 60 'MDB2' => 'http://pear.php.net/package/MDB2', 61 'Net_SMTP' => 'http://pear.php.net/package/Net_SMTP', 60 62 'Mail_mime' => 'http://pear.php.net/package/Mail_mime', 61 63 ); -
installer/test.php
re019f2d re999919 250 250 echo '<p>Trying to send email...<br />'; 251 251 252 if (preg_match('/^' . $RCI->email_pattern . '$/i', trim($_POST['_from'])) && 253 preg_match('/^' . $RCI->email_pattern . '$/i', trim($_POST['_to']))) { 254 252 $from = idn_to_ascii(trim($_POST['_from'])); 253 $to = idn_to_ascii(trim($_POST['_to'])); 254 255 if (preg_match('/^' . $RCI->email_pattern . '$/i', $from) && 256 preg_match('/^' . $RCI->email_pattern . '$/i', $to) 257 ) { 255 258 $headers = array( 256 'From' => trim($_POST['_from']),257 'To' => trim($_POST['_to']),259 'From' => $from, 260 'To' => $to, 258 261 'Subject' => 'Test message from Roundcube', 259 262 ); … … 261 264 $body = 'This is a test to confirm that Roundcube can send email.'; 262 265 $smtp_response = array(); 263 266 264 267 // send mail using configured SMTP server 265 268 if ($RCI->getprop('smtp_server')) { … … 384 387 $imap_port = $RCI->getprop('default_port'); 385 388 } 386 389 390 $imap_host = idn_to_ascii($imap_host); 391 $imap_user = idn_to_ascii($_POST['_user']); 392 387 393 $imap = new rcube_imap(null); 388 if ($imap->connect($imap_host, $ _POST['_user'], $_POST['_pass'], $imap_port, $imap_ssl)) {394 if ($imap->connect($imap_host, $imap_user, $_POST['_pass'], $imap_port, $imap_ssl)) { 389 395 $RCI->pass('IMAP connect', 'SORT capability: ' . ($imap->get_capability('SORT') ? 'yes' : 'no')); 390 396 $imap->close(); -
program/include/main.inc
re019f2d re999919 1765 1765 } 1766 1766 } 1767 -
program/include/rcmail.php
r6d94ab3 re999919 588 588 $host = $a_host['host']; 589 589 $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? $a_host['scheme'] : null; 590 if (!empty($a_host['port']))590 if (!empty($a_host['port'])) 591 591 $imap_port = $a_host['port']; 592 592 else if ($imap_ssl && $imap_ssl != 'tls' && (!$config['default_port'] || $config['default_port'] == 143)) … … 619 619 $this->imap_init(); 620 620 621 // Here we need IDNA ASCII 622 // Only rcube_contacts class is using domain names in Unicode 623 $host = idn_to_ascii($host); 624 if (strpos($username, '@')) 625 $username = idn_to_ascii($username); 626 621 627 // try IMAP login 622 628 if (!($imap_login = $this->imap->connect($host, $username, $pass, $imap_port, $imap_ssl))) { -
program/include/rcube_config.php
re019f2d re999919 275 275 * Return the mail domain configured for the given host 276 276 * 277 * @param string IMAP host 277 * @param string IMAP host 278 * @param boolean If true, domain name will be converted to IDN ASCII 278 279 * @return string Resolved SMTP host 279 280 */ 280 public function mail_domain($host )281 public function mail_domain($host, $encode=true) 281 282 { 282 283 $domain = $host; … … 289 290 $domain = rcube_parse_host($this->prop['mail_domain']); 290 291 292 if ($encode) 293 $domain = idn_to_ascii($domain); 294 291 295 return $domain; 292 296 } -
program/include/rcube_imap.php
reacce9b re999919 3506 3506 $name = trim($val['name']); 3507 3507 3508 if ( preg_match('/^[\'"]/', $name) && preg_match('/[\'"]$/', $name))3508 if ($name && preg_match('/^[\'"]/', $name) && preg_match('/[\'"]$/', $name)) 3509 3509 $name = trim($name, '\'"'); 3510 3510 … … 3516 3516 $string = $name; 3517 3517 3518 $out[$j] = array('name' => $name, 3518 $out[$j] = array( 3519 'name' => $name, 3519 3520 'mailto' => $address, 3520 3521 'string' => $string … … 3913 3914 } 3914 3915 3915 if (empty($result[$key]['name']))3916 $result[$key]['name'] = $result[$key]['address'];3917 elseif (empty($result[$key]['address']))3916 // if (empty($result[$key]['name'])) 3917 // $result[$key]['name'] = $result[$key]['address']; 3918 if (empty($result[$key]['address'])) 3918 3919 $result[$key]['address'] = $result[$key]['name']; 3919 3920 } -
program/include/rcube_ldap.php
re019f2d re999919 100 100 foreach ($this->prop['hosts'] as $host) 101 101 { 102 $host = rcube_parse_host($host);102 $host = idn_to_ascii(rcube_parse_host($host)); 103 103 $this->_debug("C: Connect [$host".($this->prop['port'] ? ':'.$this->prop['port'] : '')."]"); 104 104 -
program/include/rcube_shared.inc
r8603bbb re999919 681 681 } 682 682 683 /** 684 * intl replacement functions 685 */ 686 687 if (!function_exists('idn_to_utf8')) 688 { 689 function idn_to_utf8($domain, $flags=null) 690 { 691 static $idn, $loaded; 692 693 if (!$loaded) { 694 $idn = new Net_IDNA2(); 695 $loaded = true; 696 } 697 698 if ($idn && $domain && preg_match('/(^|@|\.)xn--/i', $domain)) { 699 try { 700 $domain = $idn->decode($domain); 701 } 702 catch (Exception $e) { 703 } 704 } 705 return $domain; 706 } 707 } 708 709 if (!function_exists('idn_to_ascii')) 710 { 711 function idn_to_ascii($domain, $flags=null) 712 { 713 static $idn, $loaded; 714 715 if (!$loaded) { 716 $idn = new Net_IDNA2(); 717 $loaded = true; 718 } 719 720 if ($idn && $domain && preg_match('/[^\x20-\x7E]/', $domain)) { 721 try { 722 $domain = $idn->encode($domain); 723 } 724 catch (Exception $e) { 725 } 726 } 727 return $domain; 728 } 729 } 730 -
program/include/rcube_smtp.php
re019f2d re999919 99 99 $helo_host = 'localhost'; 100 100 101 // IDNA Support 102 $smtp_host = idn_to_ascii($smtp_host); 103 101 104 $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host); 102 105 … … 117 120 $smtp_pass = str_replace('%p', $RCMAIL->decrypt($_SESSION['password']), $CONFIG['smtp_pass']); 118 121 $smtp_auth_type = empty($CONFIG['smtp_auth_type']) ? NULL : $CONFIG['smtp_auth_type']; 119 122 120 123 // attempt to authenticate to the SMTP server 121 124 if ($smtp_user && $smtp_pass) 122 125 { 126 // IDNA Support 127 if (strpos($smtp_user, '@')) 128 $smtp_user = idn_to_ascii($smtp_user); 129 123 130 $result = $this->conn->auth($smtp_user, $smtp_pass, $smtp_auth_type, $use_tls); 124 131 -
program/include/rcube_template.php
re019f2d re999919 995 995 } 996 996 997 // Current username is an e-mail address 998 if (strpos($_SESSION['username'], '@')) { 999 $username = $_SESSION['username']; 1000 } 997 1001 // get e-mail address from default identity 998 if ($sql_arr = $this->app->user->get_identity()) {1002 else if ($sql_arr = $this->app->user->get_identity()) { 999 1003 $username = $sql_arr['email']; 1000 1004 } … … 1003 1007 } 1004 1008 1005 return $username;1009 return idn_to_utf8($username); 1006 1010 } 1007 1011 -
program/include/rcube_user.php
re019f2d re999919 45 45 { 46 46 $this->db = rcmail::get_instance()->get_dbh(); 47 47 48 48 if ($id && !$sql_arr) { 49 49 $sql_result = $this->db->query( … … 122 122 if (!$this->ID) 123 123 return false; 124 124 125 125 $config = rcmail::get_instance()->config; 126 126 $old_prefs = (array)$this->get_prefs(); … … 129 129 $save_prefs = $a_user_prefs + $old_prefs; 130 130 unset($save_prefs['language']); 131 131 132 132 // don't save prefs with default values if they haven't been changed yet 133 133 foreach ($a_user_prefs as $key => $value) { … … 187 187 " ORDER BY ".$this->db->quoteIdentifier('standard')." DESC, name ASC, identity_id ASC", 188 188 $this->ID); 189 189 190 190 while ($sql_arr = $this->db->fetch_assoc($sql_result)) { 191 191 $result[] = $sql_arr; 192 192 } 193 193 194 194 return $result; 195 195 } … … 209 209 210 210 $query_cols = $query_params = array(); 211 211 212 212 foreach ((array)$data as $col => $value) { 213 213 $query_cols[] = $this->db->quoteIdentifier($col) . ' = ?'; … … 225 225 call_user_func_array(array($this->db, 'query'), 226 226 array_merge(array($sql), $query_params)); 227 227 228 228 return $this->db->affected_rows(); 229 229 } 230 231 230 231 232 232 /** 233 233 * Create a new identity record linked with this user … … 260 260 return $this->db->insert_id('identities'); 261 261 } 262 263 262 263 264 264 /** 265 265 * Mark the given identity as deleted … … 283 283 if ($sql_arr['ident_count'] <= 1) 284 284 return false; 285 285 286 286 $this->db->query( 287 287 "UPDATE ".get_table_name('identities'). … … 294 294 return $this->db->affected_rows(); 295 295 } 296 297 296 297 298 298 /** 299 299 * Make this identity the default one for this user … … 314 314 } 315 315 } 316 317 316 317 318 318 /** 319 319 * Update user's last_login timestamp … … 329 329 } 330 330 } 331 332 331 332 333 333 /** 334 334 * Clear the saved object state … … 339 339 $this->data = null; 340 340 } 341 342 341 342 343 343 /** 344 344 * Find a user record matching the given name and host … … 351 351 { 352 352 $dbh = rcmail::get_instance()->get_dbh(); 353 353 354 354 // query for matching user name 355 355 $query = "SELECT * FROM ".get_table_name('users')." WHERE mail_host = ? AND %s = ?"; 356 356 $sql_result = $dbh->query(sprintf($query, 'username'), $host, $user); 357 357 358 358 // query for matching alias 359 359 if (!($sql_arr = $dbh->fetch_assoc($sql_result))) { … … 361 361 $sql_arr = $dbh->fetch_assoc($sql_result); 362 362 } 363 363 364 364 // user already registered -> overwrite username 365 365 if ($sql_arr) … … 368 368 return false; 369 369 } 370 371 370 371 372 372 /** 373 373 * Create a new user record and return a rcube_user instance … … 449 449 $plugin = $rcmail->plugins->exec_hook('identity_create', 450 450 array('login' => true, 'record' => $record)); 451 451 452 452 if (!$plugin['abort'] && $plugin['record']['email']) { 453 453 $rcmail->user->insert_identity($plugin['record']); … … 464 464 'message' => "Failed to create new user"), true, false); 465 465 } 466 466 467 467 return $user_id ? $user_instance : false; 468 468 } 469 470 469 470 471 471 /** 472 472 * Resolve username using a virtuser plugins -
program/js/common.js
re019f2d re999919 485 485 { 486 486 if (input && window.RegExp) { 487 var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'; 488 var dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'; 489 var atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'; 490 var quoted_pair = '\\x5c[\\x00-\\x7f]'; 491 var domain_literal = '\\x5b('+dtext+'|'+quoted_pair+')*\\x5d'; 492 var quoted_string = '\\x22('+qtext+'|'+quoted_pair+')*\\x22'; 493 var sub_domain = '('+atom+'|'+domain_literal+')'; 494 var word = '('+atom+'|'+quoted_string+')'; 495 var domain = sub_domain+'(\\x2e'+sub_domain+')*'; 496 var local_part = word+'(\\x2e'+word+')*'; 497 var addr_spec = local_part+'\\x40'+domain; 498 var delim = '[,;\s\n]'; 499 var reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i'); 487 var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]', 488 dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]', 489 atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+', 490 quoted_pair = '\\x5c[\\x00-\\x7f]', 491 quoted_string = '\\x22('+qtext+'|'+quoted_pair+')*\\x22', 492 // Use simplified domain matching, because we need to allow Unicode characters here 493 // So, e-mail address should be validated also on server side after idn_to_ascii() use 494 sub_domain = '[^@]+', 495 //domain_literal = '\\x5b('+dtext+'|'+quoted_pair+')*\\x5d', 496 //sub_domain = '('+atom+'|'+domain_literal+')', 497 word = '('+atom+'|'+quoted_string+')', 498 delim = '[,;\s\n]', 499 domain = sub_domain+'(\\x2e'+sub_domain+')*', 500 local_part = word+'(\\x2e'+word+')*', 501 addr_spec = local_part+'\\x40'+domain, 502 reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i'); 503 500 504 return reg1.test(input) ? true : false; 501 505 } 506 502 507 return false; 503 508 }; -
program/steps/mail/addcontact.inc
re019f2d re999919 37 37 'name' => $contact_arr[1]['name'] 38 38 ); 39 39 40 $contact['email'] = idn_to_utf8($contact['email']); 41 40 42 // use email address part for name 41 43 if (empty($contact['name']) || $contact['name'] == $contact['email']) -
program/steps/mail/compose.inc
re019f2d re999919 228 228 229 229 case 'cc': 230 if (!$fname) 231 { 230 if (!$fname) { 232 231 $fname = '_cc'; 233 232 $header = $param = 'cc'; 234 233 } 235 234 case 'bcc': 236 if (!$fname) 237 { 235 if (!$fname) { 238 236 $fname = '_bcc'; 239 237 $header = $param = 'bcc'; … … 252 250 break; 253 251 } 254 252 255 253 if ($fname && !empty($_POST[$fname])) { 256 254 $fvalue = get_input_value($fname, RCUBE_INPUT_POST, TRUE); … … 263 261 if ($header=='to' && !empty($MESSAGE->headers->replyto)) 264 262 $fvalue = $MESSAGE->headers->replyto; 265 266 263 else if ($header=='to' && !empty($MESSAGE->headers->from)) 267 264 $fvalue = $MESSAGE->headers->from; 268 269 265 // add recipent of original message if reply to all 270 else if ($header=='cc' && !empty($MESSAGE->reply_all)) 271 { 266 else if ($header=='cc' && !empty($MESSAGE->reply_all)) { 272 267 if ($v = $MESSAGE->headers->to) 273 268 $fvalue .= $v; … … 278 273 279 274 // split recipients and put them back together in a unique way 280 if (!empty($fvalue)) 281 { 275 if (!empty($fvalue)) { 282 276 $to_addresses = $IMAP->decode_address_list($fvalue); 283 277 $fvalue = ''; 284 278 285 foreach ($to_addresses as $addr_part) 286 { 287 if (!empty($addr_part['mailto']) 288 && !in_array($addr_part['mailto'], $sa_recipients) 279 foreach ($to_addresses as $addr_part) { 280 if (empty($addr_part['mailto'])) 281 continue; 282 283 $mailto = idn_to_utf8($addr_part['mailto']); 284 285 if (!in_array($mailto, $sa_recipients) 289 286 && (!$MESSAGE->compose_from 290 || !in_array_nocase($addr_part['mailto'], $MESSAGE->compose_from) 291 || (count($to_addresses)==1 && $header=='to'))) // allow reply to yourself 292 { 293 $fvalue .= (strlen($fvalue) ? ', ':'').$addr_part['string']; 287 || !in_array_nocase($mailto, $MESSAGE->compose_from) 288 || (count($to_addresses)==1 && $header=='to')) // allow reply to yourself 289 ) { 290 if ($addr_part['name'] && $addr_part['mailto'] != $addr_part['name']) 291 $string = format_email_recipient($mailto, $addr_part['name']); 292 else 293 $string = $mailto; 294 $fvalue .= (strlen($fvalue) ? ', ':'') . $string; 294 295 $sa_recipients[] = $addr_part['mailto']; 295 296 } … … 297 298 } 298 299 } 299 else if ($header && in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) 300 { 300 else if ($header && in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) { 301 301 // get drafted headers 302 302 if ($header=='to' && !empty($MESSAGE->headers->to)) 303 303 $fvalue = $MESSAGE->get_header('to'); 304 305 if ($header=='cc' && !empty($MESSAGE->headers->cc)) 304 else if ($header=='cc' && !empty($MESSAGE->headers->cc)) 306 305 $fvalue = $MESSAGE->get_header('cc'); 307 308 if ($header=='bcc' && !empty($MESSAGE->headers->bcc)) 306 else if ($header=='bcc' && !empty($MESSAGE->headers->bcc)) 309 307 $fvalue = $MESSAGE->get_header('bcc'); 310 } 311 312 308 309 $addresses = $IMAP->decode_address_list($fvalue); 310 $fvalue = ''; 311 312 foreach ($addresses as $addr_part) { 313 if (empty($addr_part['mailto'])) 314 continue; 315 316 $mailto = idn_to_utf8($addr_part['mailto']); 317 318 if ($addr_part['name'] && $addr_part['mailto'] != $addr_part['name']) 319 $string = format_email_recipient($mailto, $addr_part['name']); 320 else 321 $string = $mailto; 322 $fvalue .= (strlen($fvalue) ? ', ':'') . $string; 323 } 324 } 325 326 313 327 if ($fname && $field_type) 314 328 { … … 327 341 $out = $form_start.$out; 328 342 329 return $out; 343 return $out; 330 344 } 331 345 … … 351 365 { 352 366 if (!empty($addr['mailto'])) 353 $a_recipients[] = mb_strtolower( $addr['mailto']);367 $a_recipients[] = mb_strtolower(idn_to_utf8($addr['mailto'])); 354 368 } 355 369 … … 360 374 { 361 375 if (!empty($addr['mailto'])) 362 $a_recipients[] = mb_strtolower( $addr['mailto']);376 $a_recipients[] = mb_strtolower(idn_to_utf8($addr['mailto'])); 363 377 } 364 378 } … … 378 392 foreach ($user_identities as $sql_arr) 379 393 { 394 $sql_arr['email'] = mb_strtolower(idn_to_utf8($sql_arr['email'])); 380 395 $identity_id = $sql_arr['identity_id']; 381 396 $select_from->add(format_email_recipient($sql_arr['email'], $sql_arr['name']), $identity_id); … … 402 417 $from_id = $sql_arr['identity_id']; 403 418 // set identity if it's one of the reply-message recipients (with prio for default identity) 404 else if (in_array( mb_strtolower($sql_arr['email']), $a_recipients) && (empty($from_id) || $sql_arr['standard']))419 else if (in_array($sql_arr['email'], $a_recipients) && (empty($from_id) || $sql_arr['standard'])) 405 420 $from_id = $sql_arr['identity_id']; 406 421 } … … 926 941 $out .= $textfield->show($subject); 927 942 $out .= $form_end ? "\n$form_end" : ''; 928 943 929 944 return $out; 930 945 } -
program/steps/mail/func.inc
r2753a4c re999919 25 25 $SEARCH_MODS_DEFAULT = array('*' => array('subject'=>1, 'from'=>1), $SENT_MBOX => array('subject'=>1, 'to'=>1), $DRAFTS_MBOX => array('subject'=>1, 'to'=>1)); 26 26 27 $EMAIL_ADDRESS_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9][a-z0-9\-\.]*\\.[a-z]{2,5})'; 27 // Simplified for IDN in Unicode 28 //$EMAIL_ADDRESS_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9][a-z0-9\-\.]*\\.[a-z]{2,5})'; 29 $EMAIL_ADDRESS_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[^.].*\\.[a-z]{2,5})'; 28 30 29 31 // actions that do not require imap connection here … … 1242 1244 function rcmail_address_string($input, $max=null, $linked=false, $addicon=null) 1243 1245 { 1244 global $IMAP, $RCMAIL, $PRINT_MODE, $CONFIG , $OUTPUT, $EMAIL_ADDRESS_PATTERN;1246 global $IMAP, $RCMAIL, $PRINT_MODE, $CONFIG; 1245 1247 static $got_writable_abook = null; 1246 1248 … … 1260 1262 foreach ($a_parts as $part) { 1261 1263 $j++; 1264 1265 $name = $part['name']; 1266 $mailto = $part['mailto']; 1267 $string = $part['string']; 1268 1269 // IDNA ASCII to Unicode 1270 if ($name == $mailto) 1271 $name = idn_to_utf8($name); 1272 if ($string == $mailto) 1273 $string = idn_to_utf8($string); 1274 $mailto = idn_to_utf8($mailto); 1275 1262 1276 if ($PRINT_MODE) { 1263 $out .= sprintf('%s <%s>', Q($ part['name']), $part['mailto']);1277 $out .= sprintf('%s <%s>', Q($name), $mailto); 1264 1278 } 1265 1279 else if (check_email($part['mailto'], false)) { 1266 1280 if ($linked) { 1267 1281 $out .= html::a(array( 1268 'href' => 'mailto:'.$ part['mailto'],1269 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ($ part['mailto'])),1270 'title' => $ part['mailto'],1282 'href' => 'mailto:'.$mailto, 1283 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ($mailto)), 1284 'title' => $mailto, 1271 1285 'class' => "rcmContactAddress", 1272 1286 ), 1273 Q($ part['name']));1287 Q($name ? $name : $mailto)); 1274 1288 } 1275 1289 else { 1276 $out .= html::span(array('title' => $part['mailto'], 'class' => "rcmContactAddress"), Q($part['name'])); 1290 $out .= html::span(array('title' => $mailto, 'class' => "rcmContactAddress"), 1291 Q($name ? $name : $mailto)); 1277 1292 } 1278 1293 … … 1280 1295 $out .= ' ' . html::a(array( 1281 1296 'href' => "#add", 1282 'onclick' => sprintf("return %s.command('add-contact','%s',this)", JS_OBJECT_NAME, urlencode($ part['string'])),1297 'onclick' => sprintf("return %s.command('add-contact','%s',this)", JS_OBJECT_NAME, urlencode($string)), 1283 1298 'title' => rcube_label('addtoaddressbook'), 1284 1299 ), … … 1290 1305 } 1291 1306 else { 1292 if ($ part['name'])1293 $out .= Q($ part['name']);1294 if ($ part['mailto'])1295 $out .= (strlen($out) ? ' ' : '') . sprintf('<%s>', Q($ part['mailto']));1307 if ($name) 1308 $out .= Q($name); 1309 if ($mailto) 1310 $out .= (strlen($out) ? ' ' : '') . sprintf('<%s>', Q($mailto)); 1296 1311 } 1297 1312 … … 1376 1391 1377 1392 function rcmail_message_part_controls() 1378 {1393 { 1379 1394 global $MESSAGE; 1380 1395 … … 1398 1413 1399 1414 return $table->show($attrib); 1400 }1415 } 1401 1416 1402 1417 1403 1418 1404 1419 function rcmail_message_part_frame($attrib) 1405 {1420 { 1406 1421 global $MESSAGE; 1407 1422 … … 1412 1427 1413 1428 return html::iframe($attrib); 1414 }1429 } 1415 1430 1416 1431 … … 1419 1434 */ 1420 1435 function rcmail_compose_cleanup() 1421 {1436 { 1422 1437 if (!isset($_SESSION['compose'])) 1423 1438 return; … … 1426 1441 $rcmail->plugins->exec_hook('attachments_cleanup', array()); 1427 1442 $rcmail->session->remove('compose'); 1428 }1443 } 1429 1444 1430 1445 -
program/steps/mail/sendmail.inc
re019f2d re999919 61 61 { 62 62 global $CONFIG, $RCMAIL; 63 if (!$CONFIG['http_received_header_encrypt']) 64 { 63 if (!$CONFIG['http_received_header_encrypt']) { 65 64 return $what; 66 65 } … … 70 69 // get identity record 71 70 function rcmail_get_identity($id) 72 {71 { 73 72 global $USER, $OUTPUT; 74 73 75 if ($sql_arr = $USER->get_identity($id)) 76 { 74 if ($sql_arr = $USER->get_identity($id)) { 77 75 $out = $sql_arr; 78 76 $out['mailto'] = $sql_arr['email']; 79 80 // Special chars as defined by RFC 822 need to in quoted string (or escaped). 81 if (preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $sql_arr['name'])) 82 $name = '"' . addcslashes($sql_arr['name'], '"') . '"'; 83 else 84 $name = $sql_arr['name']; 85 86 $out['string'] = rcube_charset_convert($name, RCMAIL_CHARSET, $OUTPUT->get_charset()); 87 if ($sql_arr['email']) 88 $out['string'] .= ' <' . $sql_arr['email'] . '>'; 77 $out['string'] = format_email_recipient($sql_arr['email'], 78 rcube_charset_convert($sql_arr['name'], RCMAIL_CHARSET, $OUTPUT->get_charset())); 89 79 90 80 return $out; 91 }92 93 return FALSE; 94 }81 } 82 83 return FALSE; 84 } 95 85 96 86 /** … … 147 137 148 138 // parse email address input (and count addresses) 149 function rcmail_email_input_format($mailto, $count=false )139 function rcmail_email_input_format($mailto, $count=false, $check=true) 150 140 { 151 141 global $EMAIL_FORMAT_ERROR, $RECIPIENT_COUNT; … … 164 154 // address in brackets without name (do nothing) 165 155 if (preg_match('/^<\S+@\S+>$/', $item)) { 156 $item = idn_to_ascii($item); 166 157 $result[] = $item; 167 158 // address without brackets and without name (add brackets) 168 159 } else if (preg_match('/^\S+@\S+$/', $item)) { 160 $item = idn_to_ascii($item); 169 161 $result[] = '<'.$item.'>'; 170 162 // address with name (handle name) … … 177 169 $name = '"'.addcslashes($name, '"').'"'; 178 170 } 171 $address = idn_to_ascii($address); 179 172 if (!preg_match('/^<\S+@\S+>$/', $address)) 180 173 $address = '<'.$address.'>'; … … 188 181 // check address format 189 182 $item = trim($item, '<>'); 190 if ($item && !check_email($item)) {183 if ($item && $check && !check_email($item)) { 191 184 $EMAIL_FORMAT_ERROR = $item; 192 185 return; … … 298 291 if (!empty($mailbcc)) 299 292 $headers['Bcc'] = $mailbcc; 300 293 301 294 if (!empty($identity_arr['bcc'])) { 302 295 $headers['Bcc'] = ($headers['Bcc'] ? $headers['Bcc'].', ' : '') . $identity_arr['bcc']; … … 320 313 $headers['Reply-To'] = rcmail_email_input_format(get_input_value('_replyto', RCUBE_INPUT_POST, TRUE, $message_charset)); 321 314 else if (!empty($identity_arr['reply-to'])) 322 $headers['Reply-To'] = $identity_arr['reply-to'];315 $headers['Reply-To'] = rcmail_email_input_format($identity_arr['reply-to'], false, true); 323 316 324 317 if (!empty($_SESSION['compose']['reply_msgid'])) 325 318 $headers['In-Reply-To'] = $_SESSION['compose']['reply_msgid']; 326 319 327 320 // remember reply/forward UIDs in special headers 328 321 if (!empty($_SESSION['compose']['reply_uid']) && $savedraft) -
program/steps/settings/edit_identity.inc
re019f2d re999919 95 95 } 96 96 97 $IDENTITY_RECORD['email'] = idn_to_utf8($IDENTITY_RECORD['email']); 98 $IDENTITY_RECORD['reply-to'] = idn_to_utf8($IDENTITY_RECORD['reply-to']); 99 $IDENTITY_RECORD['bcc'] = idn_to_utf8($IDENTITY_RECORD['bcc']); 100 97 101 // Allow plugins to modify identity form content 98 102 $plugin = $RCMAIL->plugins->exec_hook('identity_form', array( -
program/steps/settings/func.inc
re019f2d re999919 73 73 $list = $USER->list_identities(); 74 74 foreach ($list as $idx => $row) 75 $list[$idx]['mail'] = trim($row['name'] . ' <' . $row['email'].'>');75 $list[$idx]['mail'] = trim($row['name'] . ' <' . idn_to_utf8($row['email']) .'>'); 76 76 77 77 // get all identites from DB and define list of cols to be displayed -
program/steps/settings/save_identity.inc
re019f2d re999919 57 57 unset($save_data['email']); 58 58 59 // Validate e-mail addresses 60 foreach (array('email', 'reply-to', 'bcc') as $item) { 61 if ($email = $save_data[$item]) { 62 $ascii_email = idn_to_ascii($email); 63 if (!check_email($ascii_email, false)) { 64 // show error message 65 $OUTPUT->show_message('emailformaterror', 'error', array('email' => $email), false); 66 rcmail_overwrite_action('edit-identity'); 67 return; 68 } 69 } 70 } 59 71 60 72 // update an existing contact … … 64 76 $plugin = $RCMAIL->plugins->exec_hook('identity_update', array('id' => $iid, 'record' => $save_data)); 65 77 $save_data = $plugin['record']; 78 79 if ($save_data['email']) 80 $save_data['email'] = idn_to_ascii($save_data['email']); 81 if ($save_data['bcc']) 82 $save_data['bcc'] = idn_to_ascii($save_data['bcc']); 83 if ($save_data['reply-to']) 84 $save_data['reply-to'] = idn_to_ascii($save_data['reply-to']); 66 85 67 86 if (!$plugin['abort'] && ($updated = $USER->update_identity($iid, $save_data))) … … 75 94 { 76 95 // update the changed col in list 77 // ... 96 // ... 78 97 } 79 98 } … … 95 114 $plugin = $RCMAIL->plugins->exec_hook('identity_create', array('record' => $save_data)); 96 115 $save_data = $plugin['record']; 116 117 $save_data['email'] = idn_to_ascii($save_data['email']); 118 $save_data['bcc'] = idn_to_ascii($save_data['bcc']); 119 $save_data['reply-to'] = idn_to_ascii($save_data['reply-to']); 97 120 98 121 if (!$plugin['abort'] && $save_data['email'] && ($insert_id = $USER->insert_identity($save_data)))
Note: See TracChangeset
for help on using the changeset viewer.
