Skip to content
Snippets Groups Projects
Commit d6263f21 authored by Thomas Oster's avatar Thomas Oster
Browse files

Added LaserScript classes from VisiCut

parent 26da4886
No related branches found
No related tags found
No related merge requests found
/**
* This file is part of VisiCut.
* Copyright (C) 2011 - 2013 Thomas Oster <thomas.oster@rwth-aachen.de>
* RWTH Aachen University - 52062 Aachen, Germany
*
* VisiCut is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VisiCut is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with VisiCut. If not, see <http://www.gnu.org/licenses/>.
**/
function move(x, y)
{
_instance.move(x, y);
}
function line(x, y)
{
_instance.line(x,y);
}
function get(property)
{
return _instance.get(property);
}
function set(property, value)
{
_instance.set(property, value);
}
function echo(text)
{
_instance.echo(text);
}
\ No newline at end of file
/**
* This file is part of VisiCut.
* Copyright (C) 2011 - 2013 Thomas Oster <thomas.oster@rwth-aachen.de>
* RWTH Aachen University - 52062 Aachen, Germany
*
* VisiCut is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VisiCut is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with VisiCut. If not, see <http://www.gnu.org/licenses/>.
**/
package com.t_oster.liblasercut.laserscript;
/**
*
* @author thommy
*/
public interface ScriptInterface
{
public void move(double x, double y);
public void line(double x, double y);
public void set(String property, Object value);
public Object get(String property);
public void echo(String text);
}
/**
* This file is part of VisiCut.
* Copyright (C) 2011 - 2013 Thomas Oster <thomas.oster@rwth-aachen.de>
* RWTH Aachen University - 52062 Aachen, Germany
*
* VisiCut is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VisiCut is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with VisiCut. If not, see <http://www.gnu.org/licenses/>.
**/
package com.t_oster.liblasercut.laserscript;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import javax.script.ScriptException;
import sun.org.mozilla.javascript.Context;
import sun.org.mozilla.javascript.ContextFactory;
import sun.org.mozilla.javascript.NativeJavaObject;
import sun.org.mozilla.javascript.Scriptable;
import sun.org.mozilla.javascript.WrapFactory;
/**
* This class provides a JavaScript interpreter which is pretty sandboxed.
* The only accessible stuff are the methods "move/line/get/set from the provided
* ScriptInterface object).
*
* The sandboxing code is taken from:
* http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/
*
* @author Thomas Oster <thomas.oster@rwth-aachen.de>
*/
public class ScriptInterpreter
{
public static class SandboxNativeJavaObject extends NativeJavaObject {
public SandboxNativeJavaObject(Scriptable scope, Object javaObject, Class staticType) {
super(scope, javaObject, staticType);
}
@Override
public Object get(String name, Scriptable start) {
//don't allow the getClass method
if (name.equals("getClass")) {
System.err.println("ScriptingSecurity: LaserScript tried to access 'getClass'");
return NOT_FOUND;
}
return super.get(name, start);
}
}
public static class SandboxWrapFactory extends WrapFactory {
@Override
public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class staticType) {
return new SandboxNativeJavaObject(scope, javaObject, staticType);
}
}
public class SandboxContextFactory extends ContextFactory {
@Override
protected Context makeContext() {
Context cx = super.makeContext();
cx.setWrapFactory(new SandboxWrapFactory());
return cx;
}
}
public void execute(String script, ScriptInterface si) throws ScriptException, IOException
{
this.execute(new StringReader(script), si, true);
}
public void execute(final Reader script, final ScriptInterface si) throws ScriptException, IOException
{
this.execute(script, si, true);
}
public void execute(String script, ScriptInterface si, boolean sandbox) throws ScriptException, IOException
{
this.execute(new StringReader(script), si, sandbox);
}
public void execute(final Reader script, final ScriptInterface si, boolean sandbox) throws ScriptException, IOException
{
if (!ContextFactory.hasExplicitGlobal())
{
ContextFactory.initGlobal(new SandboxContextFactory());
}
Context cx = ContextFactory.getGlobal().enterContext();
try
{
cx.setClassShutter(ScriptingSecurity.getInstance());
}
catch (SecurityException e)
{
//already registered for the current thread....
}
// Scriptable represents the script environment
Scriptable scope = cx.initStandardObjects(null);
scope.put("_instance", scope, Context.toObject(si, scope));
ScriptingSecurity.getInstance().setLocked(false);
cx.evaluateReader(scope, new InputStreamReader(this.getClass().getResourceAsStream("LaserScriptBootstrap.js")), "LaserScriptBootstrap.js", -1, null);
ScriptingSecurity.getInstance().setLocked(sandbox);
try
{
cx.evaluateReader(scope, script, "laserscript", -1, null);
}
catch (Exception e)
{
if (e instanceof ScriptException)
{
throw (ScriptException) e;
}
else
{
throw new ScriptException(e);
}
}
}
}
/**
* This file is part of VisiCut.
* Copyright (C) 2011 - 2013 Thomas Oster <thomas.oster@rwth-aachen.de>
* RWTH Aachen University - 52062 Aachen, Germany
*
* VisiCut is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VisiCut is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with VisiCut. If not, see <http://www.gnu.org/licenses/>.
**/
package com.t_oster.liblasercut.laserscript;
import sun.org.mozilla.javascript.ClassShutter;
/**
*
* @author Thomas Oster <thomas.oster@rwth-aachen.de>
*/
public class ScriptingSecurity implements ClassShutter
{
private static ScriptingSecurity instance;
private static String[] allowedClasses = new String[]{
"adapter",
"com.t_oster",
"java.lang.Double",
"java.lang.Float",
"java.lang.Integer",
"java.lang.String",
"java.lang.Boolean"
};
public static ScriptingSecurity getInstance()
{
if (instance == null)
{
instance = new ScriptingSecurity();
}
return instance;
}
private boolean locked = false;
public boolean isLocked()
{
return locked;
}
public void setLocked(boolean locked)
{
this.locked = locked;
}
private ScriptingSecurity()
{
}
@Override
public boolean visibleToScripts(String className)
{
if (locked)
{
for (String prefix : allowedClasses)
{
if(className.startsWith(prefix))
{
return true;
}
}
System.err.println("ScriptingSecurity: LaserScript tried to access forbidden class: "+className);
return false;
}
return true;
}
}
/**
* This file is part of VisiCut.
* Copyright (C) 2011 - 2013 Thomas Oster <thomas.oster@rwth-aachen.de>
* RWTH Aachen University - 52062 Aachen, Germany
*
* VisiCut is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VisiCut is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with VisiCut. If not, see <http://www.gnu.org/licenses/>.
**/
package com.t_oster.liblasercut.laserscript;
import com.t_oster.liblasercut.LaserProperty;
import com.t_oster.liblasercut.VectorPart;
import java.awt.geom.AffineTransform;
/**
*
* @author Thomas Oster <thomas.oster@rwth-aachen.de>
*/
public class VectorPartScriptInterface implements ScriptInterface
{
private VectorPart vp;
private AffineTransform objectTrans;
public VectorPartScriptInterface(VectorPart vp, AffineTransform objectTrans)
{
this.vp = vp;
this.objectTrans = objectTrans;
}
public void move(double x, double y)
{
double[] p = new double[2];
objectTrans.transform(new double[]{x,y}, 0, p, 0, 1);
vp.moveto((int) p[0],(int) p[1]);
}
public void line(double x, double y)
{
double[] p = new double[2];
objectTrans.transform(new double[]{x,y}, 0, p, 0, 1);
vp.lineto((int) p[0],(int) p[1]);
}
public void set(String property, Object value)
{
LaserProperty cp = vp.getCurrentCuttingProperty().clone();
Object current = cp.getProperty(property);
if (current instanceof Float)
{
cp.setProperty(property, (Float) ((Double) value).floatValue());
}
else if (current instanceof Integer)
{
cp.setProperty(property, (Integer) ((Double) value).intValue());
}
else if (current instanceof String)
{
cp.setProperty(property, current.toString());
}
else
{
cp.setProperty(property, value);
}
vp.setProperty(cp);
}
public Object get(String property)
{
return vp.getCurrentCuttingProperty().getProperty(property);
}
public void echo(String text)
{
System.err.println("LaserScript: "+text);
}
}
/**
* This file is part of VisiCut.
* Copyright (C) 2011 - 2013 Thomas Oster <thomas.oster@rwth-aachen.de>
* RWTH Aachen University - 52062 Aachen, Germany
*
* VisiCut is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VisiCut is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with VisiCut. If not, see <http://www.gnu.org/licenses/>.
**/
package com.t_oster.liblasercut.laserscript;
import com.t_oster.liblasercut.PowerSpeedFocusProperty;
import com.t_oster.liblasercut.VectorPart;
import com.t_oster.liblasercut.laserscript.ScriptInterface;
import com.t_oster.liblasercut.laserscript.ScriptInterpreter;
import com.t_oster.liblasercut.laserscript.VectorPartScriptInterface;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.AccessControlException;
import java.util.LinkedList;
import java.util.List;
import javax.script.ScriptException;
import static org.junit.Assert.*;
import org.junit.Test;
/**
*
* @author Thomas Oster <thomas.oster@rwth-aachen.de>
*/
public class ScriptInterpreterTest
{
public ScriptInterpreterTest()
{
}
@Test
public void testSecurity() throws ScriptException, IOException
{
SecurityManager bak = System.getSecurityManager();
ScriptInterpreter instance = new ScriptInterpreter();
File f = new File("testfile");
if (f.exists())
{
f.delete();
}
try
{
instance.execute(new InputStreamReader(this.getClass().getResourceAsStream("SecurityTest.js")), new ScriptInterface(){
public void move(double x, double y)
{
}
public void line(double x, double y)
{
}
public void set(String property, Object value)
{
}
public Object get(String property)
{
return null;
}
public void echo(String text)
{
}
});
}
catch (ScriptException e)
{
assertFalse(f.exists());
return;
}
fail("No Exception thrown");
}
@Test
public void testVectorJobScriptInterface() throws ScriptException, IOException
{
String script = "function rectangle(x, y, width, height) {";
script += "move(x, y);";
script += "line(x+width, y);";
script += "line(x+width, y+height);";
script += "line(x, y+height);";
script += "line(x, y);";
script += "}";
script += "rectangle(0, 0, 20, 30);";
script += "rectangle(0, 0, 20, 30);";
ScriptInterpreter instance = new ScriptInterpreter();
VectorPart vp = new VectorPart(new PowerSpeedFocusProperty(), 500d);
VectorPartScriptInterface si = new VectorPartScriptInterface(vp, new AffineTransform());
instance.execute(script, si);
assertEquals(0, vp.getMinX());
assertEquals(0, vp.getMinY());
assertEquals(20, vp.getMaxX());
assertEquals(30, vp.getMaxY());
}
/**
* Test of execute method, of class ScriptInterpreter.
*/
@Test
public void testExecute() throws Exception
{
System.out.println("execute");
String script = "function rectangle(x, y, width, height) {";
script += "move(x, y);";
script += "line(x+width, y);";
script += "line(x+width, y+height);";
script += "line(x, y+height);";
script += "line(x, y);";
script += "}";
script += "rectangle(0, 0, 20, 30);";
script += "rectangle(0, 0, 20, 30);";
ScriptInterpreter instance = new ScriptInterpreter();
final List<String> steps = new LinkedList<String>();
instance.execute(script, new ScriptInterface(){
public void move(double x, double y)
{
assertTrue(x == 0 && y == 0);
steps.add("move ("+x+","+y+")");
}
public void line(double x, double y)
{
steps.add("line ("+x+","+y+")");
}
public void set(String property, Object value)
{
steps.add("set ("+property+","+value.toString()+")");
}
public Object get(String property)
{
steps.add("get ("+property+")");
return null;
}
public void echo(String text)
{
steps.add("echo ("+text+")");
}
});
assertEquals(10, steps.size());
}
}
/**
* This file is part of VisiCut.
* Copyright (C) 2011 - 2013 Thomas Oster <thomas.oster@rwth-aachen.de>
* RWTH Aachen University - 52062 Aachen, Germany
*
* VisiCut is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VisiCut is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with VisiCut. If not, see <http://www.gnu.org/licenses/>.
**/
var f = new java.io.FileWriter("testfile");
f.write("I am a bad javascript");
f.close();
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment