#3705: Fix crash when given a non-ascii value on the command line for the "-c" and "-m" parameters

Second part, for Windows.

Reviewed by Antoine Pitrou
This commit is contained in:
Amaury Forgeot d'Arc 2008-09-09 07:04:36 +00:00
parent f7bfcfbb68
commit 14b785192b
4 changed files with 33 additions and 27 deletions

View file

@ -135,6 +135,12 @@ class CmdLineTest(unittest.TestCase):
self.exit_code('-c', 'pass'), self.exit_code('-c', 'pass'),
0) 0)
# Test handling of non-ascii data
command = "assert(ord('\xe9') == 0xe9)"
self.assertEqual(
self.exit_code('-c', command),
0)
def test_main(): def test_main():
test.support.run_unittest(CmdLineTest) test.support.run_unittest(CmdLineTest)

View file

@ -13,8 +13,7 @@ Core and Builtins
----------------- -----------------
- Issue #3705: fix crash when given a non-ascii value on the command line for - Issue #3705: fix crash when given a non-ascii value on the command line for
the "-c" and "-m" parameters. Now the behaviour is as expected under Linux, the "-c" and "-m" parameters.
although under Windows it fails at a later point.
- Issue #3279: Importing site at interpreter was failing silently because the - Issue #3279: Importing site at interpreter was failing silently because the
site module uses the open builtin which was not initialized at the time. site module uses the open builtin which was not initialized at the time.

View file

@ -287,7 +287,7 @@ Py_Main(int argc, wchar_t **argv)
{ {
int c; int c;
int sts; int sts;
char *command = NULL; wchar_t *command = NULL;
wchar_t *filename = NULL; wchar_t *filename = NULL;
wchar_t *module = NULL; wchar_t *module = NULL;
FILE *fp = stdin; FILE *fp = stdin;
@ -299,7 +299,6 @@ Py_Main(int argc, wchar_t **argv)
int version = 0; int version = 0;
int saw_unbuffered_flag = 0; int saw_unbuffered_flag = 0;
PyCompilerFlags cf; PyCompilerFlags cf;
char *oldloc;
cf.cf_flags = 0; cf.cf_flags = 0;
@ -310,30 +309,19 @@ Py_Main(int argc, wchar_t **argv)
while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) { while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
if (c == 'c') { if (c == 'c') {
size_t r1, r2; size_t len;
oldloc = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "");
r1 = wcslen(_PyOS_optarg);
r2 = wcstombs(NULL, _PyOS_optarg, r1);
if (r2 == (size_t) -1)
Py_FatalError(
"cannot convert character encoding of -c argument");
if (r2 > r1)
r1 = r2;
r1 += 2;
/* -c is the last option; following arguments /* -c is the last option; following arguments
that look like options are left for the that look like options are left for the
command to interpret. */ command to interpret. */
command = (char *)malloc(r1);
len = wcslen(_PyOS_optarg) + 1 + 1;
command = (wchar_t *)malloc(sizeof(wchar_t) * len);
if (command == NULL) if (command == NULL)
Py_FatalError( Py_FatalError(
"not enough memory to copy -c argument"); "not enough memory to copy -c argument");
r2 = wcstombs(command, _PyOS_optarg, r1); wcscpy(command, _PyOS_optarg);
if (r2 > r1-1) command[len - 2] = '\n';
Py_FatalError( command[len - 1] = 0;
"not enough memory to copy -c argument");
strcat(command, "\n");
setlocale(LC_ALL, oldloc);
break; break;
} }
@ -543,8 +531,18 @@ Py_Main(int argc, wchar_t **argv)
} }
if (command) { if (command) {
sts = PyRun_SimpleStringFlags(command, &cf) != 0; PyObject *commandObj = PyUnicode_FromUnicode(
command, wcslen(command));
free(command); free(command);
if (commandObj != NULL) {
sts = PyRun_SimpleStringFlags(
_PyUnicode_AsString(commandObj), &cf) != 0;
}
else {
PyErr_Print();
sts = 1;
}
Py_DECREF(commandObj);
} else if (module) { } else if (module) {
sts = RunModule(module, 1); sts = RunModule(module, 1);
} }

View file

@ -2804,6 +2804,7 @@ call_find_module(char *name, PyObject *path)
{ {
extern int fclose(FILE *); extern int fclose(FILE *);
PyObject *fob, *ret; PyObject *fob, *ret;
PyObject *pathobj;
struct filedescr *fdp; struct filedescr *fdp;
char pathname[MAXPATHLEN+1]; char pathname[MAXPATHLEN+1];
FILE *fp = NULL; FILE *fp = NULL;
@ -2847,9 +2848,9 @@ call_find_module(char *name, PyObject *path)
fob = Py_None; fob = Py_None;
Py_INCREF(fob); Py_INCREF(fob);
} }
ret = Py_BuildValue("Os(ssi)", pathobj = PyUnicode_DecodeFSDefault(pathname);
fob, pathname, fdp->suffix, fdp->mode, fdp->type); ret = Py_BuildValue("NN(ssi)",
Py_DECREF(fob); fob, pathobj, fdp->suffix, fdp->mode, fdp->type);
PyMem_FREE(found_encoding); PyMem_FREE(found_encoding);
return ret; return ret;
@ -2860,7 +2861,9 @@ imp_find_module(PyObject *self, PyObject *args)
{ {
char *name; char *name;
PyObject *path = NULL; PyObject *path = NULL;
if (!PyArg_ParseTuple(args, "s|O:find_module", &name, &path)) if (!PyArg_ParseTuple(args, "es|O:find_module",
Py_FileSystemDefaultEncoding, &name,
&path))
return NULL; return NULL;
return call_find_module(name, path); return call_find_module(name, path);
} }