Author: Hakan Ardo <ha...@debian.org> Branch: jit-targets Changeset: r50373:ebf413fc4faa Date: 2011-12-11 12:42 +0100 http://bitbucket.org/pypy/pypy/changeset/ebf413fc4faa/
Log: hg merge default diff --git a/pypy/module/_hashlib/test/test_hashlib.py b/pypy/module/_hashlib/test/test_hashlib.py --- a/pypy/module/_hashlib/test/test_hashlib.py +++ b/pypy/module/_hashlib/test/test_hashlib.py @@ -79,3 +79,29 @@ assert h.digest() == _hashlib.openssl_md5('x' * 20).digest() _hashlib.openssl_sha1(b).digest() + def test_extra_algorithms(self): + import _hashlib + test_string = "Nobody inspects the spammish repetition" + expected_results = { + "md5": "bb649c83dd1ea5c9d9dec9a18df0ffe9", + "md4": "c275b8454684ea416b93d7a418b43176", + "mdc2": None, # XXX find the correct expected value + "sha": "e2b0a8609b47c58e5d984c9ccfe69f9b654b032b", + "ripemd160": "cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc", + "whirlpool": "1a22b79fe5afda02c63a25927193ed01dc718b74" + "026e597608ce431f9c3d2c9e74a7350b7fbb7c5d" + "4effe5d7a31879b8b7a10fd2f544c4ca268ecc6793923583", + } + def extracheck(hash_name, expected): + try: + m = _hashlib.new(hash_name) + except ValueError, e: + skip('%s: %s' % (hash_name, e)) + m.update(test_string) + got = m.hexdigest() + assert got and type(got) is str and len(got) % 2 == 0 + got.decode('hex') + if expected is not None: + assert got == expected + for hash_name, expected in sorted(expected_results.items()): + yield extracheck, hash_name, expected diff --git a/pypy/translator/sandbox/sandlib.py b/pypy/translator/sandbox/sandlib.py --- a/pypy/translator/sandbox/sandlib.py +++ b/pypy/translator/sandbox/sandlib.py @@ -6,11 +6,10 @@ import py import sys, os, posixpath, errno, stat, time -from pypy.rpython.module.ll_os_stat import s_StatResult from pypy.tool.ansi_print import AnsiLog -from pypy.rlib.rarithmetic import r_longlong import subprocess from pypy.tool.killsubprocess import killsubprocess +from pypy.translator.sandbox.vfs import UID, GID class MyAnsiLog(AnsiLog): KW_TO_COLOR = { @@ -34,6 +33,10 @@ from pypy.tool.lib_pypy import import_from_lib_pypy marshal = import_from_lib_pypy('marshal') +# Non-marshal result types +RESULTTYPE_STATRESULT = object() +RESULTTYPE_LONGLONG = object() + def read_message(f, timeout=None): # warning: 'timeout' is not really reliable and should only be used # for testing. Also, it doesn't work if the file f does any buffering. @@ -50,12 +53,30 @@ marshal.dump(msg, g) else: marshal.dump(msg, g, 0) + elif resulttype is RESULTTYPE_STATRESULT: + # Hand-coded marshal for stat results that mimics what rmarshal expects. + # marshal.dump(tuple(msg)) would have been too easy. rmarshal insists + # on 64-bit ints at places, even when the value fits in 32 bits. + import struct + st = tuple(msg) + fmt = "iIIiiiIfff" + buf = [] + buf.append(struct.pack("<ci", '(', len(st))) + for c, v in zip(fmt, st): + if c == 'i': + buf.append(struct.pack("<ci", c, v)) + elif c == 'I': + buf.append(struct.pack("<cq", c, v)) + elif c == 'f': + fstr = "%g" % v + buf.append(struct.pack("<cB", c, len(fstr))) + buf.append(fstr) + g.write(''.join(buf)) + elif resulttype is RESULTTYPE_LONGLONG: + import struct + g.write(struct.pack("<cq", 'I', msg)) else: - # use the exact result type for encoding - from pypy.rlib.rmarshal import get_marshaller - buf = [] - get_marshaller(resulttype)(buf, msg) - g.write(''.join(buf)) + raise Exception("Can't marshal: %r (%r)" % (msg, resulttype)) # keep the table in sync with rsandbox.reraise_error() EXCEPTION_TABLE = [ @@ -390,7 +411,7 @@ def __init__(self, *args, **kwds): super(VirtualizedSandboxedProc, self).__init__(*args, **kwds) self.virtual_root = self.build_virtual_root() - self.open_fds = {} # {virtual_fd: real_file_object} + self.open_fds = {} # {virtual_fd: (real_file_object, node)} def build_virtual_root(self): raise NotImplementedError("must be overridden") @@ -425,26 +446,39 @@ def do_ll_os__ll_os_stat(self, vpathname): node = self.get_node(vpathname) return node.stat() - do_ll_os__ll_os_stat.resulttype = s_StatResult + do_ll_os__ll_os_stat.resulttype = RESULTTYPE_STATRESULT do_ll_os__ll_os_lstat = do_ll_os__ll_os_stat def do_ll_os__ll_os_isatty(self, fd): return self.virtual_console_isatty and fd in (0, 1, 2) - def allocate_fd(self, f): + def allocate_fd(self, f, node=None): for fd in self.virtual_fd_range: if fd not in self.open_fds: - self.open_fds[fd] = f + self.open_fds[fd] = (f, node) return fd else: raise OSError(errno.EMFILE, "trying to open too many files") - def get_file(self, fd): + def get_fd(self, fd, throw=True): + """Get the objects implementing file descriptor `fd`. + + Returns a pair, (open file, vfs node) + + `throw`: if true, raise OSError for bad fd, else return (None, None). + """ try: - return self.open_fds[fd] + f, node = self.open_fds[fd] except KeyError: - raise OSError(errno.EBADF, "bad file descriptor") + if throw: + raise OSError(errno.EBADF, "bad file descriptor") + return None, None + return f, node + + def get_file(self, fd, throw=True): + """Return the open file for file descriptor `fd`.""" + return self.get_fd(fd, throw)[0] def do_ll_os__ll_os_open(self, vpathname, flags, mode): node = self.get_node(vpathname) @@ -452,7 +486,7 @@ raise OSError(errno.EPERM, "write access denied") # all other flags are ignored f = node.open() - return self.allocate_fd(f) + return self.allocate_fd(f, node) def do_ll_os__ll_os_close(self, fd): f = self.get_file(fd) @@ -460,9 +494,8 @@ f.close() def do_ll_os__ll_os_read(self, fd, size): - try: - f = self.open_fds[fd] - except KeyError: + f = self.get_file(fd, throw=False) + if f is None: return super(VirtualizedSandboxedProc, self).do_ll_os__ll_os_read( fd, size) else: @@ -471,11 +504,16 @@ # don't try to read more than 256KB at once here return f.read(min(size, 256*1024)) + def do_ll_os__ll_os_fstat(self, fd): + f, node = self.get_fd(fd) + return node.stat() + do_ll_os__ll_os_fstat.resulttype = RESULTTYPE_STATRESULT + def do_ll_os__ll_os_lseek(self, fd, pos, how): f = self.get_file(fd) f.seek(pos, how) return f.tell() - do_ll_os__ll_os_lseek.resulttype = r_longlong + do_ll_os__ll_os_lseek.resulttype = RESULTTYPE_LONGLONG def do_ll_os__ll_os_getcwd(self): return self.virtual_cwd @@ -488,6 +526,14 @@ node = self.get_node(vpathname) return node.keys() + def do_ll_os__ll_os_getuid(self): + return UID + do_ll_os__ll_os_geteuid = do_ll_os__ll_os_getuid + + def do_ll_os__ll_os_getgid(self): + return GID + do_ll_os__ll_os_getegid = do_ll_os__ll_os_getgid + class VirtualizedSocketProc(VirtualizedSandboxedProc): """ Extends VirtualizedSandboxProc with socket @@ -511,13 +557,13 @@ def do_ll_os__ll_os_read(self, fd, size): if fd in self.sockets: - return self.open_fds[fd].recv(size) + return self.get_file(fd).recv(size) return super(VirtualizedSocketProc, self).do_ll_os__ll_os_read( fd, size) def do_ll_os__ll_os_write(self, fd, data): if fd in self.sockets: - return self.open_fds[fd].send(data) + return self.get_file(fd).send(data) return super(VirtualizedSocketProc, self).do_ll_os__ll_os_write( fd, data) diff --git a/pypy/translator/sandbox/test/test_sandbox.py b/pypy/translator/sandbox/test/test_sandbox.py --- a/pypy/translator/sandbox/test/test_sandbox.py +++ b/pypy/translator/sandbox/test/test_sandbox.py @@ -80,7 +80,7 @@ assert tail == "" def test_stat_ftruncate(): - from pypy.rpython.module.ll_os_stat import s_StatResult + from pypy.translator.sandbox.sandlib import RESULTTYPE_STATRESULT from pypy.rlib.rarithmetic import r_longlong r0x12380000007 = r_longlong(0x12380000007) @@ -93,7 +93,7 @@ g, f = os.popen2(exe, "t", 0) st = os.stat_result((55, 0, 0, 0, 0, 0, 0x12380000007, 0, 0, 0)) expect(f, g, "ll_os.ll_os_stat", ("somewhere",), st, - resulttype = s_StatResult) + resulttype = RESULTTYPE_STATRESULT) expect(f, g, "ll_os.ll_os_ftruncate", (55, 0x12380000007), None) g.close() tail = f.read() diff --git a/pypy/translator/sandbox/test/test_sandlib.py b/pypy/translator/sandbox/test/test_sandlib.py --- a/pypy/translator/sandbox/test/test_sandlib.py +++ b/pypy/translator/sandbox/test/test_sandlib.py @@ -1,14 +1,17 @@ import py -import os, StringIO +import errno, os, StringIO from pypy.tool.sourcetools import func_with_new_name from pypy.rpython.lltypesystem import rffi from pypy.translator.sandbox.sandlib import SandboxedProc from pypy.translator.sandbox.sandlib import SimpleIOSandboxedProc +from pypy.translator.sandbox.sandlib import VirtualizedSandboxedProc from pypy.translator.sandbox.sandlib import VirtualizedSocketProc from pypy.translator.sandbox.test.test_sandbox import compile +from pypy.translator.sandbox.vfs import Dir, File, RealDir, RealFile -class MySandboxedProc(SandboxedProc): +class MockSandboxedProc(SandboxedProc): + """A sandbox process wrapper that replays expected syscalls.""" def __init__(self, args, expected): SandboxedProc.__init__(self, args) @@ -48,7 +51,7 @@ return 0 exe = compile(entry_point) - proc = MySandboxedProc([exe, 'x1', 'y2'], expected = [ + proc = MockSandboxedProc([exe, 'x1', 'y2'], expected = [ ("open", ("/tmp/foobar", os.O_RDONLY, 0777), 77), ("read", (77, 123), "he\x00llo"), ("write", (77, "world\x00!\x00"), 42), @@ -69,7 +72,7 @@ return n exe = compile(entry_point) - proc = MySandboxedProc([exe, 'spam', 'egg'], expected = [ + proc = MockSandboxedProc([exe, 'spam', 'egg'], expected = [ ("foobar", ("spam",), 2), ("foobar", ("egg",), 0), ]) @@ -122,9 +125,140 @@ return 0 exe = compile(entry_point) - proc = MySandboxedProc([exe], expected = [ + proc = MockSandboxedProc([exe], expected = [ ("open", ("/tmp/foobar", os.O_RDONLY, 0777), OSError(-42, "baz")), ("close", (-42,), None), ]) proc.handle_forever() assert proc.seen == len(proc.expected) + + +class SandboxedProcWithFiles(VirtualizedSandboxedProc, SimpleIOSandboxedProc): + """A sandboxed process with a simple virtualized filesystem. + + For testing file operations. + + """ + def build_virtual_root(self): + return Dir({ + 'hi.txt': File("Hello, world!\n"), + 'this.pyc': RealFile(__file__), + }) + +def test_too_many_opens(): + def entry_point(argv): + try: + open_files = [] + for i in range(500): + fd = os.open('/hi.txt', os.O_RDONLY, 0777) + open_files.append(fd) + txt = os.read(fd, 100) + if txt != "Hello, world!\n": + print "Wrong content: %s" % txt + except OSError, e: + # We expect to get EMFILE, for opening too many files. + if e.errno != errno.EMFILE: + print "OSError: %s!" % (e.errno,) + else: + print "We opened 500 fake files! Shouldn't have been able to." + + for fd in open_files: + os.close(fd) + + try: + open_files = [] + for i in range(500): + fd = os.open('/this.pyc', os.O_RDONLY, 0777) + open_files.append(fd) + except OSError, e: + # We expect to get EMFILE, for opening too many files. + if e.errno != errno.EMFILE: + print "OSError: %s!" % (e.errno,) + else: + print "We opened 500 real files! Shouldn't have been able to." + + print "All ok!" + return 0 + exe = compile(entry_point) + + proc = SandboxedProcWithFiles([exe]) + output, error = proc.communicate("") + assert output == "All ok!\n" + assert error == "" + +def test_fstat(): + def compare(a, b, i): + if a != b: + print "stat and fstat differ @%d: %s != %s" % (i, a, b) + + def entry_point(argv): + try: + # Open a file, and compare stat and fstat + fd = os.open('/hi.txt', os.O_RDONLY, 0777) + st = os.stat('/hi.txt') + fs = os.fstat(fd) + # RPython requires the index for stat to be a constant.. :( + compare(st[0], fs[0], 0) + compare(st[1], fs[1], 1) + compare(st[2], fs[2], 2) + compare(st[3], fs[3], 3) + compare(st[4], fs[4], 4) + compare(st[5], fs[5], 5) + compare(st[6], fs[6], 6) + compare(st[7], fs[7], 7) + compare(st[8], fs[8], 8) + compare(st[9], fs[9], 9) + except OSError, e: + print "OSError: %s" % (e.errno,) + print "All ok!" + return 0 + exe = compile(entry_point) + + proc = SandboxedProcWithFiles([exe]) + output, error = proc.communicate("") + assert output == "All ok!\n" + assert error == "" + +def test_lseek(): + def char_should_be(c, should): + if c != should: + print "Wrong char: '%s' should be '%s'" % (c, should) + + def entry_point(argv): + fd = os.open('/hi.txt', os.O_RDONLY, 0777) + char_should_be(os.read(fd, 1), "H") + new = os.lseek(fd, 3, os.SEEK_CUR) + if new != 4: + print "Wrong offset, %d should be 4" % new + char_should_be(os.read(fd, 1), "o") + new = os.lseek(fd, -3, os.SEEK_END) + if new != 11: + print "Wrong offset, %d should be 11" % new + char_should_be(os.read(fd, 1), "d") + new = os.lseek(fd, 7, os.SEEK_SET) + if new != 7: + print "Wrong offset, %d should be 7" % new + char_should_be(os.read(fd, 1), "w") + print "All ok!" + return 0 + exe = compile(entry_point) + + proc = SandboxedProcWithFiles([exe]) + output, error = proc.communicate("") + assert output == "All ok!\n" + assert error == "" + +def test_getuid(): + def entry_point(argv): + import os + print "uid is %s" % os.getuid() + print "euid is %s" % os.geteuid() + print "gid is %s" % os.getgid() + print "egid is %s" % os.getegid() + return 0 + exe = compile(entry_point) + + proc = SandboxedProcWithFiles([exe]) + output, error = proc.communicate("") + assert output == "uid is 1000\neuid is 1000\ngid is 1000\negid is 1000\n" + assert error == "" _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit