Skip to content

Commit

Permalink
Merge with 3.5
Browse files Browse the repository at this point in the history
  • Loading branch information
zooba committed Sep 9, 2016
2 parents 06aed90 + 6ceda63 commit 2a2becc
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 10 deletions.
9 changes: 5 additions & 4 deletions Lib/email/contentmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,13 @@ def _finalize_set(msg, disposition, filename, cid, params):
msg.set_param(key, value)


# XXX: This is a cleaned-up version of base64mime.body_encode. It would
# be nice to drop both this and quoprimime.body_encode in favor of
# enhanced binascii routines that accepted a max_line_length parameter.
# XXX: This is a cleaned-up version of base64mime.body_encode (including a bug
# fix in the calculation of unencoded_bytes_per_line). It would be nice to
# drop both this and quoprimime.body_encode in favor of enhanced binascii
# routines that accepted a max_line_length parameter.
def _encode_base64(data, max_line_length):
encoded_lines = []
unencoded_bytes_per_line = max_line_length * 3 // 4
unencoded_bytes_per_line = max_line_length // 4 * 3
for i in range(0, len(data), unencoded_bytes_per_line):
thisline = data[i:i+unencoded_bytes_per_line]
encoded_lines.append(binascii.b2a_base64(thisline).decode('ascii'))
Expand Down
12 changes: 10 additions & 2 deletions Lib/test/test_email/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ def example_as_myfunc_input(self, name, count):
Note: if and only if the generated test name is a valid identifier can it
be used to select the test individually from the unittest command line.
The values in the params dict can be a single value, a tuple, or a
dict. If a single value of a tuple, it is passed to the test function
as positional arguments. If a dict, it is a passed via **kw.
"""
paramdicts = {}
testers = collections.defaultdict(list)
Expand Down Expand Up @@ -148,8 +152,12 @@ def example_as_myfunc_input(self, name, count):
if name.startswith(paramsname):
testnameroot = 'test_' + name[len(paramsname):]
for paramname, params in paramsdict.items():
test = (lambda self, name=name, params=params:
getattr(self, name)(*params))
if hasattr(params, 'keys'):
test = (lambda self, name=name, params=params:
getattr(self, name)(**params))
else:
test = (lambda self, name=name, params=params:
getattr(self, name)(*params))
testname = testnameroot + '_' + paramname
test.__name__ = testname
testfuncs[testname] = test
Expand Down
23 changes: 22 additions & 1 deletion Lib/test/test_email/test_inversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io
import unittest
from email import policy, message_from_bytes
from email.message import EmailMessage
from email.generator import BytesGenerator
from test.test_email import TestEmailBase, parameterize

Expand All @@ -23,7 +24,10 @@ def dedent(bstr):


@parameterize
class TestInversion(TestEmailBase, unittest.TestCase):
class TestInversion(TestEmailBase):

policy = policy.default
message = EmailMessage

def msg_as_input(self, msg):
m = message_from_bytes(msg, policy=policy.SMTP)
Expand All @@ -44,6 +48,23 @@ def msg_as_input(self, msg):

}

payload_params = {
'plain_text': dict(payload='This is a test\n'*20),
'base64_text': dict(payload=(('xy a'*40+'\n')*5), cte='base64'),
'qp_text': dict(payload=(('xy a'*40+'\n')*5), cte='quoted-printable'),
}

def payload_as_body(self, payload, **kw):
msg = self._make_message()
msg['From'] = 'foo'
msg['To'] = 'bar'
msg['Subject'] = 'payload round trip test'
msg.set_content(payload, **kw)
b = bytes(msg)
msg2 = message_from_bytes(b, policy=self.policy)
self.assertEqual(bytes(msg2), b)
self.assertEqual(msg2.get_content(), payload)


if __name__ == '__main__':
unittest.main()
5 changes: 5 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ Core and Builtins
Library
-------

- Issue #24594: Validates persist parameter when opening MSI database

- Issue #28047: Fixed calculation of line length used for the base64 CTE
in the new email policies.

- Issue #27576: Fix call order in OrderedDict.__init__().

- email.generator.DecodedGenerator now supports the policy keyword.
Expand Down
20 changes: 17 additions & 3 deletions PC/_msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -955,18 +955,32 @@ static PyTypeObject msidb_Type = {
0, /*tp_is_gc*/
};

#define Py_NOT_PERSIST(x, flag) \
(x != (int)(flag) && \
x != ((int)(flag) | MSIDBOPEN_PATCHFILE))

#define Py_INVALID_PERSIST(x) \
(Py_NOT_PERSIST(x, MSIDBOPEN_READONLY) && \
Py_NOT_PERSIST(x, MSIDBOPEN_TRANSACT) && \
Py_NOT_PERSIST(x, MSIDBOPEN_DIRECT) && \
Py_NOT_PERSIST(x, MSIDBOPEN_CREATE) && \
Py_NOT_PERSIST(x, MSIDBOPEN_CREATEDIRECT))

static PyObject* msiopendb(PyObject *obj, PyObject *args)
{
int status;
char *path;
int persist;
MSIHANDLE h;
msiobj *result;

if (!PyArg_ParseTuple(args, "si:MSIOpenDatabase", &path, &persist))
return NULL;

status = MsiOpenDatabase(path, (LPCSTR)persist, &h);
/* We need to validate that persist is a valid MSIDBOPEN_* value. Otherwise,
MsiOpenDatabase may treat the value as a pointer, leading to unexpected
behavior. */
if (Py_INVALID_PERSIST(persist))
return msierror(ERROR_INVALID_PARAMETER);
status = MsiOpenDatabase(path, (LPCSTR)persist, &h);
if (status != ERROR_SUCCESS)
return msierror(status);

Expand Down

0 comments on commit 2a2becc

Please sign in to comment.