You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
6.3 KiB
159 lines
6.3 KiB
|
|
# HG changeset patch
|
|
# User Jim Baker <jim.baker@rackspace.com>
|
|
# Date 1454384221 25200
|
|
# Node ID d06e29d100c04576735e86c75a26c5f33669bb72
|
|
# Parent b6735606c13df95f770527e629954407f82808c5
|
|
Do not deserialize PyFunction objects. Fixes #2454
|
|
|
|
Instead use standard Python pickling; or subclass PyFunction.
|
|
|
|
diff --git a/Lib/test/test_java_integration.py b/Lib/test/test_java_integration.py
|
|
--- a/Lib/test/test_java_integration.py
|
|
+++ b/Lib/test/test_java_integration.py
|
|
@@ -14,8 +14,9 @@ import re
|
|
from collections import deque
|
|
from test import test_support
|
|
|
|
-from java.lang import (ClassCastException, ExceptionInInitializerError, String, Runnable, System,
|
|
- Runtime, Math, Byte)
|
|
+from java.lang import (
|
|
+ ClassCastException, ExceptionInInitializerError, UnsupportedOperationException,
|
|
+ String, Runnable, System, Runtime, Math, Byte)
|
|
from java.math import BigDecimal, BigInteger
|
|
from java.net import URI
|
|
from java.io import (ByteArrayInputStream, ByteArrayOutputStream, File, FileInputStream,
|
|
@@ -656,13 +657,30 @@ class SerializationTest(unittest.TestCas
|
|
self.assertEqual(date_list, roundtrip_serialization(date_list))
|
|
|
|
def test_java_serialization_pycode(self):
|
|
-
|
|
def universal_answer():
|
|
return 42
|
|
|
|
serialized_code = roundtrip_serialization(universal_answer.func_code)
|
|
self.assertEqual(eval(serialized_code), universal_answer())
|
|
|
|
+ def test_java_serialization_pyfunction(self):
|
|
+ # Not directly supported due to lack of general utility
|
|
+ # (globals will usually be in the function object in
|
|
+ # func_globals), and problems with unserialization
|
|
+ # vulnerabilities. Users can always subclass from PyFunction
|
|
+ # for specific cases, as seen in PyCascading
|
|
+ import new
|
|
+ def f():
|
|
+ return 6 * 7 + max(0, 1, 2)
|
|
+ # However, using the new module, it's possible to create a
|
|
+ # function with no globals, which means the globals will come
|
|
+ # from the current context
|
|
+ g = new.function(f.func_code, {}, "g")
|
|
+ # But still forbid Java deserialization of this function
|
|
+ # object. Use pickling or other support instead.
|
|
+ with self.assertRaises(UnsupportedOperationException):
|
|
+ roundtrip_serialization(g)
|
|
+
|
|
def test_builtin_names(self):
|
|
import __builtin__
|
|
names = [x for x in dir(__builtin__)]
|
|
@@ -872,7 +890,7 @@ class SingleMethodInterfaceTest(unittest
|
|
future.get()
|
|
self.assertEqual(x, [42])
|
|
|
|
- @unittest.skip("FIXME: not working")
|
|
+ @unittest.skip("FIXME: not working; see http://bugs.jython.org/issue2115")
|
|
def test_callable_object(self):
|
|
callable_obj = CallableObject()
|
|
future = self.executor.submit(callable_obj)
|
|
diff --git a/Lib/test/test_new.py b/Lib/test/test_new.py
|
|
--- a/Lib/test/test_new.py
|
|
+++ b/Lib/test/test_new.py
|
|
@@ -24,18 +24,10 @@ class NewTest(unittest.TestCase):
|
|
c = new.instance(C, {'yolks': 3})
|
|
|
|
o = new.instance(C)
|
|
-
|
|
- # __dict__ is a non dict mapping in Jython
|
|
- if test_support.is_jython:
|
|
- self.assertEqual(len(o.__dict__), 0, "new __dict__ should be empty")
|
|
- else:
|
|
- self.assertEqual(o.__dict__, {}, "new __dict__ should be empty")
|
|
+ self.assertEqual(o.__dict__, {}, "new __dict__ should be empty")
|
|
del o
|
|
o = new.instance(C, None)
|
|
- if test_support.is_jython:
|
|
- self.assertEqual(len(o.__dict__), 0, "new __dict__ should be empty")
|
|
- else:
|
|
- self.assertEqual(o.__dict__, {}, "new __dict__ should be empty")
|
|
+ self.assertEqual(o.__dict__, {}, "new __dict__ should be empty")
|
|
del o
|
|
|
|
def break_yolks(self):
|
|
@@ -109,7 +101,14 @@ class NewTest(unittest.TestCase):
|
|
test_closure(g, (1, 1), ValueError) # closure is wrong size
|
|
test_closure(f, g.func_closure, ValueError) # no closure needed
|
|
|
|
- if hasattr(new, 'code') and not test_support.is_jython:
|
|
+ # [Obsolete] Note: Jython will never have new.code()
|
|
+ #
|
|
+ # Who said that?!!! guess what, we do! :)
|
|
+ #
|
|
+ # Unfortunately we still need a way to compile to Python bytecode,
|
|
+ # so support is still incomplete, as seen in the fact that we need
|
|
+ # to get values from CPython 2.7.
|
|
+ if hasattr(new, 'code'):
|
|
def test_code(self):
|
|
# bogus test of new.code()
|
|
def f(a): pass
|
|
@@ -117,16 +116,16 @@ class NewTest(unittest.TestCase):
|
|
c = f.func_code
|
|
argcount = c.co_argcount
|
|
nlocals = c.co_nlocals
|
|
- stacksize = c.co_stacksize
|
|
+ stacksize = 1 # TODO c.co_stacksize
|
|
flags = c.co_flags
|
|
- codestring = c.co_code
|
|
- constants = c.co_consts
|
|
- names = c.co_names
|
|
+ codestring = 'd\x00\x00S' # TODO c.co_code
|
|
+ constants = (None,) # TODO c.co_consts
|
|
+ names = () # TODO c.co_names
|
|
varnames = c.co_varnames
|
|
filename = c.co_filename
|
|
name = c.co_name
|
|
firstlineno = c.co_firstlineno
|
|
- lnotab = c.co_lnotab
|
|
+ lnotab = '' # TODO c.co_lnotab, but also see http://bugs.jython.org/issue1638
|
|
freevars = c.co_freevars
|
|
cellvars = c.co_cellvars
|
|
|
|
diff --git a/src/org/python/core/PyBytecode.java b/src/org/python/core/PyBytecode.java
|
|
--- a/src/org/python/core/PyBytecode.java
|
|
+++ b/src/org/python/core/PyBytecode.java
|
|
@@ -66,6 +66,12 @@ public class PyBytecode extends PyBaseCo
|
|
|
|
debug = defaultDebug;
|
|
|
|
+ if (argcount < 0) {
|
|
+ throw Py.ValueError("code: argcount must not be negative");
|
|
+ } else if (nlocals < 0) {
|
|
+ throw Py.ValueError("code: nlocals must not be negative");
|
|
+ }
|
|
+
|
|
co_argcount = nargs = argcount;
|
|
co_varnames = varnames;
|
|
co_nlocals = nlocals; // maybe assert = varnames.length;
|
|
diff --git a/src/org/python/core/PyFunction.java b/src/org/python/core/PyFunction.java
|
|
--- a/src/org/python/core/PyFunction.java
|
|
+++ b/src/org/python/core/PyFunction.java
|
|
@@ -545,6 +545,9 @@ public class PyFunction extends PyObject
|
|
@Override
|
|
public boolean isSequenceType() { return false; }
|
|
|
|
+ private Object readResolve() {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
|
|
/* Traverseproc implementation */
|
|
@Override
|
|
|