bpo-25083: Python can sometimes create incorrect .pyc files (GH-8449)
Python 2 never checked for I/O error when reading .py files and
thus could mistake an I/O error for EOF and create incorrect .pyc
files.
This adds an check for this and aborts on an error.
diff --git a/Include/errcode.h b/Include/errcode.h
index becec80..5c5a0f7 100644
--- a/Include/errcode.h
+++ b/Include/errcode.h
@@ -29,6 +29,7 @@
#define E_EOFS 23 /* EOF in triple-quoted string */
#define E_EOLS 24 /* EOL in single-quoted string */
#define E_LINECONT 25 /* Unexpected characters after a line continuation */
+#define E_IO 26 /* I/O error */
#ifdef __cplusplus
}
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-25-22-47-19.bpo-25083.HT_hXh.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-25-22-47-19.bpo-25083.HT_hXh.rst
new file mode 100644
index 0000000..0dc44c4
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2018-07-25-22-47-19.bpo-25083.HT_hXh.rst
@@ -0,0 +1,2 @@
+Adding I/O error checking when reading .py files and aborting importing on
+error.
diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c
index 61bfb4e..c6e61df 100644
--- a/Parser/tokenizer.c
+++ b/Parser/tokenizer.c
@@ -1681,6 +1681,11 @@
PyTokenizer_Get(struct tok_state *tok, char **p_start, char **p_end)
{
int result = tok_get(tok, p_start, p_end);
+ if (tok->fp && ferror(tok->fp)) {
+ clearerr(tok->fp);
+ result = ERRORTOKEN;
+ tok->done = E_IO;
+ }
if (tok->decoding_erred) {
result = ERRORTOKEN;
tok->done = E_DECODE;
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 5707c9f..2c9f55f 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1654,6 +1654,9 @@
Py_XDECREF(tb);
break;
}
+ case E_IO:
+ msg = "I/O error while reading";
+ break;
case E_LINECONT:
msg = "unexpected character after line continuation character";
break;