antoine.pitrou
2008-09-06 20:46:58 UTC
Author: antoine.pitrou
Date: Sat Sep 6 22:46:58 2008
New Revision: 66269
Log:
Issue #3705: py3k aborts if "-c" or "-m" is given a non-ascii value.
Reviewed by Benjamin Peterson.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/main.c
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 6 22:46:58 2008
@@ -12,6 +12,10 @@
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
site module uses the open builtin which was not initialized at the time.
Modified: python/branches/py3k/Modules/main.c
==============================================================================
--- python/branches/py3k/Modules/main.c (original)
+++ python/branches/py3k/Modules/main.c Sat Sep 6 22:46:58 2008
@@ -4,6 +4,8 @@
#include "osdefs.h"
#include "import.h"
+#include <locale.h>
+
#ifdef __VMS
#include <unixlib.h>
#endif
@@ -174,9 +176,9 @@
}
-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");
if (runpy == NULL) {
fprintf(stderr, "Could not import runpy module\n");
@@ -188,12 +190,20 @@
Py_DECREF(runpy);
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) {
fprintf(stderr,
"Could not create arguments for runpy._run_module_as_main\n");
Py_DECREF(runpy);
Py_DECREF(runmodule);
+ Py_DECREF(module);
return -1;
}
result = PyObject_Call(runmodule, runargs, NULL);
@@ -202,6 +212,7 @@
}
Py_DECREF(runpy);
Py_DECREF(runmodule);
+ Py_DECREF(module);
Py_DECREF(runargs);
if (result == NULL) {
return -1;
@@ -227,7 +238,7 @@
Py_INCREF(argv0);
Py_DECREF(importer);
sys_path = NULL;
- return RunModule("__main__", 0) != 0;
+ return RunModule(L"__main__", 0) != 0;
}
}
Py_XDECREF(argv0);
@@ -278,7 +289,7 @@
int sts;
char *command = NULL;
wchar_t *filename = NULL;
- char *module = NULL;
+ wchar_t *module = NULL;
FILE *fp = stdin;
char *p;
int unbuffered = 0;
@@ -288,6 +299,7 @@
int version = 0;
int saw_unbuffered_flag = 0;
PyCompilerFlags cf;
+ char *oldloc;
cf.cf_flags = 0;
@@ -298,8 +310,17 @@
while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
if (c == 'c') {
- size_t r1 = wcslen(_PyOS_optarg) + 2;
- size_t r2;
+ size_t r1, 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
that look like options are left for the
command to interpret. */
@@ -308,10 +329,11 @@
Py_FatalError(
"not enough memory to copy -c argument");
r2 = wcstombs(command, _PyOS_optarg, r1);
- if (r2 > r1-2)
+ if (r2 > r1-1)
Py_FatalError(
"not enough memory to copy -c argument");
strcat(command, "\n");
+ setlocale(LC_ALL, oldloc);
break;
}
@@ -319,16 +341,7 @@
/* -m is the last option; following arguments
that look like options are left for the
module to interpret. */
- size_t r1 = wcslen(_PyOS_optarg) + 1;
- 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");
+ module = _PyOS_optarg;
break;
}
@@ -534,7 +547,6 @@
free(command);
} else if (module) {
sts = RunModule(module, 1);
- free(module);
}
else {
Date: Sat Sep 6 22:46:58 2008
New Revision: 66269
Log:
Issue #3705: py3k aborts if "-c" or "-m" is given a non-ascii value.
Reviewed by Benjamin Peterson.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/main.c
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 6 22:46:58 2008
@@ -12,6 +12,10 @@
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
site module uses the open builtin which was not initialized at the time.
Modified: python/branches/py3k/Modules/main.c
==============================================================================
--- python/branches/py3k/Modules/main.c (original)
+++ python/branches/py3k/Modules/main.c Sat Sep 6 22:46:58 2008
@@ -4,6 +4,8 @@
#include "osdefs.h"
#include "import.h"
+#include <locale.h>
+
#ifdef __VMS
#include <unixlib.h>
#endif
@@ -174,9 +176,9 @@
}
-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");
if (runpy == NULL) {
fprintf(stderr, "Could not import runpy module\n");
@@ -188,12 +190,20 @@
Py_DECREF(runpy);
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) {
fprintf(stderr,
"Could not create arguments for runpy._run_module_as_main\n");
Py_DECREF(runpy);
Py_DECREF(runmodule);
+ Py_DECREF(module);
return -1;
}
result = PyObject_Call(runmodule, runargs, NULL);
@@ -202,6 +212,7 @@
}
Py_DECREF(runpy);
Py_DECREF(runmodule);
+ Py_DECREF(module);
Py_DECREF(runargs);
if (result == NULL) {
return -1;
@@ -227,7 +238,7 @@
Py_INCREF(argv0);
Py_DECREF(importer);
sys_path = NULL;
- return RunModule("__main__", 0) != 0;
+ return RunModule(L"__main__", 0) != 0;
}
}
Py_XDECREF(argv0);
@@ -278,7 +289,7 @@
int sts;
char *command = NULL;
wchar_t *filename = NULL;
- char *module = NULL;
+ wchar_t *module = NULL;
FILE *fp = stdin;
char *p;
int unbuffered = 0;
@@ -288,6 +299,7 @@
int version = 0;
int saw_unbuffered_flag = 0;
PyCompilerFlags cf;
+ char *oldloc;
cf.cf_flags = 0;
@@ -298,8 +310,17 @@
while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
if (c == 'c') {
- size_t r1 = wcslen(_PyOS_optarg) + 2;
- size_t r2;
+ size_t r1, 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
that look like options are left for the
command to interpret. */
@@ -308,10 +329,11 @@
Py_FatalError(
"not enough memory to copy -c argument");
r2 = wcstombs(command, _PyOS_optarg, r1);
- if (r2 > r1-2)
+ if (r2 > r1-1)
Py_FatalError(
"not enough memory to copy -c argument");
strcat(command, "\n");
+ setlocale(LC_ALL, oldloc);
break;
}
@@ -319,16 +341,7 @@
/* -m is the last option; following arguments
that look like options are left for the
module to interpret. */
- size_t r1 = wcslen(_PyOS_optarg) + 1;
- 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");
+ module = _PyOS_optarg;
break;
}
@@ -534,7 +547,6 @@
free(command);
} else if (module) {
sts = RunModule(module, 1);
- free(module);
}
else {