Handle AF_UNIX addresses according to PEP 383. socket.connect(), etc., previously accepted read-only buffers, so in order to accept bytearray pathnames, they now accept any PyBUF_SIMPLE in addition to surrogateescape-encoded strings. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -979,7 +979,9 @@ makesockaddr(int sockfd, struct sockaddr len++) ; } - return PyUnicode_FromStringAndSize(a->sun_path, len); + return PyUnicode_Decode(a->sun_path, len, + Py_FileSystemDefaultEncoding, + "surrogateescape"); } #endif /* AF_UNIX */ @@ -1149,29 +1151,48 @@ getsockaddrarg(PySocketSockObject *s, Py case AF_UNIX: { struct sockaddr_un* addr; - char *path; - int len; - if (!PyArg_Parse(args, "s#", &path, &len)) - return 0; + Py_buffer view; + int retval = 0; + + /* PEP 383. Not using PyUnicode_FSConverter since we + need to allow embedded nulls on Linux, and previous + versions accepted read-only buffers here. */ + if (PyUnicode_Check(args)) { + args = PyUnicode_AsEncodedString( + args, Py_FileSystemDefaultEncoding, + "surrogateescape"); + if (args == NULL) + return 0; + } + else + Py_INCREF(args); + if (!PyArg_Parse(args, "y*", &view)) + goto unix_out; addr = (struct sockaddr_un*)addr_ret; #ifdef linux - if (len > sizeof(addr->sun_path)) { + if (view.len > sizeof(addr->sun_path)) { #else - if (len >= sizeof(addr->sun_path)) { + if (view.len >= sizeof(addr->sun_path)) { #endif PyErr_SetString(socket_error, "AF_UNIX path too long"); - return 0; + goto unix_releasebuf; } addr->sun_family = s->sock_family; - memcpy(addr->sun_path, path, len); - memset(addr->sun_path + len, 0, sizeof(addr->sun_path) - len); + memcpy(addr->sun_path, view.buf, view.len); + memset(addr->sun_path + view.len, 0, + sizeof(addr->sun_path) - view.len); #if defined(PYOS_OS2) *len_ret = sizeof(*addr); #else - *len_ret = len + offsetof(struct sockaddr_un, sun_path); -#endif - return 1; + *len_ret = view.len + offsetof(struct sockaddr_un, sun_path); +#endif + retval = 1; + unix_releasebuf: + PyBuffer_Release(&view); + unix_out: + Py_DECREF(args); + return retval; } #endif /* AF_UNIX */