Index: Python/getargs.c =================================================================== --- Python/getargs.c (révision 81974) +++ Python/getargs.c (copie de travail) @@ -162,11 +162,20 @@ } static int -addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr) +addcleanup(void *ptr, PyObject **freelist, int is_buffer) { PyObject *cobj; const char *name; + PyCapsule_Destructor destr; + if (is_buffer) { + destr = cleanup_buffer; + name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER; + } else { + destr = cleanup_ptr; + name = GETARGS_CAPSULE_NAME_CLEANUP_PTR; + } + if (!*freelist) { *freelist = PyList_New(0); if (!*freelist) { @@ -175,13 +184,6 @@ } } - if (destr == cleanup_ptr) { - name = GETARGS_CAPSULE_NAME_CLEANUP_PTR; - } else if (destr == cleanup_buffer) { - name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER; - } else { - return -1; - } cobj = PyCapsule_New(ptr, name, destr); if (!cobj) { destr(ptr); @@ -615,6 +617,7 @@ else q=va_arg(*p_va, int*); #define STORE_SIZE(s) if (flags & FLAG_SIZE_T) *q2=s; else *q=s; #define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2:*q) +#define RETURN_ERR_OCCURRED return msgbuf const char *format = *p_format; char c = *format++; @@ -626,19 +629,19 @@ char *p = va_arg(*p_va, char *); long ival; if (float_argument_error(arg)) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; ival = PyLong_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else if (ival < 0) { PyErr_SetString(PyExc_OverflowError, "unsigned byte integer is less than minimum"); - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } else if (ival > UCHAR_MAX) { PyErr_SetString(PyExc_OverflowError, "unsigned byte integer is greater than maximum"); - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } else *p = (unsigned char) ival; @@ -650,10 +653,10 @@ char *p = va_arg(*p_va, char *); long ival; if (float_argument_error(arg)) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; ival = PyLong_AsUnsignedLongMask(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else *p = (unsigned char) ival; break; @@ -663,19 +666,19 @@ short *p = va_arg(*p_va, short *); long ival; if (float_argument_error(arg)) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; ival = PyLong_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else if (ival < SHRT_MIN) { PyErr_SetString(PyExc_OverflowError, "signed short integer is less than minimum"); - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } else if (ival > SHRT_MAX) { PyErr_SetString(PyExc_OverflowError, "signed short integer is greater than maximum"); - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } else *p = (short) ival; @@ -687,10 +690,10 @@ unsigned short *p = va_arg(*p_va, unsigned short *); long ival; if (float_argument_error(arg)) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; ival = PyLong_AsUnsignedLongMask(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else *p = (unsigned short) ival; break; @@ -700,19 +703,19 @@ int *p = va_arg(*p_va, int *); long ival; if (float_argument_error(arg)) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; ival = PyLong_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else if (ival > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "signed integer is greater than maximum"); - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } else if (ival < INT_MIN) { PyErr_SetString(PyExc_OverflowError, "signed integer is less than minimum"); - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } else *p = ival; @@ -724,10 +727,10 @@ unsigned int *p = va_arg(*p_va, unsigned int *); unsigned int ival; if (float_argument_error(arg)) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; ival = (unsigned int)PyLong_AsUnsignedLongMask(arg); if (ival == (unsigned int)-1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else *p = ival; break; @@ -739,14 +742,14 @@ Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *); Py_ssize_t ival = -1; if (float_argument_error(arg)) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; iobj = PyNumber_Index(arg); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); } if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; *p = ival; break; } @@ -754,10 +757,10 @@ long *p = va_arg(*p_va, long *); long ival; if (float_argument_error(arg)) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; ival = PyLong_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else *p = ival; break; @@ -779,10 +782,10 @@ PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * ); PY_LONG_LONG ival; if (float_argument_error(arg)) - return converterr("long", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; ival = PyLong_AsLongLong(arg); if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred()) - return converterr("long", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else *p = ival; break; @@ -804,7 +807,7 @@ float *p = va_arg(*p_va, float *); double dval = PyFloat_AsDouble(arg); if (PyErr_Occurred()) - return converterr("float", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else *p = (float) dval; break; @@ -814,7 +817,7 @@ double *p = va_arg(*p_va, double *); double dval = PyFloat_AsDouble(arg); if (PyErr_Occurred()) - return converterr("float", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else *p = dval; break; @@ -825,7 +828,7 @@ Py_complex cval; cval = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) - return converterr("complex", arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; else *p = cval; break; @@ -860,8 +863,7 @@ if (PyUnicode_Check(arg)) { uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) - return converterr(CONV_UNICODE, - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; PyBuffer_FillInfo(p, arg, PyBytes_AS_STRING(uarg), PyBytes_GET_SIZE(uarg), 1, 0); @@ -871,11 +873,8 @@ if (getbuffer(arg, p, &buf) < 0) return converterr(buf, arg, msgbuf, bufsize); } - if (addcleanup(p, freelist, cleanup_buffer)) { - return converterr( - "(cleanup problem)", - arg, msgbuf, bufsize); - } + if (addcleanup(p, freelist, 1)) + RETURN_ERR_OCCURRED; format++; } else if (*format == '#') { void **p = (void **)va_arg(*p_va, char **); @@ -884,8 +883,7 @@ if (PyUnicode_Check(arg)) { uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) - return converterr(CONV_UNICODE, - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; *p = PyBytes_AS_STRING(uarg); STORE_SIZE(PyBytes_GET_SIZE(uarg)); } @@ -904,8 +902,7 @@ if (PyUnicode_Check(arg)) { uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) - return converterr(CONV_UNICODE, - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; *p = PyBytes_AS_STRING(uarg); } else @@ -925,11 +922,8 @@ if (getbuffer(arg, (Py_buffer*)p, &buf) < 0) return converterr(buf, arg, msgbuf, bufsize); format++; - if (addcleanup(p, freelist, cleanup_buffer)) { - return converterr( - "(cleanup problem)", - arg, msgbuf, bufsize); - } + if (addcleanup(p, freelist, 1)) + RETURN_ERR_OCCURRED; break; } count = convertbuffer(arg, p, &buf); @@ -957,8 +951,7 @@ else if (PyUnicode_Check(arg)) { uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) - return converterr(CONV_UNICODE, - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; PyBuffer_FillInfo(p, arg, PyBytes_AS_STRING(uarg), PyBytes_GET_SIZE(uarg), 1, 0); @@ -968,11 +961,8 @@ if (getbuffer(arg, p, &buf) < 0) return converterr(buf, arg, msgbuf, bufsize); } - if (addcleanup(p, freelist, cleanup_buffer)) { - return converterr( - "(cleanup problem)", - arg, msgbuf, bufsize); - } + if (addcleanup(p, freelist, 1)) + RETURN_ERR_OCCURRED; format++; } else if (*format == '#') { /* any buffer-like object */ void **p = (void **)va_arg(*p_va, char **); @@ -985,8 +975,7 @@ else if (PyUnicode_Check(arg)) { uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) - return converterr(CONV_UNICODE, - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; *p = PyBytes_AS_STRING(uarg); STORE_SIZE(PyBytes_GET_SIZE(uarg)); } @@ -1013,8 +1002,7 @@ else if (PyUnicode_Check(arg)) { uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) - return converterr(CONV_UNICODE, - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; *p = PyBytes_AS_STRING(uarg); } else @@ -1099,8 +1087,7 @@ s = arg; Py_INCREF(s); if (PyObject_AsCharBuffer(s, &ptr, &size) < 0) - return converterr("(AsCharBuffer failed)", - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } else { PyObject *u; @@ -1108,24 +1095,13 @@ /* Convert object to Unicode */ u = PyUnicode_FromObject(arg); if (u == NULL) - return converterr( - "string or unicode or text buffer", - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; /* Encode object; use default error handling */ - s = PyUnicode_AsEncodedString(u, - encoding, - NULL); + s = PyUnicode_AsEncodedString(u, encoding, NULL); Py_DECREF(u); if (s == NULL) - return converterr("(encoding failed)", - arg, msgbuf, bufsize); - if (!PyBytes_Check(s)) { - Py_DECREF(s); - return converterr( - "(encoder failed to return bytes)", - arg, msgbuf, bufsize); - } + RETURN_ERR_OCCURRED; size = PyBytes_GET_SIZE(s); ptr = PyBytes_AS_STRING(s); if (ptr == NULL) @@ -1169,15 +1145,11 @@ if (*buffer == NULL) { Py_DECREF(s); PyErr_NoMemory(); - return converterr( - "(memory error)", - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } - if (addcleanup(*buffer, freelist, cleanup_ptr)) { + if (addcleanup(*buffer, freelist, 0)) { Py_DECREF(s); - return converterr( - "(cleanup problem)", - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } } else { if (size + 1 > BUFFER_LEN) { @@ -1213,13 +1185,11 @@ if (*buffer == NULL) { Py_DECREF(s); PyErr_NoMemory(); - return converterr("(memory error)", - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } - if (addcleanup(*buffer, freelist, cleanup_ptr)) { + if (addcleanup(*buffer, freelist, 0)) { Py_DECREF(s); - return converterr("(cleanup problem)", - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } memcpy(*buffer, ptr, size+1); } @@ -1292,12 +1262,10 @@ int res; format++; if (! (res = (*convert)(arg, addr))) - return converterr("(unspecified)", - arg, msgbuf, bufsize); + return converterr("(converter error)", arg, msgbuf, bufsize); if (res == Py_CLEANUP_SUPPORTED && addcleanup_convert(addr, freelist, convert) == -1) - return converterr("(cleanup problem)", - arg, msgbuf, bufsize); + RETURN_ERR_OCCURRED; } else { p = va_arg(*p_va, PyObject **); @@ -1328,11 +1296,8 @@ PyErr_Clear(); return converterr("read-write buffer", arg, msgbuf, bufsize); } - if (addcleanup(p, freelist, cleanup_buffer)) { - return converterr( - "(cleanup problem)", - arg, msgbuf, bufsize); - } + if (addcleanup(p, freelist, 1)) + RETURN_ERR_OCCURRED; if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) return converterr("contiguous buffer", arg, msgbuf, bufsize); break;