Skip to content
Permalink
Browse files

Merge pull request #502 from topazproject/tim/handle-no_nul-strings

Switch to proper merging of no_nul annotation, and fix translation
  • Loading branch information
alex committed Mar 12, 2013
2 parents 502b409 + e1910ee commit 990466305585a0dde1a049350aab214de14ac1f0
@@ -10,3 +10,7 @@ def target(driver, args):

def jitpolicy(driver):
return JitPolicy()


def handle_config(config, translateconfig):
config.translation.suggest(check_str_without_nul=True)
@@ -364,6 +364,32 @@ def test_no_ext_on_path(self, space, tmpdir):
""" % f)
assert space.int_w(w_res) == 5

def test_null_bytes(self, space):
with self.raises(space, "ArgumentError", "string contains null byte"):
space.execute('require "b\\0"')
with self.raises(space, "ArgumentError", "string contains null byte"):
space.execute("""
$LOAD_PATH.unshift "\\0"
require 'pp'
""")

def test_load_path_element_coerce(self, space, tmpdir):
f = tmpdir.join("t.rb")
f.write("""
$success = true
""")
w_res = space.execute("""
class A
def to_path
"%s"
end
end
$LOAD_PATH.unshift A.new
require 't'
return $success
""" % tmpdir)
assert w_res is space.w_true


class TestExec(BaseTopazTest):
def fork_and_wait(self, space, capfd, code):
@@ -395,6 +421,16 @@ def test_exec_with_path_search(self, space, capfd):
out = self.fork_and_wait(space, capfd, "exec 'echo', '$0'")
assert out == "$0\n"

def test_exec_with_null_bytes(self, space):
with self.raises(space, "ArgumentError", "string contains null byte"):
space.execute('exec "\\0"')
with self.raises(space, "ArgumentError", "string contains null byte"):
space.execute('exec ["\\0", "none"]')
with self.raises(space, "ArgumentError", "string contains null byte"):
space.execute('exec ["none", "\\0"]')
with self.raises(space, "ArgumentError", "string contains null byte"):
space.execute('exec "none", "\\0"')


class TestSetTraceFunc(BaseTopazTest):
def test_class(self, space):
@@ -105,6 +105,13 @@ def test_glob(self, space, tmpdir):
end
""" % (tmpdir, tmpdir.join("..")))
assert self.unwrap(space, w_res) == [str(tmpdir.join("..")) + "/"]
w_res = space.execute("""
Dir.chdir('%s') do
return Dir["sub1\\0foo", "sub\\02bar"], Dir["sub1\\0foo"]
end
""" % tmpdir)
res = self.unwrap(space, w_res)
assert res == [["sub1"], ["sub1"]]

def test_read(self, space, tmpdir):
d = tmpdir.mkdir("sub")
@@ -1,6 +1,3 @@
from rpython.rlib.rstring import assert_str0


class Coerce(object):
@staticmethod
def bool(space, w_obj):
@@ -52,12 +49,7 @@ def path(space, w_obj):
w_string = space.convert_type(w_obj, space.w_string, "to_path", raise_error=False)
if w_string is space.w_nil:
w_string = space.convert_type(w_obj, space.w_string, "to_str")
string = space.str_w(w_string)

if "\x00" in string:
raise space.error(space.w_ArgumentError, "string contains null byte")
else:
return assert_str0(string)
return space.str0_w(w_string)

@staticmethod
def array(space, w_obj):
@@ -4,9 +4,9 @@
import time

from rpython.rlib.rfloat import round_double
from rpython.rlib.rstring import assert_str0
from rpython.rlib.streamio import open_file_as_stream

from topaz.coerce import Coerce
from topaz.error import RubyError, error_for_oserror
from topaz.module import Module, ModuleDef
from topaz.modules.process import Process
@@ -54,16 +54,16 @@ def find_feature(space, path):
if not (path.startswith("/") or path.startswith("./") or path.startswith("../")):
w_load_path = space.globals.get(space, "$LOAD_PATH")
for w_base in space.listview(w_load_path):
base = space.str_w(w_base)
base = Coerce.path(space, w_base)
full = os.path.join(base, path)
if os.path.exists(assert_str0(full)):
if os.path.exists(full):
path = os.path.join(base, path)
break
return path

@staticmethod
def load_feature(space, path, orig_path):
if not os.path.exists(assert_str0(path)):
if not os.path.exists(path):
raise space.error(space.w_LoadError, orig_path)

try:
@@ -166,13 +166,13 @@ def method_exec(self, space, args_w):
if space.respond_to(args_w[0], space.newsymbol("to_ary")):
w_cmd = space.convert_type(args_w[0], space.w_array, "to_ary")
cmd, argv0 = [
space.str_w(space.convert_type(
space.str0_w(space.convert_type(
w_e, space.w_string, "to_str"
)) for w_e in space.listview(w_cmd)
]
else:
w_cmd = space.convert_type(args_w[0], space.w_string, "to_str")
cmd = space.str_w(w_cmd)
cmd = space.str0_w(w_cmd)
argv0 = None

if len(args_w) > 1 or argv0 is not None:
@@ -184,7 +184,7 @@ def method_exec(self, space, args_w):
argv0 = cmd
args = [argv0]
args += [
space.str_w(space.convert_type(
space.str0_w(space.convert_type(
w_arg, space.w_string, "to_str"
)) for w_arg in args_w[1:]
]
@@ -88,7 +88,7 @@ def method_glob(self, space, w_pattern, flags=0, block=None):
for pat in pattern.split("\0"):
glob.glob(pat, flags)
else:
glob.glob(pattern, flags)
glob.glob(pattern.split("\0")[0], flags)

if block:
for match in glob.matches():
@@ -69,7 +69,7 @@ def singleton_method_delete(self, space, args_w):
raise error_for_oserror(space, e)
return space.newint(len(args_w))

@classdef.method("initialize", filename="str")
@classdef.method("initialize", filename="path")
def method_initialize(self, space, filename, w_mode=None, w_perm_or_opt=None, w_opt=None):
if w_mode is None:
w_mode = space.w_nil
@@ -408,6 +408,13 @@ def str_w(self, w_obj):
"""Unpacks a string object as an rstr."""
return w_obj.str_w(self)

def str0_w(self, w_obj):
string = w_obj.str_w(self)
if "\x00" in string:
raise self.error(self.w_ArgumentError, "string contains null byte")
else:
return string

def listview(self, w_obj):
return w_obj.listview(self)

0 comments on commit 9904663

Please sign in to comment.
You can’t perform that action at this time.