mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
[ Bug #113803 ] [2.0b1 NT4.0] printing non asci char causes idle to abort
http://sourceforge.net/bugs/?func=detailbug&bug_id=113803&group_id=5470 Add Unicode support and error handling to AsString(). Both AsString() and Merge() now return NULL and set a proper Python exception condition when an error happens; Merge() and other callers of AsString() check for errors from AsString(). Also fixed cleanup in Merge() and Tkapp_Call() return cleanup code; the fv array was not necessarily completely initialized, causing calls to ckfree() with garbage arguments! (Also reindented some lines that were longer than 80 chars and reformatted some code that used an alien coding standard.)
This commit is contained in:
parent
476491396e
commit
2834b974b6
1 changed files with 86 additions and 44 deletions
|
@ -137,7 +137,7 @@ static PyThreadState *tcl_tstate = NULL;
|
||||||
PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
|
PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
|
||||||
|
|
||||||
#define LEAVE_TCL \
|
#define LEAVE_TCL \
|
||||||
tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
|
tcl_tstate = NULL; PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
|
||||||
|
|
||||||
#define ENTER_OVERLAP \
|
#define ENTER_OVERLAP \
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
@ -177,10 +177,10 @@ static PyThreadState *tcl_tstate = NULL;
|
||||||
#include <Events.h> /* For EventRecord */
|
#include <Events.h> /* For EventRecord */
|
||||||
|
|
||||||
typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
|
typedef int (*TclMacConvertEventPtr) (EventRecord *eventPtr);
|
||||||
void Tcl_MacSetEventProc (TclMacConvertEventPtr procPtr);
|
void Tcl_MacSetEventProc(TclMacConvertEventPtr procPtr);
|
||||||
int TkMacConvertEvent (EventRecord *eventPtr);
|
int TkMacConvertEvent(EventRecord *eventPtr);
|
||||||
|
|
||||||
staticforward int PyMacConvertEvent (EventRecord *eventPtr);
|
staticforward int PyMacConvertEvent(EventRecord *eventPtr);
|
||||||
|
|
||||||
#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
|
#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
|
||||||
#pragma import on
|
#pragma import on
|
||||||
|
@ -261,9 +261,25 @@ AsString(PyObject *value, PyObject *tmp)
|
||||||
{
|
{
|
||||||
if (PyString_Check(value))
|
if (PyString_Check(value))
|
||||||
return PyString_AsString(value);
|
return PyString_AsString(value);
|
||||||
|
else if (PyUnicode_Check(value)) {
|
||||||
|
PyObject *v = PyUnicode_AsUTF8String(value);
|
||||||
|
if (v == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (PyList_Append(tmp, v) != 0) {
|
||||||
|
Py_DECREF(v);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_DECREF(v);
|
||||||
|
return PyString_AsString(v);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
PyObject *v = PyObject_Str(value);
|
PyObject *v = PyObject_Str(value);
|
||||||
PyList_Append(tmp, v);
|
if (v == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (PyList_Append(tmp, v) != 0) {
|
||||||
|
Py_DECREF(v);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
return PyString_AsString(v);
|
return PyString_AsString(v);
|
||||||
}
|
}
|
||||||
|
@ -281,7 +297,7 @@ Merge(PyObject *args)
|
||||||
char **argv = NULL;
|
char **argv = NULL;
|
||||||
int fvStore[ARGSZ];
|
int fvStore[ARGSZ];
|
||||||
int *fv = NULL;
|
int *fv = NULL;
|
||||||
int argc = 0, i;
|
int argc = 0, fvc = 0, i;
|
||||||
char *res = NULL;
|
char *res = NULL;
|
||||||
|
|
||||||
if (!(tmp = PyList_New(0)))
|
if (!(tmp = PyList_New(0)))
|
||||||
|
@ -296,7 +312,8 @@ Merge(PyObject *args)
|
||||||
else if (!PyTuple_Check(args)) {
|
else if (!PyTuple_Check(args)) {
|
||||||
argc = 1;
|
argc = 1;
|
||||||
fv[0] = 0;
|
fv[0] = 0;
|
||||||
argv[0] = AsString(args, tmp);
|
if (!(argv[0] = AsString(args, tmp)))
|
||||||
|
goto finally;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
argc = PyTuple_Size(args);
|
argc = PyTuple_Size(args);
|
||||||
|
@ -316,6 +333,7 @@ Merge(PyObject *args)
|
||||||
fv[i] = 1;
|
fv[i] = 1;
|
||||||
if (!(argv[i] = Merge(v)))
|
if (!(argv[i] = Merge(v)))
|
||||||
goto finally;
|
goto finally;
|
||||||
|
fvc++;
|
||||||
}
|
}
|
||||||
else if (v == Py_None) {
|
else if (v == Py_None) {
|
||||||
argc = i;
|
argc = i;
|
||||||
|
@ -323,14 +341,18 @@ Merge(PyObject *args)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fv[i] = 0;
|
fv[i] = 0;
|
||||||
argv[i] = AsString(v, tmp);
|
if (!(argv[i] = AsString(v, tmp)))
|
||||||
|
goto finally;
|
||||||
|
fvc++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = Tcl_Merge(argc, argv);
|
res = Tcl_Merge(argc, argv);
|
||||||
|
if (res == NULL)
|
||||||
|
PyErr_SetString(Tkinter_TclError, "merge failed");
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
for (i = 0; i < argc; i++)
|
for (i = 0; i < fvc; i++)
|
||||||
if (fv[i]) {
|
if (fv[i]) {
|
||||||
ckfree(argv[i]);
|
ckfree(argv[i]);
|
||||||
}
|
}
|
||||||
|
@ -507,11 +529,11 @@ AsObj(PyObject *value)
|
||||||
else if (PyUnicode_Check(value)) {
|
else if (PyUnicode_Check(value)) {
|
||||||
#if TKMAJORMINOR <= 8001
|
#if TKMAJORMINOR <= 8001
|
||||||
/* In Tcl 8.1 we must use UTF-8 */
|
/* In Tcl 8.1 we must use UTF-8 */
|
||||||
PyObject* utf8 = PyUnicode_AsUTF8String (value);
|
PyObject* utf8 = PyUnicode_AsUTF8String(value);
|
||||||
if (!utf8)
|
if (!utf8)
|
||||||
return 0;
|
return 0;
|
||||||
result = Tcl_NewStringObj (PyString_AS_STRING (utf8),
|
result = Tcl_NewStringObj(PyString_AS_STRING(utf8),
|
||||||
PyString_GET_SIZE (utf8));
|
PyString_GET_SIZE(utf8));
|
||||||
Py_DECREF(utf8);
|
Py_DECREF(utf8);
|
||||||
return result;
|
return result;
|
||||||
#else /* TKMAJORMINOR > 8001 */
|
#else /* TKMAJORMINOR > 8001 */
|
||||||
|
@ -519,7 +541,7 @@ AsObj(PyObject *value)
|
||||||
if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
|
if (sizeof(Py_UNICODE) != sizeof(Tcl_UniChar)) {
|
||||||
/* XXX Should really test this at compile time */
|
/* XXX Should really test this at compile time */
|
||||||
PyErr_SetString(PyExc_SystemError,
|
PyErr_SetString(PyExc_SystemError,
|
||||||
"Py_UNICODE and Tcl_UniChar differ in size");
|
"Py_UNICODE and Tcl_UniChar differ in size");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
|
return Tcl_NewUnicodeObj(PyUnicode_AS_UNICODE(value),
|
||||||
|
@ -609,8 +631,8 @@ Tkapp_Call(PyObject *self, PyObject *args)
|
||||||
p = strchr(p, '\0');
|
p = strchr(p, '\0');
|
||||||
res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
|
res = PyUnicode_DecodeUTF8(s, (int)(p-s), "strict");
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
res = PyString_FromStringAndSize(s, (int)(p-s));
|
res = PyString_FromStringAndSize(s, (int)(p-s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -636,7 +658,7 @@ Tkapp_Call(PyObject *self, PyObject *args)
|
||||||
char **argv = NULL;
|
char **argv = NULL;
|
||||||
int fvStore[ARGSZ];
|
int fvStore[ARGSZ];
|
||||||
int *fv = NULL;
|
int *fv = NULL;
|
||||||
int argc = 0, i;
|
int argc = 0, fvc = 0, i;
|
||||||
PyObject *res = NULL; /* except this has a different type */
|
PyObject *res = NULL; /* except this has a different type */
|
||||||
Tcl_CmdInfo info; /* and this is added */
|
Tcl_CmdInfo info; /* and this is added */
|
||||||
Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
|
Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
|
||||||
|
@ -653,7 +675,8 @@ Tkapp_Call(PyObject *self, PyObject *args)
|
||||||
else if (!PyTuple_Check(args)) {
|
else if (!PyTuple_Check(args)) {
|
||||||
argc = 1;
|
argc = 1;
|
||||||
fv[0] = 0;
|
fv[0] = 0;
|
||||||
argv[0] = AsString(args, tmp);
|
if (!(argv[0] = AsString(args, tmp)))
|
||||||
|
goto finally;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
argc = PyTuple_Size(args);
|
argc = PyTuple_Size(args);
|
||||||
|
@ -673,6 +696,7 @@ Tkapp_Call(PyObject *self, PyObject *args)
|
||||||
fv[i] = 1;
|
fv[i] = 1;
|
||||||
if (!(argv[i] = Merge(v)))
|
if (!(argv[i] = Merge(v)))
|
||||||
goto finally;
|
goto finally;
|
||||||
|
fvc++;
|
||||||
}
|
}
|
||||||
else if (v == Py_None) {
|
else if (v == Py_None) {
|
||||||
argc = i;
|
argc = i;
|
||||||
|
@ -680,7 +704,9 @@ Tkapp_Call(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fv[i] = 0;
|
fv[i] = 0;
|
||||||
argv[i] = AsString(v, tmp);
|
if (!(argv[i] = AsString(v, tmp)))
|
||||||
|
goto finally;
|
||||||
|
fvc++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -725,7 +751,7 @@ Tkapp_Call(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
/* Copied from Merge() again */
|
/* Copied from Merge() again */
|
||||||
finally:
|
finally:
|
||||||
for (i = 0; i < argc; i++)
|
for (i = 0; i < fvc; i++)
|
||||||
if (fv[i]) {
|
if (fv[i]) {
|
||||||
ckfree(argv[i]);
|
ckfree(argv[i]);
|
||||||
}
|
}
|
||||||
|
@ -753,10 +779,7 @@ Tkapp_GlobalCall(PyObject *self, PyObject *args)
|
||||||
PyObject *res = NULL;
|
PyObject *res = NULL;
|
||||||
|
|
||||||
cmd = Merge(args);
|
cmd = Merge(args);
|
||||||
if (!cmd)
|
if (cmd) {
|
||||||
PyErr_SetString(Tkinter_TclError, "merge failed");
|
|
||||||
|
|
||||||
else {
|
|
||||||
int err;
|
int err;
|
||||||
ENTER_TCL
|
ENTER_TCL
|
||||||
err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
|
err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
|
||||||
|
@ -766,10 +789,8 @@ Tkapp_GlobalCall(PyObject *self, PyObject *args)
|
||||||
else
|
else
|
||||||
res = PyString_FromString(Tkapp_Result(self));
|
res = PyString_FromString(Tkapp_Result(self));
|
||||||
LEAVE_OVERLAP_TCL
|
LEAVE_OVERLAP_TCL
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd)
|
|
||||||
ckfree(cmd);
|
ckfree(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -892,14 +913,19 @@ SetVar(PyObject *self, PyObject *args, int flags)
|
||||||
if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
|
if (PyArg_ParseTuple(args, "sO:setvar", &name1, &newValue)) {
|
||||||
/* XXX Merge? */
|
/* XXX Merge? */
|
||||||
s = AsString(newValue, tmp);
|
s = AsString(newValue, tmp);
|
||||||
|
if (s == NULL)
|
||||||
|
return NULL;
|
||||||
ENTER_TCL
|
ENTER_TCL
|
||||||
ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
|
ok = Tcl_SetVar(Tkapp_Interp(self), name1, s, flags);
|
||||||
LEAVE_TCL
|
LEAVE_TCL
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
if (PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) {
|
if (PyArg_ParseTuple(args, "ssO:setvar",
|
||||||
s = AsString (newValue, tmp);
|
&name1, &name2, &newValue)) {
|
||||||
|
s = AsString(newValue, tmp);
|
||||||
|
if (s == NULL)
|
||||||
|
return NULL;
|
||||||
ENTER_TCL
|
ENTER_TCL
|
||||||
ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
|
ok = Tcl_SetVar2(Tkapp_Interp(self), name1, name2,
|
||||||
s, flags);
|
s, flags);
|
||||||
|
@ -1192,8 +1218,6 @@ Tkapp_Merge(PyObject *self, PyObject *args)
|
||||||
res = PyString_FromString(s);
|
res = PyString_FromString(s);
|
||||||
ckfree(s);
|
ckfree(s);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
PyErr_SetString(Tkinter_TclError, "merge failed");
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1225,7 +1249,8 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
|
PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
|
||||||
PyObject *self, *func, *arg, *res, *tmp;
|
PyObject *self, *func, *arg, *res, *tmp;
|
||||||
int i;
|
int i, rv;
|
||||||
|
char *s;
|
||||||
|
|
||||||
ENTER_PYTHON
|
ENTER_PYTHON
|
||||||
|
|
||||||
|
@ -1257,13 +1282,21 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
|
||||||
return PythonCmd_Error(interp);
|
return PythonCmd_Error(interp);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tcl_SetResult(Tkapp_Interp(self), AsString(res, tmp), TCL_VOLATILE);
|
s = AsString(res, tmp);
|
||||||
|
if (s == NULL) {
|
||||||
|
rv = PythonCmd_Error(interp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Tcl_SetResult(Tkapp_Interp(self), s, TCL_VOLATILE);
|
||||||
|
rv = TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
Py_DECREF(tmp);
|
Py_DECREF(tmp);
|
||||||
|
|
||||||
LEAVE_PYTHON
|
LEAVE_PYTHON
|
||||||
|
|
||||||
return TCL_OK;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1417,7 +1450,8 @@ Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
|
||||||
PyObject *file, *func;
|
PyObject *file, *func;
|
||||||
int mask, tfile;
|
int mask, tfile;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func))
|
if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
|
||||||
|
&file, &mask, &func))
|
||||||
return NULL;
|
return NULL;
|
||||||
tfile = PyObject_AsFileDescriptor(file);
|
tfile = PyObject_AsFileDescriptor(file);
|
||||||
if (tfile < 0)
|
if (tfile < 0)
|
||||||
|
@ -1604,7 +1638,8 @@ Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
|
||||||
PyObject *func;
|
PyObject *func;
|
||||||
TkttObject *v;
|
TkttObject *v;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func))
|
if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
|
||||||
|
&milliseconds, &func))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!PyCallable_Check(func)) {
|
if (!PyCallable_Check(func)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "bad argument list");
|
PyErr_SetString(PyExc_TypeError, "bad argument list");
|
||||||
|
@ -1801,8 +1836,8 @@ typedef struct {
|
||||||
static int
|
static int
|
||||||
_bump(FlattenContext* context, int size)
|
_bump(FlattenContext* context, int size)
|
||||||
{
|
{
|
||||||
/* expand tuple to hold (at least) size new items. return true if
|
/* expand tuple to hold (at least) size new items.
|
||||||
successful, false if an exception was raised*/
|
return true if successful, false if an exception was raised */
|
||||||
|
|
||||||
int maxsize = context->maxsize * 2;
|
int maxsize = context->maxsize * 2;
|
||||||
|
|
||||||
|
@ -1822,12 +1857,14 @@ _flatten1(FlattenContext* context, PyObject* item, int depth)
|
||||||
int i, size;
|
int i, size;
|
||||||
|
|
||||||
if (depth > 1000) {
|
if (depth > 1000) {
|
||||||
PyErr_SetString(PyExc_ValueError,"nesting too deep in _flatten");
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"nesting too deep in _flatten");
|
||||||
return 0;
|
return 0;
|
||||||
} else if (PyList_Check(item)) {
|
} else if (PyList_Check(item)) {
|
||||||
size = PyList_GET_SIZE(item);
|
size = PyList_GET_SIZE(item);
|
||||||
/* preallocate (assume no nesting) */
|
/* preallocate (assume no nesting) */
|
||||||
if (context->size + size > context->maxsize && !_bump(context, size))
|
if (context->size + size > context->maxsize &&
|
||||||
|
!_bump(context, size))
|
||||||
return 0;
|
return 0;
|
||||||
/* copy items to output tuple */
|
/* copy items to output tuple */
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
|
@ -1836,16 +1873,19 @@ _flatten1(FlattenContext* context, PyObject* item, int depth)
|
||||||
if (!_flatten1(context, o, depth + 1))
|
if (!_flatten1(context, o, depth + 1))
|
||||||
return 0;
|
return 0;
|
||||||
} else if (o != Py_None) {
|
} else if (o != Py_None) {
|
||||||
if (context->size + 1 > context->maxsize && !_bump(context, 1))
|
if (context->size + 1 > context->maxsize &&
|
||||||
|
!_bump(context, 1))
|
||||||
return 0;
|
return 0;
|
||||||
Py_INCREF(o);
|
Py_INCREF(o);
|
||||||
PyTuple_SET_ITEM(context->tuple, context->size++, o);
|
PyTuple_SET_ITEM(context->tuple,
|
||||||
|
context->size++, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (PyTuple_Check(item)) {
|
} else if (PyTuple_Check(item)) {
|
||||||
/* same, for tuples */
|
/* same, for tuples */
|
||||||
size = PyTuple_GET_SIZE(item);
|
size = PyTuple_GET_SIZE(item);
|
||||||
if (context->size + size > context->maxsize && !_bump(context, size))
|
if (context->size + size > context->maxsize &&
|
||||||
|
!_bump(context, size))
|
||||||
return 0;
|
return 0;
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
PyObject *o = PyTuple_GET_ITEM(item, i);
|
PyObject *o = PyTuple_GET_ITEM(item, i);
|
||||||
|
@ -1853,10 +1893,12 @@ _flatten1(FlattenContext* context, PyObject* item, int depth)
|
||||||
if (!_flatten1(context, o, depth + 1))
|
if (!_flatten1(context, o, depth + 1))
|
||||||
return 0;
|
return 0;
|
||||||
} else if (o != Py_None) {
|
} else if (o != Py_None) {
|
||||||
if (context->size + 1 > context->maxsize && !_bump(context, 1))
|
if (context->size + 1 > context->maxsize &&
|
||||||
|
!_bump(context, 1))
|
||||||
return 0;
|
return 0;
|
||||||
Py_INCREF(o);
|
Py_INCREF(o);
|
||||||
PyTuple_SET_ITEM(context->tuple, context->size++, o);
|
PyTuple_SET_ITEM(context->tuple,
|
||||||
|
context->size++, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue