Author: Hakan Ardo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit