[issue46943] fix[imaplib]: call Exception with string instance
SpaceOne added the comment: @iritkatriel alright, I am sorry. I created another PR: https://github.com/python/cpython/pull/31823 -- ___ Python tracker <https://bugs.python.org/issue46943> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46943] fix[imaplib]: call Exception with string instance
Change by SpaceOne : -- pull_requests: +29920 pull_request: https://github.com/python/cpython/pull/31823 ___ Python tracker <https://bugs.python.org/issue46943> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46943] fix[imaplib]: call Exception with string instance
SpaceOne added the comment: @iritkatriel they were automatically added by github via your `.github/CODEOWNERS` file with the `**/*imap* @python/email-team` match. And they all will also be informed by another pull request. -- ___ Python tracker <https://bugs.python.org/issue46943> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46943] fix[imaplib]: call Exception with string instance
SpaceOne added the comment: @iritkatriel I added a unit test to the branch. I can't create a new PR without creating a new branch. But that doesn't make much sense from a technical point. It only increases the number of existing merge requests. Also all the people subscribed to the current MR will receive another email for the new merge request. So just clicking on "Reopen" on your side should be simple. -- ___ Python tracker <https://bugs.python.org/issue46943> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46943] fix[imaplib]: call Exception with string instance
New submission from SpaceOne : imaplib raises an Exception with a bytes instance once (in login()) - all other places str instances are raised. Adjust the behavior of login() similar to authenticate() where self.error is called with a str instance. Especially for Python3 with strict bytes mode (-bb) this is helpful and prevents: Traceback (most recent call last): in "" self.login(email, password) File "/usr/lib/python3.7/imaplib.py", line 598, in login raise self.error(dat[-1]) imaplib.error: During handling of the above exception, another exception occurred: Traceback (most recent call last): in "" str(exc) BytesWarning: str() on a bytes instance -- components: Library (Lib) messages: 414657 nosy: spaceone priority: normal severity: normal status: open title: fix[imaplib]: call Exception with string instance versions: Python 3.10, Python 3.11, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue46943> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue46943] fix[imaplib]: call Exception with string instance
Change by SpaceOne : -- keywords: +patch pull_requests: +29837 stage: -> patch review pull_request: https://github.com/python/cpython/pull/31722 ___ Python tracker <https://bugs.python.org/issue46943> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue40837] email.utils.encode_rfc2231(string, None, None) returns broken value
New submission from SpaceOne : `encode_rfc2231()` must not change the returned value if no transformation of the input was done. This is also mentioned in the docstring of that function. Actual behavior: encode_rfc2231('foo bar', None, None) 'foo%20bar' Expected behavior: encode_rfc2231('foo bar', None, None) 'foo bar' -- components: Library (Lib) messages: 370526 nosy: spaceone priority: normal pull_requests: 19805 severity: normal status: open title: email.utils.encode_rfc2231(string, None, None) returns broken value type: behavior versions: Python 3.5, Python 3.6, Python 3.7 ___ Python tracker <https://bugs.python.org/issue40837> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23245] urllib2: urlopen() gets exception(kwargs bug?)
SpaceOne added the comment: Nice that you investigate again into this issue. Could you please test if this still happens on python 2.7.10 as I unfortunately have no environment with that version. This would be very kind of you! -- ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue23245> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23245] urllib2: urlopen() gets exception(kwargs bug?)
SpaceOne added the comment: Hello, The resolution of this bug is "not a bug". If that is the case can you please add information how to fix/workaround this. I have got the following valid-seeming code: """ import cookielib import urllib import urllib2 cookie = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie)) opener.open('https://www.google.com', timeout=2) """ Which results in: Traceback (most recent call last): File "httplib_context_bug.py", line 6, in opener.open('https://www.google.com', timeout=2) File "/usr/lib/python2.7/urllib2.py", line 431, in open response = self._open(req, data) File "/usr/lib/python2.7/urllib2.py", line 449, in _open '_open', req) File "/usr/lib/python2.7/urllib2.py", line 409, in _call_chain result = func(*args) File "/usr/lib/python2.7/urllib2.py", line 1240, in https_open context=self._context) File "/usr/lib/python2.7/urllib2.py", line 1166, in do_open h = http_class(host, timeout=req.timeout, **http_conn_args) TypeError: __init__() got an unexpected keyword argument 'context' $ python Python 2.7.9 (default, Mar 1 2015, 12:57:24) $ cat /etc/issue Debian GNU/Linux 8 \n \l -- nosy: +spaceone ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue23245> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26196] Argparse breaks when a switch is given an argument beginning with a dash
Changes by SpaceOne <pyt...@florianbest.de>: -- nosy: +spaceone ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue26196> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue9334] argparse does not accept options taking arguments beginning with dash (regression from optparse)
Changes by SpaceOne <pyt...@florianbest.de>: -- nosy: +spaceone ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue9334> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25880] u'..'.encode('idna') → UnicodeError: label empty or too long
SpaceOne added the comment: It makes error handling really hard. Here is a patch: https://github.com/python/cpython/compare/master...spaceone:idna?expand=1 -- status: closed -> open ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25880> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25880] u'..'.encode('idna') → UnicodeError: label empty or too long
SpaceOne added the comment: Because i need to do everywhere where I use this: try: user_input.encode(encoding) except UnicodeDecodeError: raise except (UnicodeError, UnicodeEncodeError): do_my_error_handling() instead of try: user_input.encode(encoding) except UnicodeEncodeError: do_my_error_handling() -- ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25880> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25880] u'..'.encode('idna') → UnicodeError: label empty or too long
SpaceOne added the comment: I know that UnicodeEncodeError is a subclass of UnicodeError. The problem here is that UnicodeError would also catch UnicodeDecodeError. This is especially disturbing if you catch errors of a whole function. If you e.g. use python2.7 you might want to catch only UnicodeEncodeError if you encode something and don't want to catch UnicodeDecodeError. >>> b'\xff'.encode('utf-8') Traceback (most recent call last): File "", line 1, in UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128) (Read that code carefully!!! It's not something which should ever be done but might happen in the world) Especially if you are writing python2+3 compatible applications. -- ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25880> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25880] u'..'.encode('idna') → UnicodeError: label empty or too long
SpaceOne added the comment: But why is the error UnicodeError instead of UnicodeEncodeError? -- resolution: not a bug -> status: closed -> open ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25880> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25880] u'..'.encode('idna') → UnicodeError: label empty or too long
New submission from SpaceOne: Python 3.4.2 (default, Oct 8 2014, 10:45:20) >>> u'..'.encode('idna') Traceback (most recent call last): File "/usr/lib/python3.4/encodings/idna.py", line 165, in encode raise UnicodeError("label empty or too long") UnicodeError: label empty or too long The above exception was the direct cause of the following exception: Traceback (most recent call last): File "", line 1, in UnicodeError: encoding with 'idna' codec failed (UnicodeError: label empty or too long) → I was expecting that this raises either not at all or UnicodeEncodeError. >>> b'..'.decode('idna') '..' → Why doesn't this raise then, too? The error message is also messed up which wasn't the case in python 2.7. It could be cleaned up. -- components: Unicode messages: 256514 nosy: ezio.melotti, haypo, spaceone priority: normal severity: normal status: open title: u'..'.encode('idna') → UnicodeError: label empty or too long versions: Python 2.7, Python 3.4 ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25880> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25738] http.server doesn't handle RESET CONTENT status correctly
New submission from SpaceOne: The status 205 RESET CONTENT is not correctly evaluated by http.server. It MUST NOT write a response body to the client. Patch: https://github.com/spaceone/cpython/commit/17048e2e7349cc4861c7fe90299f2c092b8e1604 -- components: Library (Lib) messages: 255443 nosy: spaceone priority: normal severity: normal status: open title: http.server doesn't handle RESET CONTENT status correctly ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25738> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25739] Add PAYLOAD_TOO_LARGE (new name in RFC 7231)
New submission from SpaceOne: Add PAYLOAD_TOO_LARGE status code to http package. Patch: https://github.com/spaceone/cpython/commit/5d9427a07bde43b523386322b1fc377618eadb76 -- components: Library (Lib) messages: 255444 nosy: spaceone priority: normal severity: normal status: open title: Add PAYLOAD_TOO_LARGE (new name in RFC 7231) ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25739> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25723] ConfigParser should never write broken configurations
SpaceOne added the comment: Of course both of you have reasonable arguments. For compatibility with overridden SECTRE attributes it should not raise ValueError for characters like [ and ]. (too bad that SECTRE is a public attribute otherwise it could also be used to validate the name (SECTRE.match('[%s]')). What if somebody changed SECTRE to multiline? Then even rejecting '\n' would break compatibility. But: How often does this happen? In open source projects it seems none. A nullege.com and google search exposed that no project does this. Terry, I completely agree with your argument "that blindly inserting external input into a database is bad idea". But in the real world it happens that there are many applications out which doesn't validate what they pass into .add_section(). (Do you want me to give you a list of python projects which are either broken or vulnerable?). In my opinion this is dangerous, as well as not validating HTTP/Mail/MIME headers for such characters and so on. What's the goal of python here? Giving programmers nice utilities which have security considerations in its software design by default or giving everything up to the programmer which is forced to never trust the stdlib and always have to read the source code it uses? As I understand when I read the documentation is that config parser is loosely based on M$ INI files and as the name says it is for configuration files. Usually(!) configuration files are human readable files editable with an editor. Disallowing non-printable characters would have been the best option in the first release of config parser. >From my experience it is good to restrict things from the beginning and make >them overrideable to be more relaxed if this is really needed. And regarding issue20923: I think it would be a great feature to include the code change instead of changing the documentation. In my research about add_section() I found some projects which uses URI's as section name. As you know the WWW is evolving and actually http://[::1]/ is a valid URI nowadays. If this would be changed these implementations will not have to overwrite SECTRE in the future and they also won't run into that bug one day. I adapted my commit to only disallow \r \n and \x00. [ ] are allowed for customization of SECTRE. https://github.com/spaceone/cpython/commit/a0cdb85e4c7c4dd71a87b1f6c4d9d92ece2dde15 -- ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25723> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25739] Add PAYLOAD_TOO_LARGE / URI_TOO_LONG (new name in RFC 7231)
SpaceOne added the comment: Also URI_TOO_LONG has been changed. https://tools.ietf.org/html/rfc7231#section-6.5.11 https://tools.ietf.org/html/rfc7231#section-6.5.12 -- title: Add PAYLOAD_TOO_LARGE (new name in RFC 7231) -> Add PAYLOAD_TOO_LARGE / URI_TOO_LONG (new name in RFC 7231) ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25739> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25740] multiple issues in http.client
New submission from SpaceOne: * RESET_CONTENT not evaluated * negative chunk size accepted * invalid ports accepted * success status !== 200 ignored Patch: https://github.com/spaceone/cpython/commit/3289080306408db971f8b816d3e9f0ab44ed392b Part of github Pull Request https://github.com/python/cpython/pull/19 from July. Should I split this up into multiple bugtracker issues? -- components: Library (Lib) messages: 255445 nosy: spaceone priority: normal severity: normal status: open title: multiple issues in http.client ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25740> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25723] ConfigParser should never write broken configurations
SpaceOne added the comment: Isn't is an actual problem in the field? We had a vulnerability in our code due to this as we only sanitized the config values and didn't recognized that add_section() does no validation of input. -- ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25723> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue20923] ConfigParser should nested [] in section names.
SpaceOne added the comment: Sorry about that! I created http://bugs.python.org/issue25723. -- ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue20923> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue20923] ConfigParser should nested [] in section names.
SpaceOne added the comment: IMHO your rejection is stupid. User input should always be validated. At least a ValueError should be raised if add_section() is called with a string containing ']\x00\n['. As this will always create a broken configuration. Otherwise ConfigParser cannot be used to write new config files without having deeper knowledge about the implementation. -- nosy: +spaceone ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue20923> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25723] ConfigParser should never write broken configurations
New submission from SpaceOne: >>> from configparser import ConfigParser >>> from io import StringIO >>> from configparser import ConfigParser >>> c = ConfigParser() >>> c.add_section('foo]\nbar=baz\n[bar') >>> fd = StringIO() >>> c.write(fd) >>> print(fd.getvalue()) [foo] bar=baz [bar] User input should always be validated. At least a ValueError should be raised if add_section() is called with a string containing anything like ']\x00\n[' or any other non-printable string. As this will always create a broken configuration or might lead to ini-injections. Otherwise ConfigParser cannot be used to write new config files without having deeper knowledge about the implementation. See also: http://bugs.python.org/issue23301 http://bugs.python.org/issue20923 -- components: Library (Lib) messages: 255270 nosy: spaceone priority: normal severity: normal status: open title: ConfigParser should never write broken configurations type: behavior versions: Python 2.7, Python 3.2, Python 3.3, Python 3.4, Python 3.5, Python 3.6 ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25723> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue25723] ConfigParser should never write broken configurations
SpaceOne added the comment: I would have expected something like ValueError('A section must not contain any of ...') or at least that the characters are simply stripped. -- ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25723> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24558] shutil.copytree with symlinks=True opens vulnerabilities
New submission from SpaceOne: shutil.copytree(src, dst, symlink=True) destroys file system permissions and open security issues. See the following python/bash session: # ls -l /etc/shadow -rw-r- 1 root shadow 1114 May 8 19:10 /etc/shadow # su foobar $ ln -s /etc/shadow exit # python -c '__import__(shutil).copytree('/home/', '/backups/home', symlinks=True) # ls -l /etc/shadow -rw-r- 1 foobar Domain Users 1114 Mai 8 19:10 /etc/shadow As you can see the file /etc/shadow is now owned by the user foobar and its primary group. -- components: Distutils messages: 246170 nosy: dstufft, eric.araujo, spaceone priority: normal severity: normal status: open title: shutil.copytree with symlinks=True opens vulnerabilities type: security ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue24558 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24558] shutil.copytree with symlinks=True opens vulnerabilities
SpaceOne added the comment: argh. sorry. I did not read the following lines in my environment which caused this by a recursive chown. -- resolution: - rejected status: open - closed ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue24558 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24558] shutil.copytree with symlinks=True opens vulnerabilities
SpaceOne added the comment: my workaround is: import os.path def ignore(src, names): return [name for name in names if os.path.islink(os.path.join(src, name))] shutil.copytree(src, dst, ignore=ignore) -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue24558 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue11874] argparse assertion failure with brackets in metavars
Changes by SpaceOne pyt...@florianbest.de: -- nosy: +spaceone ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue11874 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue24089] argparse crashes with AssertionError
New submission from SpaceOne: Just add an argument with metavar='[PROTOCOL://]HOST[:PORT]' ([...] twice in the string) causes the following traceback: Traceback (most recent call last): File curl.py, line 182, in module arguments = parser.parse_args() File /usr/lib/python2.7/argparse.py, line 1701, in parse_args args, argv = self.parse_known_args(args, namespace) File /usr/lib/python2.7/argparse.py, line 1733, in parse_known_args namespace, args = self._parse_known_args(args, namespace) File /usr/lib/python2.7/argparse.py, line 1939, in _parse_known_args start_index = consume_optional(start_index) File /usr/lib/python2.7/argparse.py, line 1879, in consume_optional take_action(action, args, option_string) File /usr/lib/python2.7/argparse.py, line 1807, in take_action action(self, namespace, argument_values, option_string) File /usr/lib/python2.7/argparse.py, line 996, in __call__ parser.print_help() File /usr/lib/python2.7/argparse.py, line 2340, in print_help self._print_message(self.format_help(), file) File /usr/lib/python2.7/argparse.py, line 2314, in format_help return formatter.format_help() File /usr/lib/python2.7/argparse.py, line 281, in format_help help = self._root_section.format_help() File /usr/lib/python2.7/argparse.py, line 211, in format_help func(*args) File /usr/lib/python2.7/argparse.py, line 332, in _format_usage assert ' '.join(opt_parts) == opt_usage AssertionError -- components: Distutils messages: 242299 nosy: dstufft, eric.araujo, spaceone priority: normal severity: normal status: open title: argparse crashes with AssertionError type: crash versions: Python 2.7 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue24089 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue9698] When reusing an handler, urllib(2)'s digest authentication fails after multiple regative replies
Changes by SpaceOne pyt...@florianbest.de: -- nosy: +spaceone ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue9698 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23777] argparse subcommand action can't be specified
New submission from SpaceOne: parser.add_subparsers(dest='arguments', action='append') will raise the following exception: File /usr/lib/python2.7/argparse.py, line 1675, in add_subparsers action = parsers_class(option_strings=[], **kwargs) TypeError: __init__() got an unexpected keyword argument 'prog' Instead of 'argparse._SubParsersAction' the class 'argparse._AppendAction' is used. Could maybe fixed by passing the 'action' parameter to the _SubParsersAction class which then instanciates a _AppendAction and somehow uses this internally for further things. -- components: Library (Lib) messages: 239246 nosy: spaceone priority: normal severity: normal status: open title: argparse subcommand action can't be specified type: crash versions: Python 2.7 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue23777 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23487] argparse: add_subparsers 'action' broken
SpaceOne added the comment: In replay to msg238931 from paul j3 (paul.j3) * And specifying something other than the default 'store' action class for the arguments of the parsers doesn't make sense. Of course it makes sense. If you e.g. want the action to be 'append' so that the subparser-name is appended to a already existing list / or to create a new list with the subparser-name as first argument. E.g.: parser.add_subparser(dest='foo', action='append') parser.parse_args('bar').__dict__ == {'foo': ['bar']} -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue23487 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com