Skip to content

Commit e44f6d6

Browse files
committed
[GR-14125] Do not give any permissions to TruffleRubyScriptEngine by default
PullRequest: truffleruby/3388
2 parents 4a02764 + 25b11d4 commit e44f6d6

File tree

7 files changed

+90
-65
lines changed

7 files changed

+90
-65
lines changed

src/main/java/org/truffleruby/core/string/CoreStrings.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ public class CoreStrings {
2929
public final CoreString STACK_LEVEL_TOO_DEEP;
3030
public final CoreString TIME_INTERVAL_MUST_BE_POS;
3131
public final CoreString TOO_FEW_ARGUMENTS;
32-
public final CoreString TZ;
3332
public final CoreString UNKNOWN;
3433
public final CoreString UTC;
3534
public final CoreString WRONG_ARGS_ZERO_PLUS_ONE;
@@ -52,7 +51,6 @@ public CoreStrings(RubyLanguage language) {
5251
STACK_LEVEL_TOO_DEEP = new CoreString(language, "stack level too deep");
5352
TIME_INTERVAL_MUST_BE_POS = new CoreString(language, "time interval must be positive");
5453
TOO_FEW_ARGUMENTS = new CoreString(language, "too few arguments");
55-
TZ = new CoreString(language, "TZ");
5654
UNKNOWN = new CoreString(language, "(unknown)");
5755
UTC = new CoreString(language, "UTC");
5856
WRONG_ARGS_ZERO_PLUS_ONE = new CoreString(language, "wrong number of arguments (0 for 1+)");

src/main/java/org/truffleruby/core/string/FrozenStrings.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class FrozenStrings {
3939
public static final ImmutableRubyString SELF = createFrozenStaticBinaryString("self");
4040
public static final ImmutableRubyString SUPER = createFrozenStaticBinaryString("super");
4141
public static final ImmutableRubyString TRUE = createFrozenStaticBinaryString("true");
42+
public static final ImmutableRubyString TZ = createFrozenStaticBinaryString("TZ");
4243

4344
private static ImmutableRubyString createFrozenStaticBinaryString(String string) {
4445
// defined?(...) returns frozen strings with a binary encoding

src/main/java/org/truffleruby/core/time/GetTimeZoneNode.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import java.util.regex.Pattern;
3535

3636
import com.oracle.truffle.api.CompilerDirectives;
37-
import org.truffleruby.RubyLanguage;
37+
import org.truffleruby.core.string.FrozenStrings;
3838
import org.truffleruby.language.RubyBaseNode;
3939
import org.truffleruby.language.RubyGuards;
4040
import org.truffleruby.language.control.RaiseException;
@@ -63,13 +63,17 @@ public static void invalidateTZ() {
6363

6464
@Specialization(assumptions = "TZ_UNCHANGED.getAssumption()")
6565
protected TimeZoneAndName getTimeZone(
66-
@Cached("getTZ(getLanguage())") Object tzValue,
66+
@Cached("getTZ()") Object tzValue,
6767
@Cached("getTimeZone(tzValue)") TimeZoneAndName zone) {
6868
return zone;
6969
}
7070

71-
protected Object getTZ(RubyLanguage language) {
72-
return lookupEnvNode.call(coreLibrary().getENV(), "[]", language.coreStrings.TZ.createInstance(getContext()));
71+
protected Object getTZ() {
72+
if (getContext().getEnv().isNativeAccessAllowed()) {
73+
return lookupEnvNode.call(coreLibrary().getENV(), "[]", FrozenStrings.TZ);
74+
} else {
75+
return nil;
76+
}
7377
}
7478

7579
@TruffleBoundary
@@ -82,18 +86,14 @@ protected TimeZoneAndName getTimeZone(Object tz) {
8286

8387
if (tz == nil) {
8488
// $TZ is not set, use the system timezone
85-
return new TimeZoneAndName(getSystemTimeZone());
89+
return new TimeZoneAndName(getContext().getEnv().getTimeZone());
8690
} else if (libString.isRubyString(tz)) {
8791
return parse(tzString);
8892
} else {
8993
throw CompilerDirectives.shouldNotReachHere();
9094
}
9195
}
9296

93-
private static ZoneId getSystemTimeZone() {
94-
return ZoneId.systemDefault();
95-
}
96-
9797
private static final Map<String, String> LONG_TZNAME = Helpers.map(
9898
"MET",
9999
"CET", // JRUBY-2759

src/services/java/org/truffleruby/services/scriptengine/TruffleRubyScriptEngine.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public class TruffleRubyScriptEngine extends AbstractScriptEngine
3838

3939
private final Context polyglot;
4040

41-
TruffleRubyScriptEngine(TruffleRubyScriptEngineFactory factory) {
41+
TruffleRubyScriptEngine(TruffleRubyScriptEngineFactory factory, boolean allowAllAccess) {
4242
this.factory = factory;
43-
polyglot = Context.newBuilder().allowAllAccess(true).build();
43+
this.polyglot = Context.newBuilder("ruby").allowAllAccess(allowAllAccess).build();
4444
}
4545

4646
@Override

src/services/java/org/truffleruby/services/scriptengine/TruffleRubyScriptEngineFactory.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ public String getProgram(String... statements) {
106106

107107
@Override
108108
public ScriptEngine getScriptEngine() {
109-
return new TruffleRubyScriptEngine(this);
109+
return getScriptEngine(false);
110+
}
111+
112+
public ScriptEngine getScriptEngine(boolean allowAllAccess) {
113+
return new TruffleRubyScriptEngine(this, allowAllAccess);
110114
}
111115

112116
private String query(String expression) {

src/test/java/org/truffleruby/JSR223InteropTest.java

Lines changed: 72 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,45 @@
1010
package org.truffleruby;
1111

1212
import static org.junit.Assert.assertEquals;
13+
import static org.junit.Assert.assertTrue;
14+
import static org.junit.Assert.fail;
1315

1416
import java.util.List;
1517

1618
import javax.script.Bindings;
1719
import javax.script.Compilable;
1820
import javax.script.CompiledScript;
1921
import javax.script.Invocable;
22+
import javax.script.ScriptEngine;
2023
import javax.script.ScriptEngineManager;
2124
import javax.script.ScriptException;
2225

26+
import org.junit.After;
2327
import org.junit.Test;
2428
import org.truffleruby.fixtures.FluidForce;
25-
import org.truffleruby.services.scriptengine.TruffleRubyScriptEngine;
2629
import org.truffleruby.services.scriptengine.TruffleRubyScriptEngineFactory;
2730
import org.truffleruby.shared.TruffleRuby;
2831

2932
public class JSR223InteropTest {
3033

34+
private ScriptEngine scriptEngine = null;
35+
36+
@After
37+
public void after() {
38+
if (scriptEngine != null) {
39+
close(scriptEngine);
40+
scriptEngine = null;
41+
}
42+
}
43+
44+
private static void close(ScriptEngine scriptEngine) {
45+
try {
46+
((AutoCloseable) scriptEngine).close();
47+
} catch (Exception e) {
48+
throw new Error(e);
49+
}
50+
}
51+
3152
@Test
3253
public void testVersion() {
3354
assertEquals(TruffleRuby.getEngineVersion(), new TruffleRubyScriptEngineFactory().getEngineVersion());
@@ -36,91 +57,93 @@ public void testVersion() {
3657
@Test
3758
public void testCreateEngine() throws ScriptException {
3859
final ScriptEngineManager m = new ScriptEngineManager();
39-
try (TruffleRubyScriptEngine scriptEngine = (TruffleRubyScriptEngine) m
40-
.getEngineByName(TruffleRuby.LANGUAGE_ID)) {
41-
assertEquals(14, scriptEngine.eval("14"));
60+
scriptEngine = m.getEngineByName("ruby");
61+
assertEquals(42, scriptEngine.eval("6 * 7"));
62+
}
63+
64+
@Test
65+
public void testNoPermissionsByDefault() {
66+
final ScriptEngineManager m = new ScriptEngineManager();
67+
scriptEngine = m.getEngineByName("ruby");
68+
try {
69+
scriptEngine.eval("Process.pid");
70+
fail("should have thrown");
71+
} catch (ScriptException scriptException) {
72+
assertEquals("org.graalvm.polyglot.PolyglotException: native access is not allowed (SecurityError)",
73+
scriptException.getMessage());
4274
}
4375
}
4476

77+
@Test
78+
public void testAllAccess() throws ScriptException {
79+
scriptEngine = new TruffleRubyScriptEngineFactory().getScriptEngine(true);
80+
assertTrue(scriptEngine.eval("Process.pid") instanceof Integer);
81+
}
82+
4583
@Test
4684
public void testParameters() throws ScriptException {
4785
final ScriptEngineManager m = new ScriptEngineManager();
48-
try (TruffleRubyScriptEngine scriptEngine = (TruffleRubyScriptEngine) m
49-
.getEngineByName(TruffleRuby.LANGUAGE_ID)) {
50-
final Bindings bindings = scriptEngine.createBindings();
51-
bindings.put("a", 14);
52-
bindings.put("b", 2);
53-
assertEquals(16, scriptEngine.eval("a + b", bindings));
54-
}
86+
scriptEngine = m.getEngineByName("ruby");
87+
final Bindings bindings = scriptEngine.createBindings();
88+
bindings.put("a", 14);
89+
bindings.put("b", 2);
90+
assertEquals(16, scriptEngine.eval("a + b", bindings));
5591
}
5692

5793
@Test
5894
public void testCallingMethods() throws ScriptException, NoSuchMethodException {
5995
final ScriptEngineManager m = new ScriptEngineManager();
60-
try (TruffleRubyScriptEngine scriptEngine = (TruffleRubyScriptEngine) m
61-
.getEngineByName(TruffleRuby.LANGUAGE_ID)) {
62-
assertEquals(
63-
0.909,
64-
(double) ((Invocable) scriptEngine).invokeMethod(scriptEngine.eval("Math"), "sin", 2),
65-
0.01);
66-
}
96+
scriptEngine = m.getEngineByName("ruby");
97+
assertEquals(
98+
0.909,
99+
(double) ((Invocable) scriptEngine).invokeMethod(scriptEngine.eval("Math"), "sin", 2),
100+
0.01);
67101
}
68102

69103
@Test
70104
public void testCreatingObjects() throws ScriptException, NoSuchMethodException {
71105
final ScriptEngineManager m = new ScriptEngineManager();
72-
try (TruffleRubyScriptEngine scriptEngine = (TruffleRubyScriptEngine) m
73-
.getEngineByName(TruffleRuby.LANGUAGE_ID)) {
74-
final Object time = ((Invocable) scriptEngine).invokeMethod(scriptEngine.eval("Time"), "new", 2021, 3, 18);
75-
final Object year = ((Invocable) scriptEngine).invokeMethod(time, "year");
76-
assertEquals(2021, year);
77-
}
106+
scriptEngine = m.getEngineByName("ruby");
107+
final Object time = ((Invocable) scriptEngine).invokeMethod(scriptEngine.eval("Time"), "new", 2021, 3, 18);
108+
final Object year = ((Invocable) scriptEngine).invokeMethod(time, "year");
109+
assertEquals(2021, year);
78110
}
79111

80112
@SuppressWarnings("unchecked")
81113
@Test
82114
public void testAccessingArrays() throws ScriptException {
83115
final ScriptEngineManager m = new ScriptEngineManager();
84-
try (TruffleRubyScriptEngine scriptEngine = (TruffleRubyScriptEngine) m
85-
.getEngineByName(TruffleRuby.LANGUAGE_ID)) {
86-
assertEquals(4, ((List<Object>) scriptEngine.eval("[3, 4, 5]")).get(1));
87-
}
116+
scriptEngine = m.getEngineByName("ruby");
117+
assertEquals(4, ((List<Object>) scriptEngine.eval("[3, 4, 5]")).get(1));
88118
}
89119

90-
@SuppressWarnings("unchecked")
91120
@Test
92121
public void testAccessingHashes() throws ScriptException, NoSuchMethodException {
93122
final ScriptEngineManager m = new ScriptEngineManager();
94-
try (TruffleRubyScriptEngine scriptEngine = (TruffleRubyScriptEngine) m
95-
.getEngineByName(TruffleRuby.LANGUAGE_ID)) {
96-
assertEquals(
97-
4,
98-
(int) ((Invocable) scriptEngine).invokeMethod(
99-
scriptEngine.eval("{'a' => 3, 'b' => 4, 'c' => 5}"),
100-
"fetch",
101-
'b'));
102-
}
123+
scriptEngine = m.getEngineByName("ruby");
124+
assertEquals(
125+
4,
126+
(int) ((Invocable) scriptEngine).invokeMethod(
127+
scriptEngine.eval("{'a' => 3, 'b' => 4, 'c' => 5}"),
128+
"fetch",
129+
'b'));
103130
}
104131

105132
@Test
106133
public void testImplementInterface() throws ScriptException {
107134
final ScriptEngineManager m = new ScriptEngineManager();
108-
try (TruffleRubyScriptEngine scriptEngine = (TruffleRubyScriptEngine) m
109-
.getEngineByName(TruffleRuby.LANGUAGE_ID)) {
110-
final FluidForce fluidForce = ((Invocable) scriptEngine)
111-
.getInterface(scriptEngine.eval(FluidForce.RUBY_SOURCE), FluidForce.class);
112-
assertEquals(5587.008375144088, fluidForce.getFluidForce(2.0, 3.0, 6.0), 0.01);
113-
}
135+
scriptEngine = m.getEngineByName("ruby");
136+
final FluidForce fluidForce = ((Invocable) scriptEngine)
137+
.getInterface(scriptEngine.eval(FluidForce.RUBY_SOURCE), FluidForce.class);
138+
assertEquals(5587.008375144088, fluidForce.getFluidForce(2.0, 3.0, 6.0), 0.01);
114139
}
115140

116141
@Test
117142
public void testParseOnceRunMany() throws ScriptException {
118143
final ScriptEngineManager m = new ScriptEngineManager();
119-
try (TruffleRubyScriptEngine scriptEngine = (TruffleRubyScriptEngine) m
120-
.getEngineByName(TruffleRuby.LANGUAGE_ID)) {
121-
final CompiledScript compiled = ((Compilable) scriptEngine).compile("14");
122-
assertEquals(14, compiled.eval());
123-
}
144+
scriptEngine = m.getEngineByName("ruby");
145+
final CompiledScript compiled = ((Compilable) scriptEngine).compile("14");
146+
assertEquals(14, compiled.eval());
124147
}
125148

126149
}

src/test/java/org/truffleruby/PolyglotInteropTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ public void testPassingBlocks() {
6262

6363
@Test
6464
public void testCreatingObjects() {
65-
// Native access needed for ENV['TZ']
66-
try (Context polyglot = Context.newBuilder().allowNativeAccess(true).build()) {
65+
try (Context polyglot = Context.create()) {
6766
assertEquals(
6867
2021,
6968
polyglot.eval("ruby", "Time").newInstance(2021, 3, 18).getMember("year").execute().asInt());

0 commit comments

Comments
 (0)