diff options
Diffstat (limited to 'Modules')
44 files changed, 930 insertions, 295 deletions
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c index ad45936..79f06dc 100644 --- a/Modules/_bsddb.c +++ b/Modules/_bsddb.c @@ -98,7 +98,7 @@ #error "eek! DBVER can't handle minor versions > 9" #endif -#define PY_BSDDB_VERSION "4.4.5" +#define PY_BSDDB_VERSION "4.4.6" static char *rcs_id = "$Id$"; @@ -1779,9 +1779,7 @@ DB_get_type(DBObject* self, PyObject* args) return NULL; CHECK_DB_NOT_CLOSED(self); - MYDB_BEGIN_ALLOW_THREADS; type = _DB_get_type(self); - MYDB_END_ALLOW_THREADS; if (type == -1) return NULL; return PyInt_FromLong(type); @@ -2430,7 +2428,7 @@ DB_stat(DBObject* self, PyObject* args, PyObject* kwargs) #if (DBVER >= 43) PyObject* txnobj = NULL; DB_TXN *txn = NULL; - static char* kwnames[] = { "txn", "flags", NULL }; + static char* kwnames[] = { "flags", "txn", NULL }; #else static char* kwnames[] = { "flags", NULL }; #endif diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 7948516..dc7feeb 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2589,16 +2589,22 @@ static PPROC FindAddress(void *handle, char *name, PyObject *type) PPROC address; char *mangled_name; int i; - StgDictObject *dict = PyType_stgdict((PyObject *)type); + StgDictObject *dict; address = (PPROC)GetProcAddress(handle, name); +#ifdef _WIN64 + /* win64 has no stdcall calling conv, so it should + also not have the name mangling of it. + */ + return address; +#else if (address) return address; - if (((size_t)name & ~0xFFFF) == 0) { return NULL; } + dict = PyType_stgdict((PyObject *)type); /* It should not happen that dict is NULL, but better be safe */ if (dict==NULL || dict->flags & FUNCFLAG_CDECL) return address; @@ -2617,6 +2623,7 @@ static PPROC FindAddress(void *handle, char *name, PyObject *type) return address; } return NULL; +#endif } #endif @@ -4588,11 +4595,11 @@ cast(void *ptr, PyObject *src, PyObject *ctype) if (obj->b_objects == NULL) goto failed; } + Py_XINCREF(obj->b_objects); result->b_objects = obj->b_objects; - if (result->b_objects) { + if (result->b_objects && PyDict_Check(result->b_objects)) { PyObject *index; int rc; - Py_INCREF(obj->b_objects); index = PyLong_FromVoidPtr((void *)src); if (index == NULL) goto failed; diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 7331d01..d13fec4 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -25,6 +25,16 @@ /* some functions handy for testing */ +EXPORT(int)myprintf(char *fmt, ...) +{ + int result; + va_list argptr; + va_start(argptr, fmt); + result = vprintf(fmt, argptr); + va_end(argptr); + return result; +} + EXPORT(char *)my_strtok(char *token, const char *delim) { return strtok(token, delim); diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index d5ab43b..89b44aa 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -294,14 +294,17 @@ ffi_info *AllocFunctionCallback(PyObject *callable, p->restype = &ffi_type_void; } else { StgDictObject *dict = PyType_stgdict(restype); - if (dict == NULL) - goto error; + if (dict == NULL || dict->setfunc == NULL) { + PyErr_SetString(PyExc_TypeError, + "invalid result type for callback function"); + goto error; + } p->setfunc = dict->setfunc; p->restype = &dict->ffi_type_pointer; } cc = FFI_DEFAULT_ABI; -#if defined(MS_WIN32) && !defined(_WIN32_WCE) +#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64) if (is_cdecl == 0) cc = FFI_STDCALL; #endif diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index e0765e9..18e1991 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -638,7 +638,7 @@ static int _call_function_pointer(int flags, } cc = FFI_DEFAULT_ABI; -#if defined(MS_WIN32) && !defined(_WIN32_WCE) +#if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE) if ((flags & FUNCFLAG_CDECL) == 0) cc = FFI_STDCALL; #endif @@ -683,6 +683,14 @@ static int _call_function_pointer(int flags, return -1; } #endif +#ifdef MS_WIN64 + if (delta != 0) { + PyErr_Format(PyExc_RuntimeError, + "ffi_call failed with code %d", + delta); + return -1; + } +#else if (delta < 0) { if (flags & FUNCFLAG_CDECL) PyErr_Format(PyExc_ValueError, @@ -704,6 +712,7 @@ static int _call_function_pointer(int flags, return -1; } #endif +#endif if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred()) return -1; return 0; @@ -979,7 +988,11 @@ PyObject *_CallProc(PPROC pProc, } for (i = 0; i < argcount; ++i) { atypes[i] = args[i].ffi_type; - if (atypes[i]->type == FFI_TYPE_STRUCT) + if (atypes[i]->type == FFI_TYPE_STRUCT +#ifdef _WIN64 + && atypes[i]->size <= sizeof(void *) +#endif + ) avalues[i] = (void *)args[i].value.p; else avalues[i] = (void *)&args[i].value; @@ -1099,7 +1112,11 @@ static PyObject *load_library(PyObject *self, PyObject *args) hMod = LoadLibrary(name); if (!hMod) return PyErr_SetFromWindowsErr(GetLastError()); +#ifdef _WIN64 + return PyLong_FromVoidPtr(hMod); +#else return Py_BuildValue("i", hMod); +#endif } static char free_library_doc[] = @@ -1230,11 +1247,11 @@ static PyObject *py_dl_open(PyObject *self, PyObject *args) static PyObject *py_dl_close(PyObject *self, PyObject *args) { - void * handle; + int handle; if (!PyArg_ParseTuple(args, "i:dlclose", &handle)) return NULL; - if (dlclose(handle)) { + if (dlclose((void*)handle)) { PyErr_SetString(PyExc_OSError, ctypes_dlerror()); return NULL; @@ -1246,12 +1263,12 @@ static PyObject *py_dl_close(PyObject *self, PyObject *args) static PyObject *py_dl_sym(PyObject *self, PyObject *args) { char *name; - void *handle; + int handle; void *ptr; if (!PyArg_ParseTuple(args, "is:dlsym", &handle, &name)) return NULL; - ptr = ctypes_dlsym(handle, name); + ptr = ctypes_dlsym((void*)handle, name); if (!ptr) { PyErr_SetString(PyExc_OSError, ctypes_dlerror()); @@ -1269,7 +1286,7 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args) static PyObject * call_function(PyObject *self, PyObject *args) { - PPROC func; + int func; PyObject *arguments; PyObject *result; @@ -1279,7 +1296,7 @@ call_function(PyObject *self, PyObject *args) &PyTuple_Type, &arguments)) return NULL; - result = _CallProc(func, + result = _CallProc((PPROC)func, arguments, #ifdef MS_WIN32 NULL, @@ -1300,7 +1317,7 @@ call_function(PyObject *self, PyObject *args) static PyObject * call_cdeclfunction(PyObject *self, PyObject *args) { - PPROC func; + int func; PyObject *arguments; PyObject *result; @@ -1310,7 +1327,7 @@ call_cdeclfunction(PyObject *self, PyObject *args) &PyTuple_Type, &arguments)) return NULL; - result = _CallProc(func, + result = _CallProc((PPROC)func, arguments, #ifdef MS_WIN32 NULL, @@ -1493,7 +1510,7 @@ resize(PyObject *self, PyObject *args) #else "On:resize", #endif - (PyObject *)&obj, &size)) + &obj, &size)) return NULL; dict = PyObject_stgdict((PyObject *)obj); diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index c16a387..ad83195 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1315,7 +1315,11 @@ z_set(void *ptr, PyObject *value, unsigned size) *(char **)ptr = PyString_AS_STRING(str); return str; } else if (PyInt_Check(value) || PyLong_Check(value)) { +#if SIZEOF_VOID_P == SIZEOF_LONG_LONG + *(char **)ptr = (char *)PyInt_AsUnsignedLongLongMask(value); +#else *(char **)ptr = (char *)PyInt_AsUnsignedLongMask(value); +#endif _RET(value); } PyErr_Format(PyExc_TypeError, @@ -1360,7 +1364,11 @@ Z_set(void *ptr, PyObject *value, unsigned size) if (!value) return NULL; } else if (PyInt_Check(value) || PyLong_Check(value)) { +#if SIZEOF_VOID_P == SIZEOF_LONG_LONG + *(wchar_t **)ptr = (wchar_t *)PyInt_AsUnsignedLongLongMask(value); +#else *(wchar_t **)ptr = (wchar_t *)PyInt_AsUnsignedLongMask(value); +#endif Py_INCREF(Py_None); return Py_None; } else if (!PyUnicode_Check(value)) { diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c b/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c index 1595b00..55af70c 100644 --- a/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c +++ b/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c @@ -1,4 +1,4 @@ -#ifdef __ppc__ +#if !(defined(__APPLE__) && !defined(__ppc__)) /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 1998 Geoffrey Keating diff --git a/Modules/_ctypes/libffi/src/x86/sysv.S b/Modules/_ctypes/libffi/src/x86/sysv.S index 46759f4..9542fba 100644 --- a/Modules/_ctypes/libffi/src/x86/sysv.S +++ b/Modules/_ctypes/libffi/src/x86/sysv.S @@ -376,3 +376,7 @@ ffi_closure_raw_SYSV: #endif #endif /* ifndef __x86_64__ */ + +#ifdef __ELF__ +.section .note.GNU-stack,"",%progbits +#endif diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c index 9af6b71..3f23a05 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.c +++ b/Modules/_ctypes/libffi_msvc/ffi.c @@ -34,6 +34,8 @@ /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ +extern void Py_FatalError(char *msg); + /*@-exportheader@*/ void ffi_prep_args(char *stack, extended_cif *ecif) /*@=exportheader@*/ @@ -44,11 +46,10 @@ void ffi_prep_args(char *stack, extended_cif *ecif) register ffi_type **p_arg; argp = stack; - if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) { *(void **) argp = ecif->rvalue; - argp += 4; + argp += sizeof(void *); } p_argv = ecif->avalue; @@ -60,8 +61,8 @@ void ffi_prep_args(char *stack, extended_cif *ecif) size_t z; /* Align if necessary */ - if ((sizeof(int) - 1) & (unsigned) argp) - argp = (char *) ALIGN(argp, sizeof(int)); + if ((sizeof(void *) - 1) & (size_t) argp) + argp = (char *) ALIGN(argp, sizeof(void *)); z = (*p_arg)->size; if (z < sizeof(int)) @@ -108,7 +109,11 @@ void ffi_prep_args(char *stack, extended_cif *ecif) p_argv++; argp += z; } - + + if (argp - stack > ecif->cif->bytes) + { + Py_FatalError("FFI BUG: not enough stack space for arguments"); + } return; } @@ -128,6 +133,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) break; case FFI_TYPE_UINT64: +#ifdef _WIN64 + case FFI_TYPE_POINTER: +#endif cif->flags = FFI_TYPE_SINT64; break; @@ -139,6 +147,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) return FFI_OK; } +#ifdef _WIN32 /*@-declundef@*/ /*@-exportheader@*/ extern int @@ -160,6 +169,16 @@ ffi_call_STDCALL(void (*)(char *, extended_cif *), void (*fn)()); /*@=declundef@*/ /*@=exportheader@*/ +#endif + +#ifdef _WIN64 +extern int +ffi_call_AMD64(void (*)(char *, extended_cif *), + /*@out@*/ extended_cif *, + unsigned, unsigned, + /*@out@*/ unsigned *, + void (*fn)()); +#endif int ffi_call(/*@dependent@*/ ffi_cif *cif, @@ -188,6 +207,7 @@ ffi_call(/*@dependent@*/ ffi_cif *cif, switch (cif->abi) { +#if !defined(_WIN64) case FFI_SYSV: /*@-usedef@*/ return ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, @@ -201,6 +221,14 @@ ffi_call(/*@dependent@*/ ffi_cif *cif, cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; +#else + case FFI_SYSV: + /*@-usedef@*/ + return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + /*@=usedef@*/ + break; +#endif default: FFI_ASSERT(0); @@ -213,10 +241,14 @@ ffi_call(/*@dependent@*/ ffi_cif *cif, /** private members **/ static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, - void** args, ffi_cif* cif); + void** args, ffi_cif* cif); /* This function is jumped to by the trampoline */ +#ifdef _WIN64 +void * +#else static void __fastcall +#endif ffi_closure_SYSV (ffi_closure *closure, int *argp) { // this is our return value storage @@ -244,6 +276,7 @@ ffi_closure_SYSV (ffi_closure *closure, int *argp) rtype = cif->flags; +#if defined(_WIN32) && !defined(_WIN64) #ifdef _MSC_VER /* now, do a generic return based on the value of rtype */ if (rtype == FFI_TYPE_INT) @@ -303,6 +336,15 @@ ffi_closure_SYSV (ffi_closure *closure, int *argp) : "eax", "edx"); } #endif +#endif + +#ifdef _WIN64 + /* The result is returned in rax. This does the right thing for + result types except for floats; we have to 'mov xmm0, rax' in the + caller to correct this. + */ + return *(void **)resp; +#endif } /*@-exportheader@*/ @@ -330,8 +372,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, size_t z; /* Align if necessary */ - if ((sizeof(int) - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, sizeof(int)); + if ((sizeof(char *) - 1) & (size_t) argp) { + argp = (char *) ALIGN(argp, sizeof(char*)); } z = (*p_arg)->size; @@ -347,24 +389,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, return; } -/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ - -#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \ -{ unsigned char *__tramp = (unsigned char*)(TRAMP); \ - unsigned int __fun = (unsigned int)(FUN); \ - unsigned int __ctx = (unsigned int)(CTX); \ - unsigned int __dis = __fun - ((unsigned int) __tramp + 8 + 4); \ - *(unsigned char*) &__tramp[0] = 0xb9; \ - *(unsigned int*) &__tramp[1] = __ctx; /* mov ecx, __ctx */ \ - *(unsigned char*) &__tramp[5] = 0x8b; \ - *(unsigned char*) &__tramp[6] = 0xd4; /* mov edx, esp */ \ - *(unsigned char*) &__tramp[7] = 0xe8; \ - *(unsigned int*) &__tramp[8] = __dis; /* call __fun */ \ - *(unsigned char*) &__tramp[12] = 0xC2; /* ret BYTES */ \ - *(unsigned short*) &__tramp[13] = BYTES; \ - } - /* the cif must already be prep'ed */ +extern void ffi_closure_OUTER(); ffi_status ffi_prep_closure (ffi_closure* closure, @@ -373,19 +399,78 @@ ffi_prep_closure (ffi_closure* closure, void *user_data) { short bytes; + char *tramp; +#ifdef _WIN64 + int mask; +#endif FFI_ASSERT (cif->abi == FFI_SYSV); if (cif->abi == FFI_SYSV) bytes = 0; +#if !defined(_WIN64) else if (cif->abi == FFI_STDCALL) bytes = cif->bytes; +#endif else return FFI_BAD_ABI; - FFI_INIT_TRAMPOLINE (&closure->tramp[0], - &ffi_closure_SYSV, - (void*)closure, - bytes); + tramp = &closure->tramp[0]; + +#define BYTES(text) memcpy(tramp, text, sizeof(text)), tramp += sizeof(text)-1 +#define POINTER(x) *(void**)tramp = (void*)(x), tramp += sizeof(void*) +#define SHORT(x) *(short*)tramp = x, tramp += sizeof(short) +#define INT(x) *(int*)tramp = x, tramp += sizeof(int) + +#ifdef _WIN64 + if (cif->nargs >= 1 && + (cif->arg_types[0]->type == FFI_TYPE_FLOAT + || cif->arg_types[0]->type == FFI_TYPE_DOUBLE)) + mask |= 1; + if (cif->nargs >= 2 && + (cif->arg_types[1]->type == FFI_TYPE_FLOAT + || cif->arg_types[1]->type == FFI_TYPE_DOUBLE)) + mask |= 2; + if (cif->nargs >= 3 && + (cif->arg_types[2]->type == FFI_TYPE_FLOAT + || cif->arg_types[2]->type == FFI_TYPE_DOUBLE)) + mask |= 4; + if (cif->nargs >= 4 && + (cif->arg_types[3]->type == FFI_TYPE_FLOAT + || cif->arg_types[3]->type == FFI_TYPE_DOUBLE)) + mask |= 8; + + /* 41 BB ---- mov r11d,mask */ + BYTES("\x41\xBB"); INT(mask); + + /* 48 B8 -------- mov rax, closure */ + BYTES("\x48\xB8"); POINTER(closure); + + /* 49 BA -------- mov r10, ffi_closure_OUTER */ + BYTES("\x49\xBA"); POINTER(ffi_closure_OUTER); + + /* 41 FF E2 jmp r10 */ + BYTES("\x41\xFF\xE2"); + +#else + + /* mov ecx, closure */ + BYTES("\xb9"); POINTER(closure); + + /* mov edx, esp */ + BYTES("\x8b\xd4"); + + /* call ffi_closure_SYSV */ + BYTES("\xe8"); POINTER((char*)&ffi_closure_SYSV - (tramp + 4)); + + /* ret bytes */ + BYTES("\xc2"); + SHORT(bytes); + +#endif + + if (tramp - &closure->tramp[0] > FFI_TRAMPOLINE_SIZE) + Py_FatalError("FFI_TRAMPOLINE_SIZE too small in " __FILE__); + closure->cif = cif; closure->user_data = user_data; closure->fun = fun; diff --git a/Modules/_ctypes/libffi_msvc/ffi.h b/Modules/_ctypes/libffi_msvc/ffi.h index 203142d..a88d874 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.h +++ b/Modules/_ctypes/libffi_msvc/ffi.h @@ -174,12 +174,10 @@ typedef struct { /* ---- Definitions for the raw API -------------------------------------- */ -#ifndef FFI_SIZEOF_ARG -# if LONG_MAX == 2147483647 -# define FFI_SIZEOF_ARG 4 -# elif LONG_MAX == 9223372036854775807 -# define FFI_SIZEOF_ARG 8 -# endif +#ifdef _WIN64 +#define FFI_SIZEOF_ARG 8 +#else +#define FFI_SIZEOF_ARG 4 #endif typedef union { diff --git a/Modules/_ctypes/libffi_msvc/ffitarget.h b/Modules/_ctypes/libffi_msvc/ffitarget.h index 78c0c37..0da79d4 100644 --- a/Modules/_ctypes/libffi_msvc/ffitarget.h +++ b/Modules/_ctypes/libffi_msvc/ffitarget.h @@ -44,7 +44,9 @@ typedef enum ffi_abi { /* ---- Intel x86 Win32 ---------- */ FFI_SYSV, +#ifndef _WIN64 FFI_STDCALL, +#endif /* TODO: Add fastcall support for the sake of completeness */ FFI_DEFAULT_ABI = FFI_SYSV, @@ -67,8 +69,8 @@ typedef enum ffi_abi { #define FFI_CLOSURES 1 -#ifdef X86_64 -#define FFI_TRAMPOLINE_SIZE 24 +#ifdef _WIN64 +#define FFI_TRAMPOLINE_SIZE 29 #define FFI_NATIVE_RAW_API 0 #else #define FFI_TRAMPOLINE_SIZE 15 diff --git a/Modules/_ctypes/libffi_msvc/win64.asm b/Modules/_ctypes/libffi_msvc/win64.asm new file mode 100644 index 0000000..301188b --- /dev/null +++ b/Modules/_ctypes/libffi_msvc/win64.asm @@ -0,0 +1,156 @@ +PUBLIC ffi_call_AMD64 + +EXTRN __chkstk:NEAR +EXTRN ffi_closure_SYSV:NEAR + +_TEXT SEGMENT + +;;; ffi_closure_OUTER will be called with these registers set: +;;; rax points to 'closure' +;;; r11 contains a bit mask that specifies which of the +;;; first four parameters are float or double +;;; +;;; It must move the parameters passed in registers to their stack location, +;;; call ffi_closure_SYSV for the actual work, then return the result. +;;; +ffi_closure_OUTER PROC FRAME + ;; save actual arguments to their stack space. + test r11, 1 + jne first_is_float + mov QWORD PTR [rsp+8], rcx + jmp second +first_is_float: + movlpd QWORD PTR [rsp+8], xmm0 + +second: + test r11, 2 + jne second_is_float + mov QWORD PTR [rsp+16], rdx + jmp third +second_is_float: + movlpd QWORD PTR [rsp+16], xmm1 + +third: + test r11, 4 + jne third_is_float + mov QWORD PTR [rsp+24], r8 + jmp forth +third_is_float: + movlpd QWORD PTR [rsp+24], xmm2 + +forth: + test r11, 8 + jne forth_is_float + mov QWORD PTR [rsp+32], r9 + jmp done +forth_is_float: + movlpd QWORD PTR [rsp+32], xmm3 + +done: +.ALLOCSTACK 40 + sub rsp, 40 +.ENDPROLOG + mov rcx, rax ; context is first parameter + mov rdx, rsp ; stack is second parameter + add rdx, 40 ; correct our own area + mov rax, ffi_closure_SYSV + call rax ; call the real closure function + ;; Here, code is missing that handles float return values + add rsp, 40 + movd xmm0, rax ; In case the closure returned a float. + ret 0 +ffi_closure_OUTER ENDP + + +;;; ffi_call_AMD64 + +stack$ = 0 +prepfunc$ = 32 +ecif$ = 40 +bytes$ = 48 +flags$ = 56 +rvalue$ = 64 +fn$ = 72 + +ffi_call_AMD64 PROC FRAME + + mov QWORD PTR [rsp+32], r9 + mov QWORD PTR [rsp+24], r8 + mov QWORD PTR [rsp+16], rdx + mov QWORD PTR [rsp+8], rcx +.PUSHREG rbp + push rbp +.ALLOCSTACK 48 + sub rsp, 48 ; 00000030H +.SETFRAME rbp, 32 + lea rbp, QWORD PTR [rsp+32] +.ENDPROLOG + + mov eax, DWORD PTR bytes$[rbp] + add rax, 15 + and rax, -16 + call __chkstk + sub rsp, rax + lea rax, QWORD PTR [rsp+32] + mov QWORD PTR stack$[rbp], rax + + mov rdx, QWORD PTR ecif$[rbp] + mov rcx, QWORD PTR stack$[rbp] + call QWORD PTR prepfunc$[rbp] + + mov rsp, QWORD PTR stack$[rbp] + + movlpd xmm3, QWORD PTR [rsp+24] + movd r9, xmm3 + + movlpd xmm2, QWORD PTR [rsp+16] + movd r8, xmm2 + + movlpd xmm1, QWORD PTR [rsp+8] + movd rdx, xmm1 + + movlpd xmm0, QWORD PTR [rsp] + movd rcx, xmm0 + + call QWORD PTR fn$[rbp] +ret_int$: + cmp DWORD PTR flags$[rbp], 1 ; FFI_TYPE_INT + jne ret_float$ + + mov rcx, QWORD PTR rvalue$[rbp] + mov DWORD PTR [rcx], eax + jmp SHORT ret_nothing$ + +ret_float$: + cmp DWORD PTR flags$[rbp], 2 ; FFI_TYPE_FLOAT + jne SHORT ret_double$ + + mov rax, QWORD PTR rvalue$[rbp] + movlpd QWORD PTR [rax], xmm0 + jmp SHORT ret_nothing$ + +ret_double$: + cmp DWORD PTR flags$[rbp], 3 ; FFI_TYPE_DOUBLE + jne SHORT ret_int64$ + + mov rax, QWORD PTR rvalue$[rbp] + movlpd QWORD PTR [rax], xmm0 + jmp SHORT ret_nothing$ + +ret_int64$: + cmp DWORD PTR flags$[rbp], 12 ; FFI_TYPE_SINT64 + jne ret_nothing$ + + mov rcx, QWORD PTR rvalue$[rbp] + mov QWORD PTR [rcx], rax + jmp SHORT ret_nothing$ + +ret_nothing$: + xor eax, eax + + lea rsp, QWORD PTR [rbp+16] + pop rbp + ret 0 +ffi_call_AMD64 ENDP +_TEXT ENDS +END diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 0942b48..c34ae01 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -173,11 +173,11 @@ MakeFields(PyObject *type, CFieldObject *descr, for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) { PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */ - PyObject *fname, *ftype; + PyObject *fname, *ftype, *bits; CFieldObject *fdescr; CFieldObject *new_descr; /* Convert to PyArg_UnpackTuple... */ - if (!PyArg_ParseTuple(pair, "OO", &fname, &ftype)) { + if (!PyArg_ParseTuple(pair, "OO|O", &fname, &ftype, &bits)) { Py_DECREF(fieldlist); return -1; } @@ -335,14 +335,14 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) stgdict = PyType_stgdict(type); if (!stgdict) return -1; + /* If this structure/union is already marked final we cannot assign + _fields_ anymore. */ + if (stgdict->flags & DICTFLAG_FINAL) {/* is final ? */ PyErr_SetString(PyExc_AttributeError, "_fields_ is final"); return -1; } - /* XXX This should probably be moved to a point when all this - stuff is sucessfully finished. */ - stgdict->flags |= DICTFLAG_FINAL; /* set final */ if (stgdict->ffi_type_pointer.elements) PyMem_Free(stgdict->ffi_type_pointer.elements); @@ -476,5 +476,15 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) stgdict->size = size; stgdict->align = total_align; stgdict->length = len; /* ADD ffi_ofs? */ + + /* We did check that this flag was NOT set above, it must not + have been set until now. */ + if (stgdict->flags & DICTFLAG_FINAL) { + PyErr_SetString(PyExc_AttributeError, + "Structure or union cannot contain itself"); + return -1; + } + stgdict->flags |= DICTFLAG_FINAL; + return MakeAnonFields(type); } diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 2921d53..aeb1ef5 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -2334,6 +2334,10 @@ PyCurses_tparm(PyObject *self, PyObject *args) } result = tparm(fmt,i1,i2,i3,i4,i5,i6,i7,i8,i9); + if (!result) { + PyErr_SetString(PyCursesError, "tparm() returned NULL"); + return NULL; + } return PyString_FromString(result); } diff --git a/Modules/_sre.c b/Modules/_sre.c index d30a350..a24f286 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -1166,9 +1166,10 @@ entrance: /* install new repeat context */ ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep)); - /* XXX(nnorwitz): anything else we need to do on error? */ - if (!ctx->u.rep) + if (!ctx->u.rep) { + PyErr_NoMemory(); RETURN_FAILURE; + } ctx->u.rep->count = -1; ctx->u.rep->pattern = ctx->pattern; ctx->u.rep->prev = state->repeat; @@ -1884,6 +1885,8 @@ pattern_match(PatternObject* self, PyObject* args, PyObject* kw) } TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); + if (PyErr_Occurred()) + return NULL; state_fini(&state); @@ -1922,6 +1925,9 @@ pattern_search(PatternObject* self, PyObject* args, PyObject* kw) state_fini(&state); + if (PyErr_Occurred()) + return NULL; + return pattern_new_match(self, &state, status); } @@ -2071,6 +2077,9 @@ pattern_findall(PatternObject* self, PyObject* args, PyObject* kw) #endif } + if (PyErr_Occurred()) + goto error; + if (status <= 0) { if (status == 0) break; @@ -2198,6 +2207,9 @@ pattern_split(PatternObject* self, PyObject* args, PyObject* kw) #endif } + if (PyErr_Occurred()) + goto error; + if (status <= 0) { if (status == 0) break; @@ -2347,6 +2359,9 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, #endif } + if (PyErr_Occurred()) + goto error; + if (status <= 0) { if (status == 0) break; @@ -3250,6 +3265,8 @@ scanner_match(ScannerObject* self, PyObject *unused) status = sre_umatch(state, PatternObject_GetCode(self->pattern)); #endif } + if (PyErr_Occurred()) + return NULL; match = pattern_new_match((PatternObject*) self->pattern, state, status); @@ -3281,6 +3298,8 @@ scanner_search(ScannerObject* self, PyObject *unused) status = sre_usearch(state, PatternObject_GetCode(self->pattern)); #endif } + if (PyErr_Occurred()) + return NULL; match = pattern_new_match((PatternObject*) self->pattern, state, status); diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 3b91b24..f1e1092 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -317,7 +317,7 @@ PySocket_ssl(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!|zz:ssl", PySocketModule.Sock_Type, - (PyObject*)&Sock, + &Sock, &key_file, &cert_file)) return NULL; diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index f5f3ab2..b11f0ae 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6,6 +6,8 @@ */ #include "Python.h" +#include <float.h> +#include "structmember.h" #ifdef WITH_THREAD #include "pythread.h" @@ -35,13 +37,13 @@ raiseTestError(const char* test_name, const char* msg) platforms have these hardcoded. Better safe than sorry. */ static PyObject* -sizeof_error(const char* fatname, const char* typename, +sizeof_error(const char* fatname, const char* typname, int expected, int got) { char buf[1024]; PyOS_snprintf(buf, sizeof(buf), "%.200s #define == %d but sizeof(%.200s) == %d", - fatname, expected, typename, got); + fatname, expected, typname, got); PyErr_SetString(TestError, buf); return (PyObject*)NULL; } @@ -615,7 +617,7 @@ _make_call(void *callable) { PyObject *rc; PyGILState_STATE s = PyGILState_Ensure(); - rc = PyObject_CallFunction(callable, ""); + rc = PyObject_CallFunction((PyObject *)callable, ""); Py_XDECREF(rc); PyGILState_Release(s); } @@ -665,6 +667,9 @@ test_thread_state(PyObject *self, PyObject *args) PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ Py_END_ALLOW_THREADS + /* Release lock we acquired above. This is required on HP-UX. */ + PyThread_release_lock(thread_done); + PyThread_free_lock(thread_done); Py_RETURN_NONE; } @@ -756,6 +761,105 @@ static PyMethodDef TestMethods[] = { #define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);} +typedef struct { + char byte_member; + unsigned char ubyte_member; + short short_member; + unsigned short ushort_member; + int int_member; + unsigned int uint_member; + long long_member; + unsigned long ulong_member; + float float_member; + double double_member; +} all_structmembers; + +typedef struct { + PyObject_HEAD + all_structmembers structmembers; +} test_structmembers; + +static struct PyMemberDef test_members[] = { + {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL}, + {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL}, + {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL}, + {"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL}, + {"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL}, + {"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL}, + {"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL}, + {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL}, + {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, + {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, + {NULL} +}; + + +static PyObject *test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs){ + static char *keywords[]={"T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", "T_INT", "T_UINT", + "T_LONG", "T_ULONG", "T_FLOAT", "T_DOUBLE", NULL}; + test_structmembers *ob=PyObject_New(test_structmembers, type); + if (ob==NULL) + return NULL; + memset(&ob->structmembers, 0, sizeof(all_structmembers)); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|bBhHiIlkfd", keywords, + &ob->structmembers.byte_member, &ob->structmembers.ubyte_member, + &ob->structmembers.short_member, &ob->structmembers.ushort_member, + &ob->structmembers.int_member, &ob->structmembers.uint_member, + &ob->structmembers.long_member, &ob->structmembers.ulong_member, + &ob->structmembers.float_member, &ob->structmembers.double_member)){ + Py_DECREF(ob); + return NULL; + } + return (PyObject *)ob; +} + +static void test_structmembers_free(PyObject *ob){ + PyObject_FREE(ob); +} + +static PyTypeObject test_structmembersType = { + PyObject_HEAD_INIT(NULL) + 0, + "test_structmembersType", + sizeof(test_structmembers), /* tp_basicsize */ + 0, /* tp_itemsize */ + test_structmembers_free, /* destructor tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + "Type containing all structmember types", + 0, /* traverseproc tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + test_members, /* tp_members */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + test_structmembers_new, /* tp_new */ +}; + + PyMODINIT_FUNC init_testcapi(void) { @@ -765,16 +869,28 @@ init_testcapi(void) if (m == NULL) return; + test_structmembersType.ob_type=&PyType_Type; + Py_INCREF(&test_structmembersType); + PyModule_AddObject(m, "test_structmembersType", (PyObject *)&test_structmembersType); + + PyModule_AddObject(m, "CHAR_MAX", PyInt_FromLong(CHAR_MAX)); + PyModule_AddObject(m, "CHAR_MIN", PyInt_FromLong(CHAR_MIN)); PyModule_AddObject(m, "UCHAR_MAX", PyInt_FromLong(UCHAR_MAX)); + PyModule_AddObject(m, "SHRT_MAX", PyInt_FromLong(SHRT_MAX)); + PyModule_AddObject(m, "SHRT_MIN", PyInt_FromLong(SHRT_MIN)); PyModule_AddObject(m, "USHRT_MAX", PyInt_FromLong(USHRT_MAX)); + PyModule_AddObject(m, "INT_MAX", PyLong_FromLong(INT_MAX)); + PyModule_AddObject(m, "INT_MIN", PyLong_FromLong(INT_MIN)); PyModule_AddObject(m, "UINT_MAX", PyLong_FromUnsignedLong(UINT_MAX)); - PyModule_AddObject(m, "ULONG_MAX", PyLong_FromUnsignedLong(ULONG_MAX)); - PyModule_AddObject(m, "INT_MIN", PyInt_FromLong(INT_MIN)); - PyModule_AddObject(m, "LONG_MIN", PyInt_FromLong(LONG_MIN)); - PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN)); - PyModule_AddObject(m, "INT_MAX", PyInt_FromLong(INT_MAX)); PyModule_AddObject(m, "LONG_MAX", PyInt_FromLong(LONG_MAX)); + PyModule_AddObject(m, "LONG_MIN", PyInt_FromLong(LONG_MIN)); + PyModule_AddObject(m, "ULONG_MAX", PyLong_FromUnsignedLong(ULONG_MAX)); + PyModule_AddObject(m, "FLT_MAX", PyFloat_FromDouble(FLT_MAX)); + PyModule_AddObject(m, "FLT_MIN", PyFloat_FromDouble(FLT_MIN)); + PyModule_AddObject(m, "DBL_MAX", PyFloat_FromDouble(DBL_MAX)); + PyModule_AddObject(m, "DBL_MIN", PyFloat_FromDouble(DBL_MIN)); PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyInt_FromSsize_t(PY_SSIZE_T_MAX)); + PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN)); TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); diff --git a/Modules/almodule.c b/Modules/almodule.c index fbeb13a..0a45d2e 100644 --- a/Modules/almodule.c +++ b/Modules/almodule.c @@ -1686,7 +1686,7 @@ al_GetParamInfo(PyObject *self, PyObject *args) { int res, param; ALparamInfo pinfo; - PyObject *v, *item;; + PyObject *v, *item; if (!PyArg_ParseTuple(args, "ii:GetParamInfo", &res, ¶m)) return NULL; diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 6ce6b07..552f80c 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1495,7 +1495,7 @@ PyMethodDef array_methods[] = { copy_doc}, {"count", (PyCFunction)array_count, METH_O, count_doc}, - {"__deepcopy__",(PyCFunction)array_copy, METH_NOARGS, + {"__deepcopy__",(PyCFunction)array_copy, METH_O, copy_doc}, {"extend", (PyCFunction)array_extend, METH_O, extend_doc}, diff --git a/Modules/audioop.c b/Modules/audioop.c index 8f5d30c..ce00975 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -472,8 +472,12 @@ audioop_findfit(PyObject *self, PyObject *args) double aj_m1, aj_lm1; double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor; + /* Passing a short** for an 's' argument is correct only + if the string contents is aligned for interpretation + as short[]. Due to the definition of PyStringObject, + this is currently (Python 2.6) the case. */ if ( !PyArg_ParseTuple(args, "s#s#:findfit", - &cp1, &len1, &cp2, &len2) ) + (char**)&cp1, &len1, (char**)&cp2, &len2) ) return 0; if ( len1 & 1 || len2 & 1 ) { PyErr_SetString(AudioopError, "Strings should be even-sized"); @@ -530,7 +534,7 @@ audioop_findfactor(PyObject *self, PyObject *args) double sum_ri_2, sum_aij_ri, result; if ( !PyArg_ParseTuple(args, "s#s#:findfactor", - &cp1, &len1, &cp2, &len2) ) + (char**)&cp1, &len1, (char**)&cp2, &len2) ) return 0; if ( len1 & 1 || len2 & 1 ) { PyErr_SetString(AudioopError, "Strings should be even-sized"); @@ -562,7 +566,8 @@ audioop_findmax(PyObject *self, PyObject *args) double aj_m1, aj_lm1; double result, best_result; - if ( !PyArg_ParseTuple(args, "s#i:findmax", &cp1, &len1, &len2) ) + if ( !PyArg_ParseTuple(args, "s#i:findmax", + (char**)&cp1, &len1, &len2) ) return 0; if ( len1 & 1 ) { PyErr_SetString(AudioopError, "Strings should be even-sized"); diff --git a/Modules/binascii.c b/Modules/binascii.c index 3b2c8b2..4dee451 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -1057,8 +1057,7 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) in++; if (in >= datalen) break; /* Soft line breaks */ - if ((data[in] == '\n') || (data[in] == '\r') || - (data[in] == ' ') || (data[in] == '\t')) { + if ((data[in] == '\n') || (data[in] == '\r')) { if (data[in] != '\n') { while (in < datalen && data[in] != '\n') in++; } diff --git a/Modules/bz2module.c b/Modules/bz2module.c index 146e2ee..5a4e5d9 100644 --- a/Modules/bz2module.c +++ b/Modules/bz2module.c @@ -1016,12 +1016,12 @@ BZ2File_seek(BZ2FileObject *self, PyObject *args) case MODE_CLOSED: PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); - goto cleanup;; + goto cleanup; default: PyErr_SetString(PyExc_IOError, "seek works only while reading"); - goto cleanup;; + goto cleanup; } if (where == 2) { diff --git a/Modules/cPickle.c b/Modules/cPickle.c index fabc3cd..f3178ab 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -1024,7 +1024,7 @@ save_int(Picklerobject *self, PyObject *args) static int save_long(Picklerobject *self, PyObject *args) { - int size; + Py_ssize_t size; int res = -1; PyObject *repr = NULL; @@ -1066,7 +1066,7 @@ save_long(Picklerobject *self, PyObject *args) * byte at the start, and cut it back later if possible. */ nbytes = (nbits >> 3) + 1; - if ((int)nbytes < 0 || (size_t)(int)nbytes != nbytes) { + if (nbytes > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "long too large " "to pickle"); goto finally; @@ -1208,12 +1208,14 @@ save_string(Picklerobject *self, PyObject *args, int doput) c_str[1] = size; len = 2; } - else { + else if (size <= INT_MAX) { c_str[0] = BINSTRING; for (i = 1; i < 5; i++) c_str[i] = (int)(size >> ((i - 1) * 8)); len = 5; } + else + return -1; /* string too large */ if (self->write_func(self, c_str, len) < 0) return -1; @@ -1286,7 +1288,7 @@ modified_EncodeRawUnicodeEscape(const Py_UNICODE *s, int size) static int save_unicode(Picklerobject *self, PyObject *args, int doput) { - int size, len; + Py_ssize_t size, len; PyObject *repr=0; if (!PyUnicode_Check(args)) @@ -1325,6 +1327,8 @@ save_unicode(Picklerobject *self, PyObject *args, int doput) if ((size = PyString_Size(repr)) < 0) goto err; + if (size > INT_MAX) + return -1; /* string too large */ c_str[0] = BINUNICODE; for (i = 1; i < 5; i++) diff --git a/Modules/cStringIO.c b/Modules/cStringIO.c index 4debb72..3f762b0 100644 --- a/Modules/cStringIO.c +++ b/Modules/cStringIO.c @@ -289,7 +289,17 @@ IO_truncate(IOobject *self, PyObject *args) { if (!IO__opencheck(self)) return NULL; if (!PyArg_ParseTuple(args, "|n:truncate", &pos)) return NULL; - if (pos < 0) pos = self->pos; + + if (PyTuple_Size(args) == 0) { + /* No argument passed, truncate to current position */ + pos = self->pos; + } + + if (pos < 0) { + errno = EINVAL; + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } if (self->string_size > pos) self->string_size = pos; self->pos = self->string_size; @@ -657,11 +667,9 @@ newIobject(PyObject *s) { char *buf; Py_ssize_t size; - if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) { - PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found", - s->ob_type->tp_name); + if (PyObject_AsCharBuffer(s, (const char **)&buf, &size) != 0) return NULL; - } + self = PyObject_New(Iobject, &Itype); if (!self) return NULL; Py_INCREF(s); diff --git a/Modules/cjkcodecs/_codecs_cn.c b/Modules/cjkcodecs/_codecs_cn.c index fb51297..c811a67 100644 --- a/Modules/cjkcodecs/_codecs_cn.c +++ b/Modules/cjkcodecs/_codecs_cn.c @@ -15,14 +15,26 @@ #undef hz #endif -#define GBK_PREDECODE(dc1, dc2, assi) \ +/* GBK and GB2312 map differently in few codepoints that are listed below: + * + * gb2312 gbk + * A1A4 U+30FB KATAKANA MIDDLE DOT U+00B7 MIDDLE DOT + * A1AA U+2015 HORIZONTAL BAR U+2014 EM DASH + * A844 undefined U+2015 HORIZONTAL BAR + */ + +#define GBK_DECODE(dc1, dc2, assi) \ if ((dc1) == 0xa1 && (dc2) == 0xaa) (assi) = 0x2014; \ else if ((dc1) == 0xa8 && (dc2) == 0x44) (assi) = 0x2015; \ - else if ((dc1) == 0xa1 && (dc2) == 0xa4) (assi) = 0x00b7; -#define GBK_PREENCODE(code, assi) \ + else if ((dc1) == 0xa1 && (dc2) == 0xa4) (assi) = 0x00b7; \ + else TRYMAP_DEC(gb2312, assi, dc1 ^ 0x80, dc2 ^ 0x80); \ + else TRYMAP_DEC(gbkext, assi, dc1, dc2); + +#define GBK_ENCODE(code, assi) \ if ((code) == 0x2014) (assi) = 0xa1aa; \ else if ((code) == 0x2015) (assi) = 0xa844; \ - else if ((code) == 0x00b7) (assi) = 0xa1a4; + else if ((code) == 0x00b7) (assi) = 0xa1a4; \ + else if ((code) != 0x30fb && TRYMAP_ENC_COND(gbcommon, assi, code)); /* * GB2312 codec @@ -99,8 +111,7 @@ ENCODER(gbk) REQUIRE_OUTBUF(2) - GBK_PREENCODE(c, code) - else TRYMAP_ENC(gbcommon, code, c); + GBK_ENCODE(c, code) else return 1; OUT1((code >> 8) | 0x80) @@ -129,9 +140,7 @@ DECODER(gbk) REQUIRE_INBUF(2) - GBK_PREDECODE(c, IN2, **outbuf) - else TRYMAP_DEC(gb2312, **outbuf, c ^ 0x80, IN2 ^ 0x80); - else TRYMAP_DEC(gbkext, **outbuf, c, IN2); + GBK_DECODE(c, IN2, **outbuf) else return 2; NEXT(2, 1) @@ -187,9 +196,7 @@ ENCODER(gb18030) REQUIRE_OUTBUF(2) - GBK_PREENCODE(c, code) - else TRYMAP_ENC(gbcommon, code, c); - else TRYMAP_ENC(gb18030ext, code, c); + GBK_ENCODE(c, code) else { const struct _gb18030_to_unibmp_ranges *utrrange; @@ -287,9 +294,7 @@ DECODER(gb18030) return 4; } - GBK_PREDECODE(c, c2, **outbuf) - else TRYMAP_DEC(gb2312, **outbuf, c ^ 0x80, c2 ^ 0x80); - else TRYMAP_DEC(gbkext, **outbuf, c, c2); + GBK_DECODE(c, c2, **outbuf) else TRYMAP_DEC(gb18030ext, **outbuf, c, c2); else return 2; diff --git a/Modules/cjkcodecs/_codecs_iso2022.c b/Modules/cjkcodecs/_codecs_iso2022.c index 8a2ab7e..55196a9 100644 --- a/Modules/cjkcodecs/_codecs_iso2022.c +++ b/Modules/cjkcodecs/_codecs_iso2022.c @@ -592,9 +592,11 @@ ksx1001_encoder(const ucs4_t *data, Py_ssize_t *length) { DBCHAR coded; assert(*length == 1); - TRYMAP_ENC(cp949, coded, *data) - if (!(coded & 0x8000)) - return coded; + if (*data < 0x10000) { + TRYMAP_ENC(cp949, coded, *data) + if (!(coded & 0x8000)) + return coded; + } return MAP_UNMAPPABLE; } @@ -628,11 +630,13 @@ jisx0208_encoder(const ucs4_t *data, Py_ssize_t *length) { DBCHAR coded; assert(*length == 1); - if (*data == 0xff3c) /* F/W REVERSE SOLIDUS */ - return 0x2140; - else TRYMAP_ENC(jisxcommon, coded, *data) { - if (!(coded & 0x8000)) - return coded; + if (*data < 0x10000) { + if (*data == 0xff3c) /* F/W REVERSE SOLIDUS */ + return 0x2140; + else TRYMAP_ENC(jisxcommon, coded, *data) { + if (!(coded & 0x8000)) + return coded; + } } return MAP_UNMAPPABLE; } @@ -665,9 +669,11 @@ jisx0212_encoder(const ucs4_t *data, Py_ssize_t *length) { DBCHAR coded; assert(*length == 1); - TRYMAP_ENC(jisxcommon, coded, *data) { - if (coded & 0x8000) - return coded & 0x7fff; + if (*data < 0x10000) { + TRYMAP_ENC(jisxcommon, coded, *data) { + if (coded & 0x8000) + return coded & 0x7fff; + } } return MAP_UNMAPPABLE; } @@ -854,7 +860,7 @@ jisx0213_2000_2_encoder(const ucs4_t *data, Py_ssize_t *length) if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) return coded; else if (coded & 0x8000) - return coded; + return coded & 0x7fff; else return MAP_UNMAPPABLE; } @@ -901,7 +907,7 @@ jisx0213_2004_2_encoder(const ucs4_t *data, Py_ssize_t *length) if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) return coded; else if (coded & 0x8000) - return coded; + return coded & 0x7fff; else return MAP_UNMAPPABLE; } @@ -970,9 +976,11 @@ gb2312_encoder(const ucs4_t *data, Py_ssize_t *length) { DBCHAR coded; assert(*length == 1); - TRYMAP_ENC(gbcommon, coded, *data) { - if (!(coded & 0x8000)) - return coded; + if (*data < 0x10000) { + TRYMAP_ENC(gbcommon, coded, *data) { + if (!(coded & 0x8000)) + return coded; + } } return MAP_UNMAPPABLE; } @@ -992,7 +1000,10 @@ dummy_encoder(const ucs4_t *data, Py_ssize_t *length) /*-*- registry tables -*-*/ -#define REGISTRY_KSX1001 { CHARSET_KSX1001, 1, 2, \ +#define REGISTRY_KSX1001_G0 { CHARSET_KSX1001, 0, 2, \ + ksx1001_init, \ + ksx1001_decoder, ksx1001_encoder } +#define REGISTRY_KSX1001_G1 { CHARSET_KSX1001, 1, 2, \ ksx1001_init, \ ksx1001_decoder, ksx1001_encoder } #define REGISTRY_JISX0201_R { CHARSET_JISX0201_R, 0, 1, \ @@ -1034,7 +1045,7 @@ dummy_encoder(const ucs4_t *data, Py_ssize_t *length) jisx0213_init, \ jisx0213_2004_2_decoder, \ jisx0213_2004_2_encoder } -#define REGISTRY_GB2312 { CHARSET_GB2312, 1, 2, \ +#define REGISTRY_GB2312 { CHARSET_GB2312, 0, 2, \ gb2312_init, \ gb2312_decoder, gb2312_encoder } #define REGISTRY_CNS11643_1 { CHARSET_CNS11643_1, 1, 2, \ @@ -1054,7 +1065,7 @@ dummy_encoder(const ucs4_t *data, Py_ssize_t *length) }; static const struct iso2022_designation iso2022_kr_designations[] = { - REGISTRY_KSX1001, REGISTRY_SENTINEL + REGISTRY_KSX1001_G1, REGISTRY_SENTINEL }; CONFIGDEF(kr, 0) @@ -1071,7 +1082,7 @@ static const struct iso2022_designation iso2022_jp_1_designations[] = { CONFIGDEF(jp_1, NO_SHIFT | USE_JISX0208_EXT) static const struct iso2022_designation iso2022_jp_2_designations[] = { - REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_KSX1001, + REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_KSX1001_G0, REGISTRY_GB2312, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O, REGISTRY_ISO8859_1, REGISTRY_ISO8859_7, REGISTRY_SENTINEL }; diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h index b266c8f..71c54f0 100644 --- a/Modules/cjkcodecs/cjkcodecs.h +++ b/Modules/cjkcodecs/cjkcodecs.h @@ -159,29 +159,32 @@ static const struct dbcs_map *mapping_list; #endif #define _TRYMAP_ENC(m, assi, val) \ - if ((m)->map != NULL && (val) >= (m)->bottom && \ + ((m)->map != NULL && (val) >= (m)->bottom && \ (val)<= (m)->top && ((assi) = (m)->map[(val) - \ (m)->bottom]) != NOCHAR) -#define TRYMAP_ENC(charset, assi, uni) \ +#define TRYMAP_ENC_COND(charset, assi, uni) \ _TRYMAP_ENC(&charset##_encmap[(uni) >> 8], assi, (uni) & 0xff) +#define TRYMAP_ENC(charset, assi, uni) \ + if TRYMAP_ENC_COND(charset, assi, uni) + #define _TRYMAP_DEC(m, assi, val) \ - if ((m)->map != NULL && (val) >= (m)->bottom && \ + ((m)->map != NULL && (val) >= (m)->bottom && \ (val)<= (m)->top && ((assi) = (m)->map[(val) - \ (m)->bottom]) != UNIINV) #define TRYMAP_DEC(charset, assi, c1, c2) \ - _TRYMAP_DEC(&charset##_decmap[c1], assi, c2) + if _TRYMAP_DEC(&charset##_decmap[c1], assi, c2) #define _TRYMAP_ENC_MPLANE(m, assplane, asshi, asslo, val) \ - if ((m)->map != NULL && (val) >= (m)->bottom && \ + ((m)->map != NULL && (val) >= (m)->bottom && \ (val)<= (m)->top && \ ((assplane) = (m)->map[((val) - (m)->bottom)*3]) != 0 && \ (((asshi) = (m)->map[((val) - (m)->bottom)*3 + 1]), 1) && \ (((asslo) = (m)->map[((val) - (m)->bottom)*3 + 2]), 1)) #define TRYMAP_ENC_MPLANE(charset, assplane, asshi, asslo, uni) \ - _TRYMAP_ENC_MPLANE(&charset##_encmap[(uni) >> 8], \ + if _TRYMAP_ENC_MPLANE(&charset##_encmap[(uni) >> 8], \ assplane, asshi, asslo, (uni) & 0xff) #define TRYMAP_DEC_MPLANE(charset, assi, plane, c1, c2) \ - _TRYMAP_DEC(&charset##_decmap[plane][c1], assi, c2) + if _TRYMAP_DEC(&charset##_decmap[plane][c1], assi, c2) #if Py_UNICODE_SIZE == 2 #define DECODE_SURROGATE(c) \ diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c index b57ccbc..7ffa316 100644 --- a/Modules/datetimemodule.c +++ b/Modules/datetimemodule.c @@ -1149,9 +1149,9 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, PyObject *newfmt = NULL; /* py string, the output format */ char *pnew; /* pointer to available byte in output format */ - char totalnew; /* number bytes total in output format buffer, + int totalnew; /* number bytes total in output format buffer, exclusive of trailing \0 */ - char usednew; /* number bytes used so far in output format buffer */ + int usednew; /* number bytes used so far in output format buffer */ char *ptoappend; /* pointer to string to append to output buffer */ int ntoappend; /* # of bytes to append to output buffer */ diff --git a/Modules/dbmmodule.c b/Modules/dbmmodule.c index ee5a7f0..83f5f43 100644 --- a/Modules/dbmmodule.c +++ b/Modules/dbmmodule.c @@ -246,11 +246,13 @@ dbm_get(register dbmobject *dp, PyObject *args) { datum key, val; PyObject *defvalue = Py_None; + char *tmp_ptr; int tmp_size; if (!PyArg_ParseTuple(args, "s#|O:get", - &key.dptr, &tmp_size, &defvalue)) + &tmp_ptr, &tmp_size, &defvalue)) return NULL; + key.dptr = tmp_ptr; key.dsize = tmp_size; check_dbmobject_open(dp); val = dbm_fetch(dp->di_dbm, key); @@ -267,11 +269,13 @@ dbm_setdefault(register dbmobject *dp, PyObject *args) { datum key, val; PyObject *defvalue = NULL; + char *tmp_ptr; int tmp_size; if (!PyArg_ParseTuple(args, "s#|S:setdefault", - &key.dptr, &tmp_size, &defvalue)) + &tmp_ptr, &tmp_size, &defvalue)) return NULL; + key.dptr = tmp_ptr; key.dsize = tmp_size; check_dbmobject_open(dp); val = dbm_fetch(dp->di_dbm, key); diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 99f2897..2dd058e 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1153,6 +1153,7 @@ PyDoc_STRVAR(gc__doc__, "disable() -- Disable automatic garbage collection.\n" "isenabled() -- Returns true if automatic collection is enabled.\n" "collect() -- Do a full collection right now.\n" +"get_count() -- Return the current collection counts.\n" "set_debug() -- Set debugging flags.\n" "get_debug() -- Get debugging flags.\n" "set_threshold() -- Set the collection thresholds.\n" diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index d913890..7fcbb10 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -618,11 +618,15 @@ static PyTypeObject tee_type = { static PyObject * tee(PyObject *self, PyObject *args) { - int i, n=2; + Py_ssize_t i, n=2; PyObject *it, *iterable, *copyable, *result; - if (!PyArg_ParseTuple(args, "O|i", &iterable, &n)) + if (!PyArg_ParseTuple(args, "O|n", &iterable, &n)) return NULL; + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "n must be >= 0"); + return NULL; + } result = PyTuple_New(n); if (result == NULL) return NULL; @@ -2068,7 +2072,7 @@ count_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject * count_next(countobject *lz) { - return PyInt_FromSize_t(lz->cnt++); + return PyInt_FromSsize_t(lz->cnt++); } static PyObject * diff --git a/Modules/linuxaudiodev.c b/Modules/linuxaudiodev.c index c1c7363..b435d76 100644 --- a/Modules/linuxaudiodev.c +++ b/Modules/linuxaudiodev.c @@ -28,7 +28,9 @@ #if defined(linux) #include <linux/soundcard.h> +#ifndef HAVE_STDINT_H typedef unsigned long uint32_t; +#endif #elif defined(__FreeBSD__) #include <machine/soundcard.h> diff --git a/Modules/main.c b/Modules/main.c index 3f39c9b..ac6b38d 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -59,31 +59,32 @@ static char *usage_line = static char *usage_1 = "\ Options and arguments (and corresponding environment variables):\n\ -c cmd : program passed in as string (terminates option list)\n\ --d : debug output from parser (also PYTHONDEBUG=x)\n\ +-d : debug output from parser; also PYTHONDEBUG=x\n\ -E : ignore environment variables (such as PYTHONPATH)\n\ -h : print this help message and exit (also --help)\n\ --i : inspect interactively after running script, (also PYTHONINSPECT=x)\n\ - and force prompts, even if stdin does not appear to be a terminal\n\ +-i : inspect interactively after running script; forces a prompt even\n\ + if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\ "; static char *usage_2 = "\ -m mod : run library module as a script (terminates option list)\n\ --O : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\ +-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ -S : don't imply 'import site' on initialization\n\ -t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\ --u : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\ +-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\ "; static char *usage_3 = "\ see man page for details on internal buffering relating to '-u'\n\ --v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ +-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\ + can be supplied multiple times to increase verbosity\n\ -V : print the Python version number and exit (also --version)\n\ --W arg : warning control (arg is action:message:category:module:lineno)\n\ +-W arg : warning control; arg is action:message:category:module:lineno\n\ -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ file : program read from script file\n\ - : program read from stdin (default; interactive mode if a tty)\n\ "; static char *usage_4 = "\ -arg ...: arguments passed to program in sys.argv[1:]\n\ +arg ...: arguments passed to program in sys.argv[1:]\n\n\ Other environment variables:\n\ PYTHONSTARTUP: file executed on interactive startup (no default)\n\ PYTHONPATH : '%c'-separated list of directories prefixed to the\n\ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 731b1d9..632dffd 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -48,10 +48,10 @@ is_error(double x) } static PyObject * -math_1(PyObject *args, double (*func) (double), char *argsfmt) +math_1(PyObject *arg, double (*func) (double)) { - double x; - if (! PyArg_ParseTuple(args, argsfmt, &x)) + double x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) return NULL; errno = 0; PyFPE_START_PROTECT("in math_1", return 0) @@ -65,10 +65,15 @@ math_1(PyObject *args, double (*func) (double), char *argsfmt) } static PyObject * -math_2(PyObject *args, double (*func) (double, double), char *argsfmt) +math_2(PyObject *args, double (*func) (double, double), char *funcname) { + PyObject *ox, *oy; double x, y; - if (! PyArg_ParseTuple(args, argsfmt, &x, &y)) + if (! PyArg_UnpackTuple(args, funcname, 2, 2, &ox, &oy)) + return NULL; + x = PyFloat_AsDouble(ox); + y = PyFloat_AsDouble(oy); + if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) return NULL; errno = 0; PyFPE_START_PROTECT("in math_2", return 0) @@ -83,13 +88,13 @@ math_2(PyObject *args, double (*func) (double, double), char *argsfmt) #define FUNC1(funcname, func, docstring) \ static PyObject * math_##funcname(PyObject *self, PyObject *args) { \ - return math_1(args, func, "d:" #funcname); \ + return math_1(args, func); \ }\ PyDoc_STRVAR(math_##funcname##_doc, docstring); #define FUNC2(funcname, func, docstring) \ static PyObject * math_##funcname(PyObject *self, PyObject *args) { \ - return math_2(args, func, "dd:" #funcname); \ + return math_2(args, func, #funcname); \ }\ PyDoc_STRVAR(math_##funcname##_doc, docstring); @@ -135,11 +140,11 @@ FUNC1(tanh, tanh, "tanh(x)\n\nReturn the hyperbolic tangent of x.") static PyObject * -math_frexp(PyObject *self, PyObject *args) +math_frexp(PyObject *self, PyObject *arg) { - double x; int i; - if (! PyArg_ParseTuple(args, "d:frexp", &x)) + double x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) return NULL; errno = 0; x = frexp(x, &i); @@ -179,10 +184,10 @@ PyDoc_STRVAR(math_ldexp_doc, "ldexp(x, i) -> x * (2**i)"); static PyObject * -math_modf(PyObject *self, PyObject *args) +math_modf(PyObject *self, PyObject *arg) { - double x, y; - if (! PyArg_ParseTuple(args, "d:modf", &x)) + double y, x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) return NULL; errno = 0; x = modf(x, &y); @@ -208,7 +213,7 @@ PyDoc_STRVAR(math_modf_doc, */ static PyObject* -loghelper(PyObject* args, double (*func)(double), char *format, PyObject *arg) +loghelper(PyObject* arg, double (*func)(double), char *funcname) { /* If it is long, do it ourselves. */ if (PyLong_Check(arg)) { @@ -229,7 +234,7 @@ loghelper(PyObject* args, double (*func)(double), char *format, PyObject *arg) } /* Else let libm handle it by itself. */ - return math_1(args, func, format); + return math_1(arg, func); } static PyObject * @@ -239,28 +244,15 @@ math_log(PyObject *self, PyObject *args) PyObject *base = NULL; PyObject *num, *den; PyObject *ans; - PyObject *newargs; if (!PyArg_UnpackTuple(args, "log", 1, 2, &arg, &base)) return NULL; - if (base == NULL) - return loghelper(args, log, "d:log", arg); - newargs = PyTuple_Pack(1, arg); - if (newargs == NULL) - return NULL; - num = loghelper(newargs, log, "d:log", arg); - Py_DECREF(newargs); - if (num == NULL) - return NULL; + num = loghelper(arg, log, "log"); + if (num == NULL || base == NULL) + return num; - newargs = PyTuple_Pack(1, base); - if (newargs == NULL) { - Py_DECREF(num); - return NULL; - } - den = loghelper(newargs, log, "d:log", base); - Py_DECREF(newargs); + den = loghelper(base, log, "log"); if (den == NULL) { Py_DECREF(num); return NULL; @@ -277,25 +269,23 @@ PyDoc_STRVAR(math_log_doc, If the base not specified, returns the natural logarithm (base e) of x."); static PyObject * -math_log10(PyObject *self, PyObject *args) +math_log10(PyObject *self, PyObject *arg) { - PyObject *arg; - - if (!PyArg_UnpackTuple(args, "log10", 1, 1, &arg)) - return NULL; - return loghelper(args, log10, "d:log10", arg); + return loghelper(arg, log10, "log10"); } PyDoc_STRVAR(math_log10_doc, "log10(x) -> the base 10 logarithm of x."); +/* XXX(nnorwitz): Should we use the platform M_PI or something more accurate + like: 3.14159265358979323846264338327950288 */ static const double degToRad = 3.141592653589793238462643383 / 180.0; static PyObject * -math_degrees(PyObject *self, PyObject *args) +math_degrees(PyObject *self, PyObject *arg) { - double x; - if (! PyArg_ParseTuple(args, "d:degrees", &x)) + double x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) return NULL; return PyFloat_FromDouble(x / degToRad); } @@ -304,10 +294,10 @@ PyDoc_STRVAR(math_degrees_doc, "degrees(x) -> converts angle x from radians to degrees"); static PyObject * -math_radians(PyObject *self, PyObject *args) +math_radians(PyObject *self, PyObject *arg) { - double x; - if (! PyArg_ParseTuple(args, "d:radians", &x)) + double x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) return NULL; return PyFloat_FromDouble(x * degToRad); } @@ -316,31 +306,31 @@ PyDoc_STRVAR(math_radians_doc, "radians(x) -> converts angle x from degrees to radians"); static PyMethodDef math_methods[] = { - {"acos", math_acos, METH_VARARGS, math_acos_doc}, - {"asin", math_asin, METH_VARARGS, math_asin_doc}, - {"atan", math_atan, METH_VARARGS, math_atan_doc}, + {"acos", math_acos, METH_O, math_acos_doc}, + {"asin", math_asin, METH_O, math_asin_doc}, + {"atan", math_atan, METH_O, math_atan_doc}, {"atan2", math_atan2, METH_VARARGS, math_atan2_doc}, - {"ceil", math_ceil, METH_VARARGS, math_ceil_doc}, - {"cos", math_cos, METH_VARARGS, math_cos_doc}, - {"cosh", math_cosh, METH_VARARGS, math_cosh_doc}, - {"degrees", math_degrees, METH_VARARGS, math_degrees_doc}, - {"exp", math_exp, METH_VARARGS, math_exp_doc}, - {"fabs", math_fabs, METH_VARARGS, math_fabs_doc}, - {"floor", math_floor, METH_VARARGS, math_floor_doc}, + {"ceil", math_ceil, METH_O, math_ceil_doc}, + {"cos", math_cos, METH_O, math_cos_doc}, + {"cosh", math_cosh, METH_O, math_cosh_doc}, + {"degrees", math_degrees, METH_O, math_degrees_doc}, + {"exp", math_exp, METH_O, math_exp_doc}, + {"fabs", math_fabs, METH_O, math_fabs_doc}, + {"floor", math_floor, METH_O, math_floor_doc}, {"fmod", math_fmod, METH_VARARGS, math_fmod_doc}, - {"frexp", math_frexp, METH_VARARGS, math_frexp_doc}, + {"frexp", math_frexp, METH_O, math_frexp_doc}, {"hypot", math_hypot, METH_VARARGS, math_hypot_doc}, {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc}, {"log", math_log, METH_VARARGS, math_log_doc}, - {"log10", math_log10, METH_VARARGS, math_log10_doc}, - {"modf", math_modf, METH_VARARGS, math_modf_doc}, + {"log10", math_log10, METH_O, math_log10_doc}, + {"modf", math_modf, METH_O, math_modf_doc}, {"pow", math_pow, METH_VARARGS, math_pow_doc}, - {"radians", math_radians, METH_VARARGS, math_radians_doc}, - {"sin", math_sin, METH_VARARGS, math_sin_doc}, - {"sinh", math_sinh, METH_VARARGS, math_sinh_doc}, - {"sqrt", math_sqrt, METH_VARARGS, math_sqrt_doc}, - {"tan", math_tan, METH_VARARGS, math_tan_doc}, - {"tanh", math_tanh, METH_VARARGS, math_tanh_doc}, + {"radians", math_radians, METH_O, math_radians_doc}, + {"sin", math_sin, METH_O, math_sin_doc}, + {"sinh", math_sinh, METH_O, math_sinh_doc}, + {"sqrt", math_sqrt, METH_O, math_sqrt_doc}, + {"tan", math_tan, METH_O, math_tan_doc}, + {"tanh", math_tanh, METH_O, math_tanh_doc}, {NULL, NULL} /* sentinel */ }; @@ -358,6 +348,8 @@ initmath(void) if (m == NULL) goto finally; d = PyModule_GetDict(m); + if (d == NULL) + goto finally; if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0))) goto finally; diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index a728d3d..d39169a 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -470,7 +470,7 @@ static PyObject * mmap_tell_method(mmap_object *self, PyObject *unused) { CHECK_VALID(NULL); - return PyInt_FromLong((long) self->pos); + return PyInt_FromSize_t(self->pos); } static PyObject * diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index 9716838..eb59c4d 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -34,7 +34,9 @@ #if defined(linux) +#ifndef HAVE_STDINT_H typedef unsigned long uint32_t; +#endif #elif defined(__FreeBSD__) diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 39394a5..78180b0 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -74,7 +74,8 @@ static PyObject* node2tuple(node *n, /* node to convert */ SeqMaker mkseq, /* create sequence */ SeqInserter addelem, /* func. to add elem. in seq. */ - int lineno) /* include line numbers? */ + int lineno, /* include line numbers? */ + int col_offset) /* include column offsets? */ { if (n == NULL) { Py_INCREF(Py_None); @@ -95,7 +96,7 @@ node2tuple(node *n, /* node to convert */ } (void) addelem(v, 0, w); for (i = 0; i < NCH(n); i++) { - w = node2tuple(CHILD(n, i), mkseq, addelem, lineno); + w = node2tuple(CHILD(n, i), mkseq, addelem, lineno, col_offset); if (w == NULL) { Py_DECREF(v); return ((PyObject*) NULL); @@ -108,12 +109,14 @@ node2tuple(node *n, /* node to convert */ return (v); } else if (ISTERMINAL(TYPE(n))) { - PyObject *result = mkseq(2 + lineno); + PyObject *result = mkseq(2 + lineno + col_offset); if (result != NULL) { (void) addelem(result, 0, PyInt_FromLong(TYPE(n))); (void) addelem(result, 1, PyString_FromString(STR(n))); if (lineno == 1) (void) addelem(result, 2, PyInt_FromLong(n->n_lineno)); + if (col_offset == 1) + (void) addelem(result, 3, PyInt_FromLong(n->n_col_offset)); } return (result); } @@ -289,29 +292,35 @@ static PyObject* parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw) { PyObject *line_option = 0; + PyObject *col_option = 0; PyObject *res = 0; int ok; - static char *keywords[] = {"ast", "line_info", NULL}; + static char *keywords[] = {"ast", "line_info", "col_info", NULL}; if (self == NULL) { - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2tuple", keywords, - &PyST_Type, &self, &line_option); + ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2tuple", keywords, + &PyST_Type, &self, &line_option, + &col_option); } else - ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1], - &line_option); + ok = PyArg_ParseTupleAndKeywords(args, kw, "|OO:totuple", &keywords[1], + &line_option, &col_option); if (ok != 0) { int lineno = 0; + int col_offset = 0; if (line_option != NULL) { lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0; } + if (col_option != NULL) { + col_offset = (PyObject_IsTrue(col_option) != 0) ? 1 : 0; + } /* * Convert ST into a tuple representation. Use Guido's function, * since it's known to work already. */ res = node2tuple(((PyST_Object*)self)->st_node, - PyTuple_New, PyTuple_SetItem, lineno); + PyTuple_New, PyTuple_SetItem, lineno, col_offset); } return (res); } @@ -327,28 +336,34 @@ static PyObject* parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw) { PyObject *line_option = 0; + PyObject *col_option = 0; PyObject *res = 0; int ok; - static char *keywords[] = {"ast", "line_info", NULL}; + static char *keywords[] = {"ast", "line_info", "col_info", NULL}; if (self == NULL) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2list", keywords, - &PyST_Type, &self, &line_option); + ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2list", keywords, + &PyST_Type, &self, &line_option, + &col_option); else - ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1], - &line_option); + ok = PyArg_ParseTupleAndKeywords(args, kw, "|OO:tolist", &keywords[1], + &line_option, &col_option); if (ok) { int lineno = 0; + int col_offset = 0; if (line_option != 0) { lineno = PyObject_IsTrue(line_option) ? 1 : 0; } + if (col_option != NULL) { + col_offset = (PyObject_IsTrue(col_option) != 0) ? 1 : 0; + } /* * Convert ST into a tuple representation. Use Guido's function, * since it's known to work already. */ res = node2tuple(self->st_node, - PyList_New, PyList_SetItem, lineno); + PyList_New, PyList_SetItem, lineno, col_offset); } return (res); } diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 5c67be6..3260c3d 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -792,7 +792,7 @@ time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr) /* XXX endianness */ __int64 out; out = time_in + secs_between_epochs; - out = out * 10000000 + nsec_in; + out = out * 10000000 + nsec_in / 100; memcpy(out_ptr, &out, sizeof(out)); } @@ -828,6 +828,106 @@ attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *resul return 0; } +/* Emulate GetFileAttributesEx[AW] on Windows 95 */ +static int checked = 0; +static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID); +static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID); +static void +check_gfax() +{ + HINSTANCE hKernel32; + if (checked) + return; + checked = 1; + hKernel32 = GetModuleHandle("KERNEL32"); + *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA"); + *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW"); +} + +static BOOL WINAPI +Py_GetFileAttributesExA(LPCSTR pszFile, + GET_FILEEX_INFO_LEVELS level, + LPVOID pv) +{ + BOOL result; + HANDLE hFindFile; + WIN32_FIND_DATAA FileData; + LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv; + /* First try to use the system's implementation, if that is + available and either succeeds to gives an error other than + that it isn't implemented. */ + check_gfax(); + if (gfaxa) { + result = gfaxa(pszFile, level, pv); + if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return result; + } + /* It's either not present, or not implemented. + Emulate using FindFirstFile. */ + if (level != GetFileExInfoStandard) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + /* Use GetFileAttributes to validate that the file name + does not contain wildcards (which FindFirstFile would + accept). */ + if (GetFileAttributesA(pszFile) == 0xFFFFFFFF) + return FALSE; + hFindFile = FindFirstFileA(pszFile, &FileData); + if (hFindFile == INVALID_HANDLE_VALUE) + return FALSE; + FindClose(hFindFile); + pfad->dwFileAttributes = FileData.dwFileAttributes; + pfad->ftCreationTime = FileData.ftCreationTime; + pfad->ftLastAccessTime = FileData.ftLastAccessTime; + pfad->ftLastWriteTime = FileData.ftLastWriteTime; + pfad->nFileSizeHigh = FileData.nFileSizeHigh; + pfad->nFileSizeLow = FileData.nFileSizeLow; + return TRUE; +} + +static BOOL WINAPI +Py_GetFileAttributesExW(LPCWSTR pszFile, + GET_FILEEX_INFO_LEVELS level, + LPVOID pv) +{ + BOOL result; + HANDLE hFindFile; + WIN32_FIND_DATAW FileData; + LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv; + /* First try to use the system's implementation, if that is + available and either succeeds to gives an error other than + that it isn't implemented. */ + check_gfax(); + if (gfaxa) { + result = gfaxw(pszFile, level, pv); + if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return result; + } + /* It's either not present, or not implemented. + Emulate using FindFirstFile. */ + if (level != GetFileExInfoStandard) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + /* Use GetFileAttributes to validate that the file name + does not contain wildcards (which FindFirstFile would + accept). */ + if (GetFileAttributesW(pszFile) == 0xFFFFFFFF) + return FALSE; + hFindFile = FindFirstFileW(pszFile, &FileData); + if (hFindFile == INVALID_HANDLE_VALUE) + return FALSE; + FindClose(hFindFile); + pfad->dwFileAttributes = FileData.dwFileAttributes; + pfad->ftCreationTime = FileData.ftCreationTime; + pfad->ftLastAccessTime = FileData.ftLastAccessTime; + pfad->ftLastWriteTime = FileData.ftLastWriteTime; + pfad->nFileSizeHigh = FileData.nFileSizeHigh; + pfad->nFileSizeLow = FileData.nFileSizeLow; + return TRUE; +} + static int win32_stat(const char* path, struct win32_stat *result) { @@ -835,7 +935,7 @@ win32_stat(const char* path, struct win32_stat *result) int code; char *dot; /* XXX not supported on Win95 and NT 3.x */ - if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) { + if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ errno = 0; @@ -863,7 +963,7 @@ win32_wstat(const wchar_t* path, struct win32_stat *result) const wchar_t *dot; WIN32_FILE_ATTRIBUTE_DATA info; /* XXX not supported on Win95 and NT 3.x */ - if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) { + if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ errno = 0; @@ -2458,7 +2558,8 @@ posix_utime(PyObject *self, PyObject *args) wpath = PyUnicode_AS_UNICODE(obwpath); Py_BEGIN_ALLOW_THREADS hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0, - NULL, OPEN_EXISTING, 0, NULL); + NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, NULL); Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) return win32_error_unicode("utime", wpath); @@ -2473,7 +2574,8 @@ posix_utime(PyObject *self, PyObject *args) return NULL; Py_BEGIN_ALLOW_THREADS hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0, - NULL, OPEN_EXISTING, 0, NULL); + NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, NULL); Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) { win32_error("utime", apath); @@ -2501,11 +2603,11 @@ posix_utime(PyObject *self, PyObject *args) if (extract_time(PyTuple_GET_ITEM(arg, 0), &atimesec, &ausec) == -1) goto done; - time_t_to_FILE_TIME(atimesec, ausec, &atime); + time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime); if (extract_time(PyTuple_GET_ITEM(arg, 1), &mtimesec, &musec) == -1) goto done; - time_t_to_FILE_TIME(mtimesec, musec, &mtime); + time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime); } if (!SetFileTime(hFile, NULL, &atime, &mtime)) { /* Avoid putting the file name into the error here, @@ -5585,17 +5687,53 @@ Return a string representing the path to which the symbolic link points."); static PyObject * posix_readlink(PyObject *self, PyObject *args) { + PyObject* v; char buf[MAXPATHLEN]; char *path; int n; - if (!PyArg_ParseTuple(args, "s:readlink", &path)) +#ifdef Py_USING_UNICODE + int arg_is_unicode = 0; +#endif + + if (!PyArg_ParseTuple(args, "et:readlink", + Py_FileSystemDefaultEncoding, &path)) return NULL; +#ifdef Py_USING_UNICODE + v = PySequence_GetItem(args, 0); + if (v == NULL) return NULL; + + if (PyUnicode_Check(v)) { + arg_is_unicode = 1; + } + Py_DECREF(v); +#endif + Py_BEGIN_ALLOW_THREADS n = readlink(path, buf, (int) sizeof buf); Py_END_ALLOW_THREADS if (n < 0) return posix_error_with_filename(path); - return PyString_FromStringAndSize(buf, n); + + v = PyString_FromStringAndSize(buf, n); +#ifdef Py_USING_UNICODE + if (arg_is_unicode) { + PyObject *w; + + w = PyUnicode_FromEncodedObject(v, + Py_FileSystemDefaultEncoding, + "strict"); + if (w != NULL) { + Py_DECREF(v); + v = w; + } + else { + /* fall back to the original byte string, as + discussed in patch #683592 */ + PyErr_Clear(); + } + } +#endif + return v; } #endif /* HAVE_READLINK */ @@ -7877,7 +8015,7 @@ win32_urandom(PyObject *self, PyObject *args) pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress( hAdvAPI32, "CryptGenRandom"); - if (pCryptAcquireContext == NULL) + if (pCryptGenRandom == NULL) return PyErr_Format(PyExc_NotImplementedError, "CryptGenRandom not found"); @@ -8617,3 +8755,4 @@ INITFUNC(void) } #endif + diff --git a/Modules/readline.c b/Modules/readline.c index 92f2d1f..853874b 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -768,10 +768,16 @@ readline_until_enter_or_signal(char *prompt, int *signal) while (!has_input) { struct timeval timeout = {0, 100000}; /* 0.1 seconds */ + + /* [Bug #1552726] Only limit the pause if an input hook has been + defined. */ + struct timeval *timeoutp = NULL; + if (PyOS_InputHook) + timeoutp = &timeout; FD_SET(fileno(rl_instream), &selectset); /* select resets selectset if no input was available */ has_input = select(fileno(rl_instream) + 1, &selectset, - NULL, NULL, &timeout); + NULL, NULL, timeoutp); if(PyOS_InputHook) PyOS_InputHook(); } diff --git a/Modules/resource.c b/Modules/resource.c index fe6f3b6..d38c660 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -298,6 +298,10 @@ initresource(void) PyModule_AddIntConstant(m, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK); #endif +#ifdef RLIMIT_SBSIZE + PyModule_AddIntConstant(m, "RLIMIT_SBSIZE", RLIMIT_SBSIZE); +#endif + #ifdef RUSAGE_SELF PyModule_AddIntConstant(m, "RUSAGE_SELF", RUSAGE_SELF); #endif diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index f03b34c..c9f0388 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -364,19 +364,16 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM #define sockaddr_l2 sockaddr_l2cap #define sockaddr_rc sockaddr_rfcomm -#define _BT_SOCKADDR_MEMB(s, proto) &((s)->sock_addr) #define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb) #define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb) #elif defined(__NetBSD__) #define sockaddr_l2 sockaddr_bt #define sockaddr_rc sockaddr_bt #define sockaddr_sco sockaddr_bt -#define _BT_SOCKADDR_MEMB(s, proto) &((s)->sock_addr) #define _BT_L2_MEMB(sa, memb) ((sa)->bt_##memb) #define _BT_RC_MEMB(sa, memb) ((sa)->bt_##memb) #define _BT_SCO_MEMB(sa, memb) ((sa)->bt_##memb) #else -#define _BT_SOCKADDR_MEMB(s, proto) (&((s)->sock_addr).bt_##proto) #define _BT_L2_MEMB(sa, memb) ((sa)->l2_##memb) #define _BT_RC_MEMB(sa, memb) ((sa)->rc_##memb) #define _BT_SCO_MEMB(sa, memb) ((sa)->sco_##memb) @@ -388,6 +385,8 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #define SEGMENT_SIZE (32 * 1024 -1) #endif +#define SAS2SA(x) ((struct sockaddr *)(x)) + /* * Constants for getnameinfo() */ @@ -1174,7 +1173,7 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto) static int getsockaddrarg(PySocketSockObject *s, PyObject *args, - struct sockaddr **addr_ret, int *len_ret) + struct sockaddr *addr_ret, int *len_ret) { switch (s->sock_family) { @@ -1184,9 +1183,10 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, struct sockaddr_un* addr; char *path; int len; - addr = (struct sockaddr_un*)&(s->sock_addr).un; if (!PyArg_Parse(args, "t#", &path, &len)) return 0; + + addr = (struct sockaddr_un*)addr_ret; #ifdef linux if (len > 0 && path[0] == 0) { /* Linux abstract namespace extension */ @@ -1209,7 +1209,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } addr->sun_family = s->sock_family; memcpy(addr->sun_path, path, len); - *addr_ret = (struct sockaddr *) addr; #if defined(PYOS_OS2) *len_ret = sizeof(*addr); #else @@ -1224,7 +1223,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, { struct sockaddr_nl* addr; int pid, groups; - addr = (struct sockaddr_nl *)&(s->sock_addr).nl; + addr = (struct sockaddr_nl *)addr_ret; if (!PyTuple_Check(args)) { PyErr_Format( PyExc_TypeError, @@ -1238,7 +1237,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, addr->nl_family = AF_NETLINK; addr->nl_pid = pid; addr->nl_groups = groups; - *addr_ret = (struct sockaddr *) addr; *len_ret = sizeof(*addr); return 1; } @@ -1249,7 +1247,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, struct sockaddr_in* addr; char *host; int port, result; - addr=(struct sockaddr_in*)&(s->sock_addr).in; if (!PyTuple_Check(args)) { PyErr_Format( PyExc_TypeError, @@ -1261,6 +1258,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, if (!PyArg_ParseTuple(args, "eti:getsockaddrarg", "idna", &host, &port)) return 0; + addr=(struct sockaddr_in*)addr_ret; result = setipaddr(host, (struct sockaddr *)addr, sizeof(*addr), AF_INET); PyMem_Free(host); @@ -1268,7 +1266,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 0; addr->sin_family = AF_INET; addr->sin_port = htons((short)port); - *addr_ret = (struct sockaddr *) addr; *len_ret = sizeof *addr; return 1; } @@ -1279,7 +1276,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, struct sockaddr_in6* addr; char *host; int port, flowinfo, scope_id, result; - addr = (struct sockaddr_in6*)&(s->sock_addr).in6; flowinfo = scope_id = 0; if (!PyTuple_Check(args)) { PyErr_Format( @@ -1294,6 +1290,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, &scope_id)) { return 0; } + addr = (struct sockaddr_in6*)addr_ret; result = setipaddr(host, (struct sockaddr *)addr, sizeof(*addr), AF_INET6); PyMem_Free(host); @@ -1303,7 +1300,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, addr->sin6_port = htons((short)port); addr->sin6_flowinfo = flowinfo; addr->sin6_scope_id = scope_id; - *addr_ret = (struct sockaddr *) addr; *len_ret = sizeof *addr; return 1; } @@ -1315,9 +1311,10 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, switch (s->sock_proto) { case BTPROTO_L2CAP: { - struct sockaddr_l2 *addr = (struct sockaddr_l2 *) _BT_SOCKADDR_MEMB(s, l2); + struct sockaddr_l2 *addr; char *straddr; + addr = (struct sockaddr_l2 *)addr_ret; _BT_L2_MEMB(addr, family) = AF_BLUETOOTH; if (!PyArg_ParseTuple(args, "si", &straddr, &_BT_L2_MEMB(addr, psm))) { @@ -1328,15 +1325,15 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, if (setbdaddr(straddr, &_BT_L2_MEMB(addr, bdaddr)) < 0) return 0; - *addr_ret = (struct sockaddr *) addr; *len_ret = sizeof *addr; return 1; } case BTPROTO_RFCOMM: { - struct sockaddr_rc *addr = (struct sockaddr_rc *) _BT_SOCKADDR_MEMB(s, rc); + struct sockaddr_rc *addr; char *straddr; + addr = (struct sockaddr_rc *)addr_ret; _BT_RC_MEMB(addr, family) = AF_BLUETOOTH; if (!PyArg_ParseTuple(args, "si", &straddr, &_BT_RC_MEMB(addr, channel))) { @@ -1347,16 +1344,16 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, if (setbdaddr(straddr, &_BT_RC_MEMB(addr, bdaddr)) < 0) return 0; - *addr_ret = (struct sockaddr *) addr; *len_ret = sizeof *addr; return 1; } #if !defined(__FreeBSD__) case BTPROTO_SCO: { - struct sockaddr_sco *addr = (struct sockaddr_sco *) _BT_SOCKADDR_MEMB(s, sco); + struct sockaddr_sco *addr; char *straddr; + addr = (struct sockaddr_sco *)addr_ret; _BT_SCO_MEMB(addr, family) = AF_BLUETOOTH; straddr = PyString_AsString(args); if (straddr == NULL) { @@ -1367,7 +1364,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, if (setbdaddr(straddr, &_BT_SCO_MEMB(addr, bdaddr)) < 0) return 0; - *addr_ret = (struct sockaddr *) addr; *len_ret = sizeof *addr; return 1; } @@ -1409,22 +1405,21 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, s->errorhandler(); return 0; } - addr = &(s->sock_addr.ll); - addr->sll_family = AF_PACKET; - addr->sll_protocol = htons((short)protoNumber); - addr->sll_ifindex = ifr.ifr_ifindex; - addr->sll_pkttype = pkttype; - addr->sll_hatype = hatype; if (halen > 8) { PyErr_SetString(PyExc_ValueError, "Hardware address must be 8 bytes or less"); return 0; } + addr = (struct sockaddr_ll*)addr_ret; + addr->sll_family = AF_PACKET; + addr->sll_protocol = htons((short)protoNumber); + addr->sll_ifindex = ifr.ifr_ifindex; + addr->sll_pkttype = pkttype; + addr->sll_hatype = hatype; if (halen != 0) { memcpy(&addr->sll_addr, haddr, halen); } addr->sll_halen = halen; - *addr_ret = (struct sockaddr *) addr; *len_ret = sizeof *addr; return 1; } @@ -1551,8 +1546,7 @@ sock_accept(PySocketSockObject *s) Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 0); if (!timeout) - newfd = accept(s->sock_fd, (struct sockaddr *) &addrbuf, - &addrlen); + newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen); Py_END_ALLOW_THREADS if (timeout == 1) { @@ -1578,7 +1572,7 @@ sock_accept(PySocketSockObject *s) SOCKETCLOSE(newfd); goto finally; } - addr = makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf, + addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, s->sock_proto); if (addr == NULL) goto finally; @@ -1819,14 +1813,14 @@ string of that length; otherwise it is an integer."); static PyObject * sock_bind(PySocketSockObject *s, PyObject *addro) { - struct sockaddr *addr; + sock_addr_t addrbuf; int addrlen; int res; - if (!getsockaddrarg(s, addro, &addr, &addrlen)) + if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) return NULL; Py_BEGIN_ALLOW_THREADS - res = bind(s->sock_fd, addr, addrlen); + res = bind(s->sock_fd, SAS2SA(&addrbuf), addrlen); Py_END_ALLOW_THREADS if (res < 0) return s->errorhandler(); @@ -1952,16 +1946,16 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen, static PyObject * sock_connect(PySocketSockObject *s, PyObject *addro) { - struct sockaddr *addr; + sock_addr_t addrbuf; int addrlen; int res; int timeout; - if (!getsockaddrarg(s, addro, &addr, &addrlen)) + if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) return NULL; Py_BEGIN_ALLOW_THREADS - res = internal_connect(s, addr, addrlen, &timeout); + res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout); Py_END_ALLOW_THREADS if (timeout == 1) { @@ -1986,16 +1980,16 @@ is a pair (host, port)."); static PyObject * sock_connect_ex(PySocketSockObject *s, PyObject *addro) { - struct sockaddr *addr; + sock_addr_t addrbuf; int addrlen; int res; int timeout; - if (!getsockaddrarg(s, addro, &addr, &addrlen)) + if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) return NULL; Py_BEGIN_ALLOW_THREADS - res = internal_connect(s, addr, addrlen, &timeout); + res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout); Py_END_ALLOW_THREADS /* Signals are not errors (though they may raise exceptions). Adapted @@ -2075,11 +2069,11 @@ sock_getsockname(PySocketSockObject *s) return NULL; memset(&addrbuf, 0, addrlen); Py_BEGIN_ALLOW_THREADS - res = getsockname(s->sock_fd, (struct sockaddr *) &addrbuf, &addrlen); + res = getsockname(s->sock_fd, SAS2SA(&addrbuf), &addrlen); Py_END_ALLOW_THREADS if (res < 0) return s->errorhandler(); - return makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf, addrlen, + return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, s->sock_proto); } @@ -2104,11 +2098,11 @@ sock_getpeername(PySocketSockObject *s) return NULL; memset(&addrbuf, 0, addrlen); Py_BEGIN_ALLOW_THREADS - res = getpeername(s->sock_fd, (struct sockaddr *) &addrbuf, &addrlen); + res = getpeername(s->sock_fd, SAS2SA(&addrbuf), &addrlen); Py_END_ALLOW_THREADS if (res < 0) return s->errorhandler(); - return makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf, addrlen, + return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, s->sock_proto); } @@ -2443,14 +2437,14 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags, #ifndef MS_WINDOWS #if defined(PYOS_OS2) && !defined(PYCC_GCC) n = recvfrom(s->sock_fd, cbuf, len, flags, - (struct sockaddr *) &addrbuf, &addrlen); + SAS2SA(&addrbuf), &addrlen); #else n = recvfrom(s->sock_fd, cbuf, len, flags, (void *) &addrbuf, &addrlen); #endif #else n = recvfrom(s->sock_fd, cbuf, len, flags, - (struct sockaddr *) &addrbuf, &addrlen); + SAS2SA(&addrbuf), &addrlen); #endif } Py_END_ALLOW_THREADS @@ -2464,7 +2458,7 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags, return -1; } - if (!(*addr = makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf, + if (!(*addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, s->sock_proto))) return -1; @@ -2664,7 +2658,7 @@ sock_sendto(PySocketSockObject *s, PyObject *args) { PyObject *addro; char *buf; - struct sockaddr *addr; + sock_addr_t addrbuf; int addrlen, len, n = -1, flags, timeout; flags = 0; @@ -2675,16 +2669,16 @@ sock_sendto(PySocketSockObject *s, PyObject *args) return NULL; } - if (!getsockaddrarg(s, addro, &addr, &addrlen)) - return NULL; - if (!IS_SELECTABLE(s)) return select_error(); + if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) + return NULL; + Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 1); if (!timeout) - n = sendto(s->sock_fd, buf, len, flags, addr, addrlen); + n = sendto(s->sock_fd, buf, len, flags, SAS2SA(&addrbuf), addrlen); Py_END_ALLOW_THREADS if (timeout == 1) { @@ -2973,10 +2967,9 @@ socket_gethostbyname(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s:gethostbyname", &name)) return NULL; - if (setipaddr(name, (struct sockaddr *)&addrbuf, sizeof(addrbuf), AF_INET) < 0) + if (setipaddr(name, SAS2SA(&addrbuf), sizeof(addrbuf), AF_INET) < 0) return NULL; - return makeipaddr((struct sockaddr *)&addrbuf, - sizeof(struct sockaddr_in)); + return makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in)); } PyDoc_STRVAR(gethostbyname_doc, diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index ae38c86..84f2422 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -114,7 +114,6 @@ typedef struct { int sock_family; /* Address family, e.g., AF_INET */ int sock_type; /* Socket type, e.g., SOCK_STREAM */ int sock_proto; /* Protocol type, usually 0 */ - sock_addr_t sock_addr; /* Socket address */ PyObject *(*errorhandler)(void); /* Error handler; checks errno, returns NULL and sets a Python exception */ diff --git a/Modules/threadmodule.c b/Modules/threadmodule.c index 3614296..baf6673 100644 --- a/Modules/threadmodule.c +++ b/Modules/threadmodule.c @@ -25,6 +25,7 @@ typedef struct { static void lock_dealloc(lockobject *self) { + assert(self->lock_lock); /* Unlock the lock so it's safe to free it */ PyThread_acquire_lock(self->lock_lock, 0); PyThread_release_lock(self->lock_lock); diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index a11a0b7..a30d30c 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -75,7 +75,7 @@ static PyMemberDef DB_members[] = { {NULL} }; -// forward declaration +/* forward declaration */ static PyTypeObject UCD_Type; static PyObject* |