[pypy-commit] pypy default: The "str0" check is now optional, and controlled by the option

amauryfa noreply at buildbot.pypy.org
Sat Feb 4 21:11:33 CET 2012


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: 
Changeset: r52100:a0016c989748
Date: 2012-02-04 21:07 +0100
http://bitbucket.org/pypy/pypy/changeset/a0016c989748/

Log:	The "str0" check is now optional, and controlled by the option
	config.translation.check_str_without_nul.

diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -740,6 +740,15 @@
         s_obj = new_s_obj
     return s_obj
 
+def remove_no_nul(s_obj):
+    if not getattr(s_obj, 'no_nul', False):
+        return s_obj
+    new_s_obj = SomeObject.__new__(s_obj.__class__)
+    new_s_obj.__dict__ = s_obj.__dict__.copy()
+    del new_s_obj.no_nul
+    return new_s_obj
+    
+
 # ____________________________________________________________
 # internal
 
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -123,6 +123,9 @@
                  default="off"),
     # jit_ffi is automatically turned on by withmod-_ffi (which is enabled by default)
     BoolOption("jit_ffi", "optimize libffi calls", default=False, cmdline=None),
+    BoolOption("check_str_without_nul",
+               "Forbid NUL chars in strings in some external function calls",
+               default=False, cmdline=None),
 
     # misc
     BoolOption("verbose", "Print extra information", default=False),
diff --git a/pypy/rpython/extfunc.py b/pypy/rpython/extfunc.py
--- a/pypy/rpython/extfunc.py
+++ b/pypy/rpython/extfunc.py
@@ -2,7 +2,7 @@
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.rpython.lltypesystem.lltype import typeOf
 from pypy.objspace.flow.model import Constant
-from pypy.annotation.model import unionof
+from pypy.annotation import model as annmodel
 from pypy.annotation.signature import annotation
 
 import py, sys
@@ -138,7 +138,6 @@
     # we defer a bit annotation here
 
     def compute_result_annotation(self):
-        from pypy.annotation import model as annmodel
         return annmodel.SomeGenericCallable([annotation(i, self.bookkeeper)
                                              for i in self.instance.args],
                            annotation(self.instance.result, self.bookkeeper))
@@ -152,8 +151,17 @@
         signature_args = [annotation(arg, None) for arg in args]
         assert len(args_s) == len(signature_args),\
                "Argument number mismatch"
+
+        check_no_nul = False
+        if hasattr(self, 'bookkeeper'):
+            config = self.bookkeeper.annotator.translator.config
+            if config.translation.check_str_without_nul:
+                check_no_nul = True
+            
         for i, expected in enumerate(signature_args):
-            arg = unionof(args_s[i], expected)
+            if not check_no_nul:
+                expected = annmodel.remove_no_nul(expected)
+            arg = annmodel.unionof(args_s[i], expected)
             if not expected.contains(arg):
                 name = getattr(self, 'name', None)
                 if not name:
diff --git a/pypy/rpython/module/ll_os_environ.py b/pypy/rpython/module/ll_os_environ.py
--- a/pypy/rpython/module/ll_os_environ.py
+++ b/pypy/rpython/module/ll_os_environ.py
@@ -3,9 +3,10 @@
 from pypy.rpython.controllerentry import Controller
 from pypy.rpython.extfunc import register_external
 from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.module import ll_os
 from pypy.rlib import rposix
 
-str0 = annmodel.s_Str0
+str0 = ll_os.str0
 
 # ____________________________________________________________
 #
diff --git a/pypy/rpython/test/test_extfunc.py b/pypy/rpython/test/test_extfunc.py
--- a/pypy/rpython/test/test_extfunc.py
+++ b/pypy/rpython/test/test_extfunc.py
@@ -167,3 +167,23 @@
         a = RPythonAnnotator(policy=policy)
         s = a.build_types(f, [])
         assert isinstance(s, annmodel.SomeString)
+
+    def test_str0(self):
+        str0 = annmodel.SomeString(no_nul=True)
+        def os_open(s):
+            pass
+        register_external(os_open, [str0], None)
+        def f(s):
+            return os_open(s)
+        policy = AnnotatorPolicy()
+        policy.allow_someobjects = False
+        a = RPythonAnnotator(policy=policy)
+        a.build_types(f, [str])  # Does not raise
+        assert a.translator.config.translation.check_str_without_nul == False
+        # Now enable the str0 check, and try again with a similar function
+        a.translator.config.translation.check_str_without_nul=True
+        def g(s):
+            return os_open(s)
+        raises(Exception, a.build_types, g, [str])
+        a.build_types(g, [str0])  # Does not raise
+


More information about the pypy-commit mailing list