From 5c264788422b7c29dd1bc05210ea4292ae0400dc Mon Sep 17 00:00:00 2001 From: David Flatz Date: Fri, 29 Jul 2022 14:44:35 +0200 Subject: rename _escape functions to _encode --- it_mail.class | 40 +++++++++++++++++++++++++--------------- test/it_mail.t | 22 +++++++++++----------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/it_mail.class b/it_mail.class index 94801a5..2342778 100644 --- a/it_mail.class +++ b/it_mail.class @@ -82,7 +82,7 @@ function add_header($header, $value) { case 'To': foreach ((array)$value as $val) - $this->to[] = $this->addrlist_escape($val); + $this->to[] = $this->addrlist_encode($val); break; case 'Subject': @@ -91,12 +91,12 @@ function add_header($header, $value) case 'Cc': foreach ((array)$value as $val) - $this->cc[] = $this->addrlist_escape($val); + $this->cc[] = $this->addrlist_encode($val); break; case 'Bcc': foreach ((array)$value as $val) - $this->bcc[] = $this->addrlist_escape($val); + $this->bcc[] = $this->addrlist_encode($val); break; case 'charset': @@ -108,7 +108,7 @@ function add_header($header, $value) /* FALLTHROUGH */ default: $this->header_names[] = $header; - $this->header_values[] = $header == 'From' || $header =='Reply-To' ? $this->addrlist_escape($value) : $this->header_escape($value); + $this->header_values[] = $header == 'From' || $header =='Reply-To' ? $this->addrlist_encode($value) : $this->header_encode($value); break; } } @@ -278,7 +278,7 @@ function send($p = array()) foreach ($this->attachments as $attachment) { - $name = $this->header_escape($attachment['name']); + $name = $this->header_encode($attachment['name']); $text .= "\n--$boundary\nContent-Type: {$attachment['mimetype']}; name=\"$name\"\nContent-Transfer-Encoding: base64\nContent-ID: <{$attachment['cid']}>\nContent-Disposition: {$attachment['disposition']}; filename=\"$name\"\n\n"; $text .= chunk_split(base64_encode($attachment['data'])); } @@ -291,12 +291,12 @@ function send($p = array()) if (it::is_live() || EDC('forcemail') || $p['forcemail']) { - if (($result = mail($to, $this->header_escape($this->subject), $text, implode("\n", $headers), $this->flags)) === false) + if (($result = mail($to, $this->header_encode($this->subject), $text, implode("\n", $headers), $this->flags)) === false) it::error(['title' => "failed sending mail to $to subject $this->subject", 'body' => ['text' => $text, 'headers' => $headers, 'flags' => $this->flags]]); return $result; } else - return ED($to, $this->header_escape($this->subject), $text, $headers, $this->flags); + return ED($to, $this->header_encode($this->subject), $text, $headers, $this->flags); } @@ -369,7 +369,7 @@ static function addrlist_split($string) * @param $string String to be escaped * @return String escape suitable for sending in header line */ -function header_escape($string) +function header_encode($string) { return preg_match('/[\x00-\x1f\x7f-\xff]/', $string) ? ltrim( @@ -388,15 +388,15 @@ function header_escape($string) * @param $string String containing address list * @return String suitable for sending in address list headers */ -function addrlist_escape($string) +function addrlist_encode($string) { # Exclude e-mail addresses from being encoded as # e.g. GMail or Exchange have problems with that foreach (self::addrlist_split($string) as list($name, $email)) { - $email = self::email_escape($email); + $email = self::email_encode($email); if ($name && $email) - $result[] = $this->header_escape(trim($name)) . " <$email>"; + $result[] = $this->header_encode(trim($name)) . " <$email>"; else if (!$name && $email) $result[] = $email; } @@ -411,12 +411,22 @@ function addrlist_escape($string) * @param $string Fulle name to be escaped * @return String to be safely used in "$fullname <$email>" for To: etc. */ -static function fullname_escape($string) +static function fullname_encode($string) { return '"' . preg_replace('/["\x00-\x1f]/', '', $string) . '"'; } + +/** + * Legacy function + */ +static function fullname_escape($string) +{ + return fullname_encode($string); +} + + /** * INTERNAL: Split email-address into local part and doomain * @return Array with to elements: local part and domain @@ -451,7 +461,7 @@ static function email_split($email) * INTERNAL: Convert domain part of email address into ascii idn form * @return String with converted email address */ -static function email_escape($email) +static function email_encode($email) { list($local, $domain) = self::email_split($email); @@ -506,7 +516,7 @@ static function address_error($addresslist) { foreach (self::addrlist_split($addresslist) as list($dummy, $email)) { - $email = self::email_escape($email); + $email = self::email_encode($email); if (filter_var($email, FILTER_VALIDATE_EMAIL) === false && !it::match('^\s*[a-z][-a-z0-9]*\s*$', $email)) return "invalid format on $email"; } @@ -526,7 +536,7 @@ static function check_email($email, $checkmailbox = false) { $result = IT_MAIL_CHECKEMAIL_INVALID; - $email = self::email_escape($email); + $email = self::email_encode($email); list($dummy, $domain) = self::email_split($email); /* Check if username starts with www. or not well-formed => reject */ if (!preg_match('/^www\./', $email) && filter_var($email, FILTER_VALIDATE_EMAIL) !== false && $domain) diff --git a/test/it_mail.t b/test/it_mail.t index 6aefd84..41a92b1 100755 --- a/test/it_mail.t +++ b/test/it_mail.t @@ -7,19 +7,19 @@ $mail = new it_mail(); # header_escape tests # is( - $mail->addrlist_escape('éxample@example.com', true), + $mail->addrlist_encode('éxample@example.com', true), 'éxample@example.com', "Don't escape plain email addresses in email headers" ); is( - $mail->header_escape('éxample@example.com'), + $mail->header_encode('éxample@example.com'), '=?utf-8?Q?=C3=A9xample@example.com?=', "Escape plain email in non-email headers" ); is( - $mail->header_escape('search.ch e-mail code d\'accès'), + $mail->header_encode('search.ch e-mail code d\'accès'), version_compare(PHP_VERSION, '7.2.11') < 0 ? '=?utf-8?B?c2VhcmNoLmNoIGUtbWFpbCBjb2RlIGQnYWNjw6hz?=' : '=?utf-8?Q?search.ch=20e-mail=20code=20d\'acc=C3=A8s?=', @@ -27,37 +27,37 @@ is( ); is( - $mail->addrlist_escape('Èxample User <èxample@example.com>', true), + $mail->addrlist_encode('Èxample User <èxample@example.com>', true), '=?utf-8?Q?=C3=88xample=20User?= <èxample@example.com>', "Escape name but not email in email headers" ); is( - $mail->addrlist_escape('Example User ', true), + $mail->addrlist_encode('Example User ', true), 'Example User ', "Don't escape characters that don't need escaping" ); is( - $mail->addrlist_escape('example@example.com, éxample@example.com, Sömeone Ëlse ', true), + $mail->addrlist_encode('example@example.com, éxample@example.com, Sömeone Ëlse ', true), 'example@example.com, éxample@example.com, =?utf-8?Q?S=C3=B6meone=20=C3=8Blse?= ', "Don't escape email addresses but escape realnames" ); is( - $mail->addrlist_escape('"Alfred E. Neuman" ', true), + $mail->addrlist_encode('"Alfred E. Neuman" ', true), '"Alfred E. Neuman" ', "Don't remove quoting characters from realname" ); is( - $mail->addrlist_escape('"Schmitt, Sören" ', true), + $mail->addrlist_encode('"Schmitt, Sören" ', true), '=?utf-8?Q?"Schmitt,=20S=C3=B6ren"?= ', "Don't remove quoting characters from realname when it contains a quotable character" ); is( - $mail->addrlist_escape('"Alfred E. Neuman" ', true), + $mail->addrlist_encode('"Alfred E. Neuman" ', true), '"Alfred E. Neuman" ', "Convert domain in email to idn version" ); @@ -119,5 +119,5 @@ is(it_mail::email_split('test@sör.ch'), ['test', 'sör.ch'], 'email_split test@ is(it_mail::email_split('"test@local.ch".foo.bar@search.ch'), ['"test@local.ch".foo.bar', 'search.ch'], 'email_split "test@local.ch".foo.bar@search.ch'); is(it_mail::email_split('aneuman'), ['aneuman', ''], 'email_split aneuman'); -is(it_mail::email_escape('test@sör.ch'), 'test@xn--sr-fka.ch', 'idn encode domain sör.ch'); -is(it_mail::email_escape('أحمد@مثال.آزمایشی'), 'أحمد@xn--mgbh0fb.xn--hgbk6aj7f53bba', 'idn encode domain ﻢﺛﺎﻟ.ﺁﺰﻣﺎﯿﺸﯾ'); +is(it_mail::email_encode('test@sör.ch'), 'test@xn--sr-fka.ch', 'idn encode domain sör.ch'); +is(it_mail::email_encode('أحمد@مثال.آزمایشی'), 'أحمد@xn--mgbh0fb.xn--hgbk6aj7f53bba', 'idn encode domain ﻢﺛﺎﻟ.ﺁﺰﻣﺎﯿﺸﯾ'); -- cgit v1.2.3