diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-03-20 07:00:36 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-03-20 07:00:36 (GMT) |
commit | 8490f5acfee7269ac0eb41257a3a214dfb31a655 (patch) | |
tree | 7cd039c0f6418571d9f8cc89741c3ec4938f2ebc /Modules | |
parent | 0eac13052c498e21cbb60ed321e5a9ea10d07b35 (diff) | |
download | cpython-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.c | 15 | ||||
-rw-r--r-- | Modules/_ssl.c | 8 | ||||
-rw-r--r-- | Modules/mmapmodule.c | 28 | ||||
-rw-r--r-- | Modules/ossaudiodev.c | 28 | ||||
-rw-r--r-- | Modules/socketmodule.c | 107 |
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, |