[pypy-commit] pypy default: extend error checking on PyFile_AsFile
mattip
pypy.commits at gmail.com
Mon May 16 13:36:52 EDT 2016
Author: Matti Picus <matti.picus at gmail.com>
Branch:
Changeset: r84483:7ccd85b1ef9a
Date: 2016-05-16 20:35 +0300
http://bitbucket.org/pypy/pypy/changeset/7ccd85b1ef9a/
Log: extend error checking on PyFile_AsFile
diff --git a/pypy/module/cpyext/pyfile.py b/pypy/module/cpyext/pyfile.py
--- a/pypy/module/cpyext/pyfile.py
+++ b/pypy/module/cpyext/pyfile.py
@@ -1,10 +1,10 @@
from rpython.rtyper.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import (
- cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, build_type_checkers, fdopen,
- fileno)
+ cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, build_type_checkers, fdopen)
from pypy.module.cpyext.pyobject import PyObject
from pypy.module.cpyext.object import Py_PRINT_RAW
-from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.error import (OperationError, oefmt,
+ exception_from_saved_errno)
from pypy.module._file.interp_file import W_File
PyFile_Check, PyFile_CheckExact = build_type_checkers("File", W_File)
@@ -45,16 +45,29 @@
w_mode = space.wrap(rffi.charp2str(mode))
return space.call_method(space.builtin, 'file', w_filename, w_mode)
- at cpython_api([PyObject], FILEP, error=CANNOT_FAIL)
+ at cpython_api([PyObject], FILEP, error=lltype.nullptr(FILEP.TO))
def PyFile_AsFile(space, w_p):
"""Return the file object associated with p as a FILE*.
If the caller will ever use the returned FILE* object while
the GIL is released it must also call the PyFile_IncUseCount() and
PyFile_DecUseCount() functions as appropriate."""
+ if not PyFile_Check(space, w_p):
+ raise oefmt(space.w_IOError, 'first argument must be an open file')
assert isinstance(w_p, W_File)
- return fdopen(space.int_w(space.call_method(w_p, 'fileno')),
- w_p.mode)
+ try:
+ fd = space.int_w(space.call_method(w_p, 'fileno'))
+ mode = w_p.mode
+ except OperationError as e:
+ raise oefmt(space.w_IOError, 'could not call fileno')
+ if (fd < 0 or not mode or mode[0] not in ['r', 'w', 'a', 'U'] or
+ ('U' in mode and ('w' in mode or 'a' in mode))):
+ raise oefmt(space.w_IOError, 'invalid fileno or mode')
+ ret = fdopen(fd, mode)
+ if not ret:
+ raise exception_from_saved_errno(space, space.w_IOError)
+ return ret
+
@cpython_api([FILEP, CONST_STRING, CONST_STRING, rffi.VOIDP], PyObject)
def PyFile_FromFile(space, fp, name, mode, close):
More information about the pypy-commit
mailing list