[Python-checkins] r86341 - in python/branches/py3k: Include/fileutils.h Modules/main.c Objects/unicodeobject.c Python/fileutils.c
victor.stinner
python-checkins at python.org
Mon Nov 8 23:43:47 CET 2010
Author: victor.stinner
Date: Mon Nov 8 23:43:46 2010
New Revision: 86341
Log:
PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
* Add error_pos optional argument to _Py_wchar2char()
* PyUnicode_EncodeFS() raises a UnicodeEncodeError or MemoryError if
_Py_wchar2char() fails
Modified:
python/branches/py3k/Include/fileutils.h
python/branches/py3k/Modules/main.c
python/branches/py3k/Objects/unicodeobject.c
python/branches/py3k/Python/fileutils.c
Modified: python/branches/py3k/Include/fileutils.h
==============================================================================
--- python/branches/py3k/Include/fileutils.h (original)
+++ python/branches/py3k/Include/fileutils.h Mon Nov 8 23:43:46 2010
@@ -10,7 +10,8 @@
size_t *size);
PyAPI_FUNC(char*) _Py_wchar2char(
- const wchar_t *text);
+ const wchar_t *text,
+ size_t *error_pos);
#if defined(HAVE_STAT) && !defined(MS_WINDOWS)
PyAPI_FUNC(int) _Py_wstat(
Modified: python/branches/py3k/Modules/main.c
==============================================================================
--- python/branches/py3k/Modules/main.c (original)
+++ python/branches/py3k/Modules/main.c Mon Nov 8 23:43:46 2010
@@ -646,7 +646,7 @@
if (fp == NULL) {
char *cfilename_buffer;
const char *cfilename;
- cfilename_buffer = _Py_wchar2char(filename);
+ cfilename_buffer = _Py_wchar2char(filename, NULL);
if (cfilename_buffer != NULL)
cfilename = cfilename_buffer;
else
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Mon Nov 8 23:43:46 2010
@@ -1606,14 +1606,31 @@
wchar_t *wchar;
char *bytes;
PyObject *bytes_obj;
+ size_t error_pos;
wchar = PyUnicode_AsWideCharString(unicode, NULL);
if (wchar == NULL)
return NULL;
- bytes = _Py_wchar2char(wchar);
- PyMem_Free(wchar);
- if (bytes == NULL)
+ bytes = _Py_wchar2char(wchar, &error_pos);
+ if (bytes == NULL) {
+ if (error_pos != (size_t)-1) {
+ char *errmsg = strerror(errno);
+ PyObject *exc = NULL;
+ if (errmsg == NULL)
+ errmsg = "Py_wchar2char() failed";
+ raise_encode_exception(&exc,
+ "filesystemencoding",
+ PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode),
+ error_pos, error_pos+1,
+ errmsg);
+ Py_XDECREF(exc);
+ }
+ else
+ PyErr_NoMemory();
+ PyMem_Free(wchar);
return NULL;
+ }
+ PyMem_Free(wchar);
bytes_obj = PyBytes_FromString(bytes);
PyMem_Free(bytes);
Modified: python/branches/py3k/Python/fileutils.c
==============================================================================
--- python/branches/py3k/Python/fileutils.c (original)
+++ python/branches/py3k/Python/fileutils.c Mon Nov 8 23:43:46 2010
@@ -132,15 +132,21 @@
This function is the reverse of _Py_char2wchar().
Return a pointer to a newly allocated byte string (use PyMem_Free() to free
- the memory), or NULL on error (conversion error or memory error). */
+ the memory), or NULL on conversion or memory allocation error.
+
+ If error_pos is not NULL: *error_pos is the index of the invalid character
+ on conversion error, or (size_t)-1 otherwise. */
char*
-_Py_wchar2char(const wchar_t *text)
+_Py_wchar2char(const wchar_t *text, size_t *error_pos)
{
const size_t len = wcslen(text);
char *result = NULL, *bytes = NULL;
size_t i, size, converted;
wchar_t c, buf[2];
+ if (error_pos != NULL)
+ *error_pos = (size_t)-1;
+
/* The function works in two steps:
1. compute the length of the output buffer in bytes (size)
2. outputs the bytes */
@@ -168,6 +174,8 @@
if (converted == (size_t)-1) {
if (result != NULL)
PyMem_Free(result);
+ if (error_pos != NULL)
+ *error_pos = i;
return NULL;
}
if (bytes != NULL) {
@@ -208,7 +216,7 @@
{
int err;
char *fname;
- fname = _Py_wchar2char(path);
+ fname = _Py_wchar2char(path, NULL);
if (fname == NULL) {
errno = EINVAL;
return -1;
@@ -263,7 +271,7 @@
errno = EINVAL;
return NULL;
}
- cpath = _Py_wchar2char(path);
+ cpath = _Py_wchar2char(path, NULL);
if (cpath == NULL)
return NULL;
f = fopen(cpath, cmode);
@@ -317,7 +325,7 @@
int res;
size_t r1;
- cpath = _Py_wchar2char(path);
+ cpath = _Py_wchar2char(path, NULL);
if (cpath == NULL) {
errno = EINVAL;
return -1;
@@ -361,7 +369,7 @@
wchar_t *wresolved_path;
char *res;
size_t r;
- cpath = _Py_wchar2char(path);
+ cpath = _Py_wchar2char(path, NULL);
if (cpath == NULL) {
errno = EINVAL;
return NULL;
More information about the Python-checkins
mailing list