Issue #3705: py3k aborts if "-c" or "-m" is given a non-ascii value.

Reviewed by Benjamin Peterson.
This commit is contained in:
Antoine Pitrou 2008-09-06 20:46:58 +00:00
parent 693fc4604f
commit 5651eaa720
2 changed files with 35 additions and 19 deletions

View file

@ -12,6 +12,10 @@ What's New in Python 3.0 release candidate 1
Core and Builtins Core and Builtins
----------------- -----------------
- 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,
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

@ -4,6 +4,8 @@
#include "osdefs.h" #include "osdefs.h"
#include "import.h" #include "import.h"
#include <locale.h>
#ifdef __VMS #ifdef __VMS
#include <unixlib.h> #include <unixlib.h>
#endif #endif
@ -174,9 +176,9 @@ static void RunStartupFile(PyCompilerFlags *cf)
} }
static int RunModule(char *module, int set_argv0) static int RunModule(wchar_t *modname, int set_argv0)
{ {
PyObject *runpy, *runmodule, *runargs, *result; PyObject *module, *runpy, *runmodule, *runargs, *result;
runpy = PyImport_ImportModule("runpy"); runpy = PyImport_ImportModule("runpy");
if (runpy == NULL) { if (runpy == NULL) {
fprintf(stderr, "Could not import runpy module\n"); fprintf(stderr, "Could not import runpy module\n");
@ -188,12 +190,20 @@ static int RunModule(char *module, int set_argv0)
Py_DECREF(runpy); Py_DECREF(runpy);
return -1; return -1;
} }
runargs = Py_BuildValue("(si)", module, set_argv0); module = PyUnicode_FromWideChar(modname, wcslen(modname));
if (module == NULL) {
fprintf(stderr, "Could not convert module name to unicode\n");
Py_DECREF(runpy);
Py_DECREF(runmodule);
return -1;
}
runargs = Py_BuildValue("(Oi)", module, set_argv0);
if (runargs == NULL) { if (runargs == NULL) {
fprintf(stderr, fprintf(stderr,
"Could not create arguments for runpy._run_module_as_main\n"); "Could not create arguments for runpy._run_module_as_main\n");
Py_DECREF(runpy); Py_DECREF(runpy);
Py_DECREF(runmodule); Py_DECREF(runmodule);
Py_DECREF(module);
return -1; return -1;
} }
result = PyObject_Call(runmodule, runargs, NULL); result = PyObject_Call(runmodule, runargs, NULL);
@ -202,6 +212,7 @@ static int RunModule(char *module, int set_argv0)
} }
Py_DECREF(runpy); Py_DECREF(runpy);
Py_DECREF(runmodule); Py_DECREF(runmodule);
Py_DECREF(module);
Py_DECREF(runargs); Py_DECREF(runargs);
if (result == NULL) { if (result == NULL) {
return -1; return -1;
@ -227,7 +238,7 @@ static int RunMainFromImporter(wchar_t *filename)
Py_INCREF(argv0); Py_INCREF(argv0);
Py_DECREF(importer); Py_DECREF(importer);
sys_path = NULL; sys_path = NULL;
return RunModule("__main__", 0) != 0; return RunModule(L"__main__", 0) != 0;
} }
} }
Py_XDECREF(argv0); Py_XDECREF(argv0);
@ -278,7 +289,7 @@ Py_Main(int argc, wchar_t **argv)
int sts; int sts;
char *command = NULL; char *command = NULL;
wchar_t *filename = NULL; wchar_t *filename = NULL;
char *module = NULL; wchar_t *module = NULL;
FILE *fp = stdin; FILE *fp = stdin;
char *p; char *p;
int unbuffered = 0; int unbuffered = 0;
@ -288,6 +299,7 @@ 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;
@ -298,8 +310,17 @@ 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 = wcslen(_PyOS_optarg) + 2; size_t r1, r2;
size_t r2; 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. */
@ -308,10 +329,11 @@ Py_Main(int argc, wchar_t **argv)
Py_FatalError( Py_FatalError(
"not enough memory to copy -c argument"); "not enough memory to copy -c argument");
r2 = wcstombs(command, _PyOS_optarg, r1); r2 = wcstombs(command, _PyOS_optarg, r1);
if (r2 > r1-2) if (r2 > r1-1)
Py_FatalError( Py_FatalError(
"not enough memory to copy -c argument"); "not enough memory to copy -c argument");
strcat(command, "\n"); strcat(command, "\n");
setlocale(LC_ALL, oldloc);
break; break;
} }
@ -319,16 +341,7 @@ Py_Main(int argc, wchar_t **argv)
/* -m is the last option; following arguments /* -m is the last option; following arguments
that look like options are left for the that look like options are left for the
module to interpret. */ module to interpret. */
size_t r1 = wcslen(_PyOS_optarg) + 1; module = _PyOS_optarg;
size_t r2;
module = (char *)malloc(r1);
if (module == NULL)
Py_FatalError(
"not enough memory to copy -m argument");
r2 = wcstombs(module, _PyOS_optarg, r1);
if (r2 >= r1)
Py_FatalError(
"not enough memory to copy -m argument");
break; break;
} }
@ -534,7 +547,6 @@ Py_Main(int argc, wchar_t **argv)
free(command); free(command);
} else if (module) { } else if (module) {
sts = RunModule(module, 1); sts = RunModule(module, 1);
free(module);
} }
else { else {