21
|
1 <?xml version="1.0" encoding="utf-8" ?>
|
|
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
4 <head>
|
|
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
6 <meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
|
|
7 <title></title>
|
|
8 <link rel="stylesheet" href="docs.css" type="text/css" />
|
|
9 </head>
|
|
10 <body>
|
|
11 <div class="document">
|
|
12 <blockquote>
|
|
13 <p>Pydertron is a high-level wrapper for <a class="reference" href="http://code.google.com/p/pydermonkey">Pydermonkey</a> that
|
|
14 provides convenient, secure object wrapping between JS and Python
|
|
15 space.</p>
|
|
16 <p>The <tt class="docutils literal"><span class="pre">JsSandbox</span></tt> class encapsulates a JavaScript runtime, context, global
|
|
17 object, and a simple <a class="reference" href="http://wiki.commonjs.org/wiki/CommonJS/Modules/SecurableModules">SecurableModule</a> implementation that complies
|
|
18 with the <a class="reference" href="http://wiki.commonjs.org/wiki/CommonJS">CommonJS</a> standard. It also provides a high-level bridge between
|
|
19 Python and JavaScript so that you don't need to deal with any of the
|
|
20 low-level details of the Pydermonkey API.</p>
|
|
21 <p>For instance, here we'll create a <tt class="docutils literal"><span class="pre">JsSandbox</span></tt> whose module root
|
|
22 points to the <tt class="docutils literal"><span class="pre">monkeys</span></tt> SecurableModule compliance test over HTTP:</p>
|
|
23 <blockquote>
|
|
24 <pre class="doctest-block">
|
|
25 >>> url = ("http://interoperablejs.googlecode.com/svn/trunk/"
|
|
26 ... "compliance/monkeys/")
|
|
27 >>> sandbox = JsSandbox(HttpFileSystem(url))
|
|
28 </pre>
|
|
29 </blockquote>
|
|
30 <p>This compliance test requires a global <tt class="docutils literal"><span class="pre">sys</span></tt> object that contains one
|
|
31 method, <tt class="docutils literal"><span class="pre">print()</span></tt>, that takes two arguments. First, we'll create the
|
|
32 <tt class="docutils literal"><span class="pre">print()</span></tt> function and prepare it for exposure to JS code:</p>
|
|
33 <blockquote>
|
|
34 <pre class="doctest-block">
|
|
35 >>> @jsexposed
|
|
36 ... def jsprint(message, label):
|
|
37 ... print message, label
|
|
38 </pre>
|
|
39 </blockquote>
|
|
40 <p>Note the use of the <tt class="docutils literal"><span class="pre">@jsexposed</span></tt> decorator: all this does is set
|
|
41 the function's <tt class="docutils literal"><span class="pre">__jsexposed__</span></tt> attribute to <tt class="docutils literal"><span class="pre">True</span></tt>. This is
|
|
42 done for security purposes: only Python callables satisfying this
|
|
43 criteria will be exposed to JavaScript code, to ensure that
|
|
44 untrusted JS can't accidentally gain access to privileged Python
|
|
45 functionality.</p>
|
|
46 <p>Creating a JS object can be done like this:</p>
|
|
47 <blockquote>
|
|
48 <pre class="doctest-block">
|
|
49 >>> system = sandbox.new_object()
|
|
50 </pre>
|
|
51 </blockquote>
|
|
52 <p>We can now access and set properties on this object via either
|
|
53 item or attribute lookup, just like in JavaScript. Because
|
|
54 <tt class="docutils literal"><span class="pre">print</span></tt> is a reserved word in Python, though, we'll use item
|
|
55 lookup to set the property here:</p>
|
|
56 <blockquote>
|
|
57 <pre class="doctest-block">
|
|
58 >>> system['print'] = jsprint
|
|
59 </pre>
|
|
60 </blockquote>
|
|
61 <p>Now we tell the sandbox that we want the <tt class="docutils literal"><span class="pre">sys</span></tt> object to be a
|
|
62 global:</p>
|
|
63 <blockquote>
|
|
64 <pre class="doctest-block">
|
|
65 >>> sandbox.set_globals(sys = system)
|
|
66 </pre>
|
|
67 </blockquote>
|
|
68 <p>And finally, we execute the compliance test by running a one-line
|
|
69 script that imports the 'program' module, like so:</p>
|
|
70 <blockquote>
|
|
71 <pre class="doctest-block">
|
|
72 >>> sandbox.run_script("require('program');")
|
|
73 PASS monkeys permitted pass
|
|
74 DONE info
|
|
75 0
|
|
76 </pre>
|
|
77 </blockquote>
|
|
78 <p>Note the <tt class="docutils literal"><span class="pre">0</span></tt> in the last line: this is the return value of
|
|
79 <tt class="docutils literal"><span class="pre">sandbox.run_script()</span></tt>, which returns <tt class="docutils literal"><span class="pre">0</span></tt> on success, and
|
|
80 <tt class="docutils literal"><span class="pre">-1</span></tt> if an exception was raised. For instance, the output of bad
|
|
81 code looks like this:</p>
|
|
82 <blockquote>
|
|
83 <pre class="doctest-block">
|
|
84 >>> sandbox.run_script("(function foo() { bar(); })();",
|
|
85 ... stderr=sys.stdout)
|
|
86 Traceback (most recent call last):
|
|
87 File "<string>", line 1, in <module>
|
|
88 File "<string>", line 1, in foo
|
|
89 ReferenceError: bar is not defined
|
|
90 -1
|
|
91 </pre>
|
|
92 </blockquote>
|
|
93 <p>Note that the traceback displayed is actually referring to
|
|
94 JavaScript code: one of Pydertron's helpful conveniences is that
|
|
95 it makes debugging JS code as much like debugging Python code as
|
|
96 possible.</p>
|
|
97 </blockquote>
|
|
98 </div>
|
|
99 </body>
|
|
100 </html>
|