Commit befb14fe authored by Brett Cannon's avatar Brett Cannon

Merged revisions 69481 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r69481 | brett.cannon | 2009-02-09 18:07:38 -0800 (Mon, 09 Feb 2009) | 4 lines

  compileall used the ctime of bytecode and source to determine if the bytecode
  should be recreated. This created a timing hole. Fixed by just doing what
  import does; check the mtime and magic number.
........
parent 6691772f
...@@ -11,10 +11,11 @@ packages -- for now, you'll have to deal with packages separately.) ...@@ -11,10 +11,11 @@ packages -- for now, you'll have to deal with packages separately.)
See module py_compile for details of the actual byte-compilation. See module py_compile for details of the actual byte-compilation.
""" """
import os import os
import sys import sys
import py_compile import py_compile
import struct
import imp
__all__ = ["compile_dir","compile_path"] __all__ = ["compile_dir","compile_path"]
...@@ -54,11 +55,17 @@ def compile_dir(dir, maxlevels=10, ddir=None, ...@@ -54,11 +55,17 @@ def compile_dir(dir, maxlevels=10, ddir=None,
if os.path.isfile(fullname): if os.path.isfile(fullname):
head, tail = name[:-3], name[-3:] head, tail = name[:-3], name[-3:]
if tail == '.py': if tail == '.py':
cfile = fullname + (__debug__ and 'c' or 'o') if not force:
ftime = os.stat(fullname).st_mtime try:
try: ctime = os.stat(cfile).st_mtime mtime = os.stat(fullname).st_mtime
except os.error: ctime = 0 expect = struct.pack('<4sl', imp.get_magic(), mtime)
if (ctime > ftime) and not force: continue cfile = fullname + (__debug__ and 'c' or 'o')
with open(cfile, 'rb') as chandle:
actual = chandle.read(8)
if expect == actual:
continue
except IOError:
pass
if not quiet: if not quiet:
print('Compiling', fullname, '...') print('Compiling', fullname, '...')
try: try:
...@@ -86,7 +93,8 @@ def compile_dir(dir, maxlevels=10, ddir=None, ...@@ -86,7 +93,8 @@ def compile_dir(dir, maxlevels=10, ddir=None,
name != os.curdir and name != os.pardir and \ name != os.curdir and name != os.pardir and \
os.path.isdir(fullname) and \ os.path.isdir(fullname) and \
not os.path.islink(fullname): not os.path.islink(fullname):
if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, quiet): if not compile_dir(fullname, maxlevels - 1, dfile, force, rx,
quiet):
success = 0 success = 0
return success return success
......
import compileall
import imp
import os
import py_compile
import shutil
import struct
import sys
import tempfile
import time
from test import support
import unittest
class CompileallTests(unittest.TestCase):
def setUp(self):
self.directory = tempfile.mkdtemp()
self.source_path = os.path.join(self.directory, '_test.py')
self.bc_path = self.source_path + ('c' if __debug__ else 'o')
with open(self.source_path, 'w') as file:
file.write('x = 123\n')
def tearDown(self):
shutil.rmtree(self.directory)
def data(self):
with open(self.bc_path, 'rb') as file:
data = file.read(8)
mtime = int(os.stat(self.source_path).st_mtime)
compare = struct.pack('<4sl', imp.get_magic(), mtime)
return data, compare
def recreation_check(self, metadata):
"""Check that compileall recreates bytecode when the new metadata is
used."""
if not hasattr(os, 'stat'):
return
py_compile.compile(self.source_path)
self.assertEqual(*self.data())
with open(self.bc_path, 'rb') as file:
bc = file.read()[len(metadata):]
with open(self.bc_path, 'wb') as file:
file.write(metadata)
file.write(bc)
self.assertNotEqual(*self.data())
compileall.compile_dir(self.directory, force=False, quiet=True)
self.assertTrue(*self.data())
def test_mtime(self):
# Test a change in mtime leads to a new .pyc.
self.recreation_check(struct.pack('<4sl', imp.get_magic(), 1))
def test_magic_number(self):
# Test a change in mtime leads to a new .pyc.
self.recreation_check(b'\0\0\0\0')
def test_main():
support.run_unittest(CompileallTests)
if __name__ == "__main__":
test_main()
...@@ -183,7 +183,7 @@ Virgil Dupras ...@@ -183,7 +183,7 @@ Virgil Dupras
Andy Dustman Andy Dustman
Gary Duzan Gary Duzan
Eugene Dvurechenski Eugene Dvurechenski
Josip Dzolonga Josip Dzolonga
Maxim Dzumanenko Maxim Dzumanenko
Walter Drwald Walter Drwald
Hans Eckardt Hans Eckardt
...@@ -234,6 +234,7 @@ Geoff Furnish ...@@ -234,6 +234,7 @@ Geoff Furnish
Ulisses Furquim Ulisses Furquim
Hagen Frstenau Hagen Frstenau
Achim Gaedke Achim Gaedke
Martin von Gagern
Lele Gaifax Lele Gaifax
Santiago Gala Santiago Gala
Yitzchak Gale Yitzchak Gale
......
...@@ -163,6 +163,10 @@ Core and Builtins ...@@ -163,6 +163,10 @@ Core and Builtins
Library Library
------- -------
- Issue #5128: Make compileall properly inspect bytecode to determine if needs
to be recreated. This avoids a timing hole thanks to the old reliance on the
ctime of the files involved.
- Issue #5122: Synchronize tk load failure check to prevent a potential - Issue #5122: Synchronize tk load failure check to prevent a potential
deadlock. deadlock.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment