summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-03-20 07:00:36 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2015-03-20 07:00:36 (GMT)
commit8490f5acfee7269ac0eb41257a3a214dfb31a655 (patch)
tree7cd039c0f6418571d9f8cc89741c3ec4938f2ebc /Modules
parent0eac13052c498e21cbb60ed321e5a9ea10d07b35 (diff)
downloadcpython-8490f5acfee7269ac0eb41257a3a214dfb31a655.zip
cpython-8490f5acfee7269ac0eb41257a3a214dfb31a655.tar.gz
cpython-8490f5acfee7269ac0eb41257a3a214dfb31a655.tar.bz2
Issue #23001: Few functions in modules mmap, ossaudiodev, socket, ssl, and
codecs, that accepted only read-only bytes-like object now accept writable bytes-like object too.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_codecsmodule.c15
-rw-r--r--Modules/_ssl.c8
-rw-r--r--Modules/mmapmodule.c28
-rw-r--r--Modules/ossaudiodev.c28
-rw-r--r--Modules/socketmodule.c107
5 files changed, 111 insertions, 75 deletions
diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c
index bf408af..b9268ce 100644
--- a/Modules/_codecsmodule.c
+++ b/Modules/_codecsmodule.c
@@ -208,15 +208,18 @@ static PyObject *
escape_decode(PyObject *self,
PyObject *args)
{
+ Py_buffer pbuf;
const char *errors = NULL;
- const char *data;
- Py_ssize_t size;
+ PyObject *result;
- if (!PyArg_ParseTuple(args, "s#|z:escape_decode",
- &data, &size, &errors))
+ if (!PyArg_ParseTuple(args, "s*|z:escape_decode",
+ &pbuf, &errors))
return NULL;
- return codec_tuple(PyBytes_DecodeEscape(data, size, errors, 0, NULL),
- size);
+ result = codec_tuple(
+ PyBytes_DecodeEscape(pbuf.buf, pbuf.len, errors, 0, NULL),
+ pbuf.len);
+ PyBuffer_Release(&pbuf);
+ return result;
}
static PyObject *
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index fb03513..be6fca3 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -3672,18 +3672,22 @@ static PyTypeObject PySSLMemoryBIO_Type = {
static PyObject *
PySSL_RAND_add(PyObject *self, PyObject *args)
{
- char *buf;
+ Py_buffer view;
+ const char *buf;
Py_ssize_t len, written;
double entropy;
- if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy))
+ if (!PyArg_ParseTuple(args, "s*d:RAND_add", &view, &entropy))
return NULL;
+ buf = (const char *)view.buf;
+ len = view.len;
do {
written = Py_MIN(len, INT_MAX);
RAND_add(buf, (int)written, entropy);
buf += written;
len -= written;
} while (len);
+ PyBuffer_Release(&view);
Py_INCREF(Py_None);
return Py_None;
}
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
index d043bb3..63e93b7 100644
--- a/Modules/mmapmodule.c
+++ b/Modules/mmapmodule.c
@@ -301,16 +301,17 @@ mmap_gfind(mmap_object *self,
{
Py_ssize_t start = self->pos;
Py_ssize_t end = self->size;
- const char *needle;
- Py_ssize_t len;
+ Py_buffer view;
CHECK_VALID(NULL);
- if (!PyArg_ParseTuple(args, reverse ? "y#|nn:rfind" : "y#|nn:find",
- &needle, &len, &start, &end)) {
+ if (!PyArg_ParseTuple(args, reverse ? "y*|nn:rfind" : "y*|nn:find",
+ &view, &start, &end)) {
return NULL;
} else {
const char *p, *start_p, *end_p;
int sign = reverse ? -1 : 1;
+ const char *needle = view.buf;
+ Py_ssize_t len = view.len;
if (start < 0)
start += self->size;
@@ -335,9 +336,11 @@ mmap_gfind(mmap_object *self,
for (i = 0; i < len && needle[i] == p[i]; ++i)
/* nothing */;
if (i == len) {
+ PyBuffer_Release(&view);
return PyLong_FromSsize_t(p - self->data);
}
}
+ PyBuffer_Release(&view);
return PyLong_FromLong(-1);
}
}
@@ -385,22 +388,25 @@ static PyObject *
mmap_write_method(mmap_object *self,
PyObject *args)
{
- Py_ssize_t length;
- char *data;
+ Py_buffer data;
CHECK_VALID(NULL);
- if (!PyArg_ParseTuple(args, "y#:write", &data, &length))
+ if (!PyArg_ParseTuple(args, "y*:write", &data))
return(NULL);
- if (!is_writable(self))
+ if (!is_writable(self)) {
+ PyBuffer_Release(&data);
return NULL;
+ }
- if ((self->pos + length) > self->size) {
+ if ((self->pos + data.len) > self->size) {
PyErr_SetString(PyExc_ValueError, "data out of range");
+ PyBuffer_Release(&data);
return NULL;
}
- memcpy(self->data+self->pos, data, length);
- self->pos = self->pos+length;
+ memcpy(self->data + self->pos, data.buf, data.len);
+ self->pos = self->pos + data.len;
+ PyBuffer_Release(&data);
Py_INCREF(Py_None);
return Py_None;
}
diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c
index 9bc7641..f6ad216 100644
--- a/Modules/ossaudiodev.c
+++ b/Modules/ossaudiodev.c
@@ -426,17 +426,18 @@ oss_read(oss_audio_t *self, PyObject *args)
static PyObject *
oss_write(oss_audio_t *self, PyObject *args)
{
- char *cp;
- int rv, size;
+ Py_buffer data;
+ int rv;
if (!_is_fd_valid(self->fd))
return NULL;
- if (!PyArg_ParseTuple(args, "y#:write", &cp, &size)) {
+ if (!PyArg_ParseTuple(args, "y*:write", &data)) {
return NULL;
}
- rv = _Py_write(self->fd, cp, size);
+ rv = _Py_write(self->fd, data.buf, data.len);
+ PyBuffer_Release(&data);
if (rv == -1)
return NULL;
@@ -447,8 +448,10 @@ oss_write(oss_audio_t *self, PyObject *args)
static PyObject *
oss_writeall(oss_audio_t *self, PyObject *args)
{
- char *cp;
- int rv, size;
+ Py_buffer data;
+ const char *cp;
+ Py_ssize_t size;
+ int rv;
fd_set write_set_fds;
int select_rv;
@@ -462,17 +465,20 @@ oss_writeall(oss_audio_t *self, PyObject *args)
if (!_is_fd_valid(self->fd))
return NULL;
- if (!PyArg_ParseTuple(args, "y#:write", &cp, &size))
+ if (!PyArg_ParseTuple(args, "y*:writeall", &data))
return NULL;
if (!_PyIsSelectable_fd(self->fd)) {
PyErr_SetString(PyExc_ValueError,
"file descriptor out of range for select");
+ PyBuffer_Release(&data);
return NULL;
}
/* use select to wait for audio device to be available */
FD_ZERO(&write_set_fds);
FD_SET(self->fd, &write_set_fds);
+ cp = (const char *)data.buf;
+ size = data.len;
while (size > 0) {
Py_BEGIN_ALLOW_THREADS
@@ -480,10 +486,12 @@ oss_writeall(oss_audio_t *self, PyObject *args)
Py_END_ALLOW_THREADS
assert(select_rv != 0); /* no timeout, can't expire */
- if (select_rv == -1)
+ if (select_rv == -1) {
+ PyBuffer_Release(&data);
return PyErr_SetFromErrno(PyExc_IOError);
+ }
- rv = _Py_write(self->fd, cp, size);
+ rv = _Py_write(self->fd, , cp, Py_MIN(size, INT_MAX));
if (rv == -1) {
/* buffer is full, try again */
if (errno == EAGAIN) {
@@ -491,6 +499,7 @@ oss_writeall(oss_audio_t *self, PyObject *args)
continue;
}
/* it's a real error */
+ PyBuffer_Release(&data);
return NULL;
}
@@ -499,6 +508,7 @@ oss_writeall(oss_audio_t *self, PyObject *args)
size -= rv;
cp += rv;
}
+ PyBuffer_Release(&data);
Py_INCREF(Py_None);
return Py_None;
}
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 480ee5a..147b48e 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -1299,8 +1299,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
case AF_UNIX:
{
struct sockaddr_un* addr;
- char *path;
- int len;
+ Py_buffer path;
int retval = 0;
/* PEP 383. Not using PyUnicode_FSConverter since we need to
@@ -1311,15 +1310,17 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
}
else
Py_INCREF(args);
- if (!PyArg_Parse(args, "y#", &path, &len))
- goto unix_out;
- assert(len >= 0);
+ if (!PyArg_Parse(args, "y*", &path)) {
+ Py_DECREF(args);
+ return retval;
+ }
+ assert(path.len >= 0);
addr = (struct sockaddr_un*)addr_ret;
#ifdef linux
- if (len > 0 && path[0] == 0) {
+ if (path.len > 0 && *(const char *)path.buf == 0) {
/* Linux abstract namespace extension */
- if ((size_t)len > sizeof addr->sun_path) {
+ if ((size_t)path.len > sizeof addr->sun_path) {
PyErr_SetString(PyExc_OSError,
"AF_UNIX path too long");
goto unix_out;
@@ -1329,18 +1330,19 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#endif /* linux */
{
/* regular NULL-terminated string */
- if ((size_t)len >= sizeof addr->sun_path) {
+ if ((size_t)path.len >= sizeof addr->sun_path) {
PyErr_SetString(PyExc_OSError,
"AF_UNIX path too long");
goto unix_out;
}
- addr->sun_path[len] = 0;
+ addr->sun_path[path.len] = 0;
}
addr->sun_family = s->sock_family;
- memcpy(addr->sun_path, path, len);
- *len_ret = len + offsetof(struct sockaddr_un, sun_path);
+ memcpy(addr->sun_path, path.buf, path.len);
+ *len_ret = path.len + offsetof(struct sockaddr_un, sun_path);
retval = 1;
unix_out:
+ PyBuffer_Release(&path);
Py_DECREF(args);
return retval;
}
@@ -1562,8 +1564,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
int protoNumber;
int hatype = 0;
int pkttype = 0;
- char *haddr = NULL;
- unsigned int halen = 0;
+ Py_buffer haddr = {NULL, NULL};
if (!PyTuple_Check(args)) {
PyErr_Format(
@@ -1573,25 +1574,28 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
Py_TYPE(args)->tp_name);
return 0;
}
- if (!PyArg_ParseTuple(args, "si|iiy#", &interfaceName,
+ if (!PyArg_ParseTuple(args, "si|iiy*", &interfaceName,
&protoNumber, &pkttype, &hatype,
- &haddr, &halen))
+ &haddr))
return 0;
strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name));
ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0';
if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) {
s->errorhandler();
+ PyBuffer_Release(&haddr);
return 0;
}
- if (halen > 8) {
- PyErr_SetString(PyExc_ValueError,
- "Hardware address must be 8 bytes or less");
- return 0;
+ if (haddr.buf && haddr.len > 8) {
+ PyErr_SetString(PyExc_ValueError,
+ "Hardware address must be 8 bytes or less");
+ PyBuffer_Release(&haddr);
+ return 0;
}
if (protoNumber < 0 || protoNumber > 0xffff) {
PyErr_SetString(
PyExc_OverflowError,
"getsockaddrarg: protoNumber must be 0-65535.");
+ PyBuffer_Release(&haddr);
return 0;
}
addr = (struct sockaddr_ll*)addr_ret;
@@ -1600,11 +1604,14 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
addr->sll_ifindex = ifr.ifr_ifindex;
addr->sll_pkttype = pkttype;
addr->sll_hatype = hatype;
- if (halen != 0) {
- memcpy(&addr->sll_addr, haddr, halen);
+ if (haddr.buf) {
+ memcpy(&addr->sll_addr, haddr.buf, haddr.len);
+ addr->sll_halen = haddr.len;
}
- addr->sll_halen = halen;
+ else
+ addr->sll_halen = 0;
*len_ret = sizeof *addr;
+ PyBuffer_Release(&haddr);
return 1;
}
#endif
@@ -2230,22 +2237,21 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args)
int level;
int optname;
int res;
- char *buf;
- int buflen;
+ Py_buffer optval;
int flag;
if (PyArg_ParseTuple(args, "iii:setsockopt",
&level, &optname, &flag)) {
- buf = (char *) &flag;
- buflen = sizeof flag;
+ res = setsockopt(s->sock_fd, level, optname, &flag, sizeof flag);
}
else {
PyErr_Clear();
- if (!PyArg_ParseTuple(args, "iiy#:setsockopt",
- &level, &optname, &buf, &buflen))
+ if (!PyArg_ParseTuple(args, "iiy*:setsockopt",
+ &level, &optname, &optval))
return NULL;
+ res = setsockopt(s->sock_fd, level, optname, optval.buf, optval.len);
+ PyBuffer_Release(&optval);
}
- res = setsockopt(s->sock_fd, level, optname, (void *)buf, buflen);
if (res < 0)
return s->errorhandler();
Py_INCREF(Py_None);
@@ -5037,21 +5043,22 @@ Convert an IP address from 32-bit packed binary format to string format");
static PyObject*
socket_inet_ntoa(PyObject *self, PyObject *args)
{
- char *packed_str;
- int addr_len;
+ Py_buffer packed_ip;
struct in_addr packed_addr;
- if (!PyArg_ParseTuple(args, "y#:inet_ntoa", &packed_str, &addr_len)) {
+ if (!PyArg_ParseTuple(args, "y*:inet_ntoa", &packed_ip)) {
return NULL;
}
- if (addr_len != sizeof(packed_addr)) {
+ if (packed_ip.len != sizeof(packed_addr)) {
PyErr_SetString(PyExc_OSError,
"packed IP wrong length for inet_ntoa");
+ PyBuffer_Release(&packed_ip);
return NULL;
}
- memcpy(&packed_addr, packed_str, addr_len);
+ memcpy(&packed_addr, packed_ip.buf, packed_ip.len);
+ PyBuffer_Release(&packed_ip);
return PyUnicode_FromString(inet_ntoa(packed_addr));
}
@@ -5162,8 +5169,7 @@ static PyObject *
socket_inet_ntop(PyObject *self, PyObject *args)
{
int af;
- char* packed;
- int len;
+ Py_buffer packed_ip;
const char* retval;
#ifdef ENABLE_IPV6
char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1];
@@ -5174,31 +5180,35 @@ socket_inet_ntop(PyObject *self, PyObject *args)
/* Guarantee NUL-termination for PyUnicode_FromString() below */
memset((void *) &ip[0], '\0', sizeof(ip));
- if (!PyArg_ParseTuple(args, "iy#:inet_ntop", &af, &packed, &len)) {
+ if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) {
return NULL;
}
if (af == AF_INET) {
- if (len != sizeof(struct in_addr)) {
+ if (packed_ip.len != sizeof(struct in_addr)) {
PyErr_SetString(PyExc_ValueError,
"invalid length of packed IP address string");
+ PyBuffer_Release(&packed_ip);
return NULL;
}
#ifdef ENABLE_IPV6
} else if (af == AF_INET6) {
- if (len != sizeof(struct in6_addr)) {
+ if (packed_ip.len != sizeof(struct in6_addr)) {
PyErr_SetString(PyExc_ValueError,
"invalid length of packed IP address string");
+ PyBuffer_Release(&packed_ip);
return NULL;
}
#endif
} else {
PyErr_Format(PyExc_ValueError,
"unknown address family %d", af);
+ PyBuffer_Release(&packed_ip);
return NULL;
}
- retval = inet_ntop(af, packed, ip, sizeof(ip));
+ retval = inet_ntop(af, packed_ip.buf, ip, sizeof(ip));
+ PyBuffer_Release(&packed_ip);
if (!retval) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -5217,8 +5227,7 @@ static PyObject *
socket_inet_ntop(PyObject *self, PyObject *args)
{
int af;
- char* packed;
- int len;
+ Py_buffer packed_ip;
struct sockaddr_in6 addr;
DWORD addrlen, ret, retlen;
#ifdef ENABLE_IPV6
@@ -5230,38 +5239,42 @@ socket_inet_ntop(PyObject *self, PyObject *args)
/* Guarantee NUL-termination for PyUnicode_FromString() below */
memset((void *) &ip[0], '\0', sizeof(ip));
- if (!PyArg_ParseTuple(args, "iy#:inet_ntop", &af, &packed, &len)) {
+ if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) {
return NULL;
}
if (af == AF_INET) {
struct sockaddr_in * addr4 = (struct sockaddr_in *)&addr;
- if (len != sizeof(struct in_addr)) {
+ if (packed_ip.len != sizeof(struct in_addr)) {
PyErr_SetString(PyExc_ValueError,
"invalid length of packed IP address string");
+ PyBuffer_Release(&packed_ip);
return NULL;
}
memset(addr4, 0, sizeof(struct sockaddr_in));
addr4->sin_family = AF_INET;
- memcpy(&(addr4->sin_addr), packed, sizeof(addr4->sin_addr));
+ memcpy(&(addr4->sin_addr), packed_ip.buf, sizeof(addr4->sin_addr));
addrlen = sizeof(struct sockaddr_in);
} else if (af == AF_INET6) {
- if (len != sizeof(struct in6_addr)) {
+ if (packed_ip.len != sizeof(struct in6_addr)) {
PyErr_SetString(PyExc_ValueError,
"invalid length of packed IP address string");
+ PyBuffer_Release(&packed_ip);
return NULL;
}
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
- memcpy(&(addr.sin6_addr), packed, sizeof(addr.sin6_addr));
+ memcpy(&(addr.sin6_addr), packed_ip.buf, sizeof(addr.sin6_addr));
addrlen = sizeof(addr);
} else {
PyErr_Format(PyExc_ValueError,
"unknown address family %d", af);
+ PyBuffer_Release(&packed_ip);
return NULL;
}
+ PyBuffer_Release(&packed_ip);
retlen = sizeof(ip);
ret = WSAAddressToStringA((struct sockaddr*)&addr, addrlen, NULL,