Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
Expand Up @@ -507,13 +507,21 @@ private Ruby(RubyInstanceConfig config) {
initExceptions(context);

// Thread library utilities
mutexClass = Mutex.setup(context, threadClass, objectClass);
conditionVariableClass = ConditionVariable.setup(context, threadClass, objectClass);
queueClass = Queue.setup(context, threadClass, objectClass);
closedQueueError = Queue.setupError(context, queueClass, stopIteration, objectClass);
sizedQueueClass = SizedQueue.setup(context, threadClass, queueClass, objectClass);

fiberClass = new ThreadFiberLibrary().createFiberClass(context, objectClass);
if (profile.allowClass("Thread")) {
mutexClass = Mutex.setup(context, threadClass, objectClass);
conditionVariableClass = ConditionVariable.setup(context, threadClass, objectClass);
queueClass = Queue.setup(context, threadClass, objectClass);
closedQueueError = Queue.setupError(context, queueClass, stopIteration, objectClass);
sizedQueueClass = SizedQueue.setup(context, threadClass, queueClass, objectClass);
fiberClass = new ThreadFiberLibrary().createFiberClass(context, objectClass);
} else {
mutexClass = null;
conditionVariableClass = null;
queueClass = null;
closedQueueError = null;
sizedQueueClass = null;
fiberClass = null;
}

dataClass = RubyData.createDataClass(context, objectClass);

Expand Down Expand Up @@ -1676,12 +1684,12 @@ private void initExceptions(ThreadContext context) {
ifAllowed("KeyError", (ruby) -> keyError = RubyKeyError.define(context, indexError));
ifAllowed("DomainError", (ruby) -> mathDomainError = RubyDomainError.define(context, argumentError, mathModule));

setRegexpTimeoutError(regexpClass.defineClassUnder(context, "TimeoutError", getRegexpError(), RubyRegexpError::new));
ifAllowed("Regex", (ruby) -> setRegexpTimeoutError(regexpClass.defineClassUnder(context, "TimeoutError", getRegexpError(), RubyRegexpError::new)));

RubyClass runtimeError = this.runtimeError;
ObjectAllocator runtimeErrorAllocator = runtimeError.getAllocator();

if (Options.FIBER_SCHEDULER.load()) {
if (profile.allowClass("Thread") && Options.FIBER_SCHEDULER.load()) {
ObjectAllocator runtimeErrorAllocator = runtimeError.getAllocator();
bufferLockedError = ioBufferClass.defineClassUnder(context, "LockedError", runtimeError, runtimeErrorAllocator);
bufferAllocationError = ioBufferClass.defineClassUnder(context, "AllocationError", runtimeError, runtimeErrorAllocator);
bufferAccessError = ioBufferClass.defineClassUnder(context, "AccessError", runtimeError, runtimeErrorAllocator);
Expand Down Expand Up @@ -1775,15 +1783,19 @@ private void initJavaSupport(ThreadContext context) {

private void initRubyKernel() {
// load Ruby parts of core
loadService.loadFromClassLoader(getClassLoader(), "jruby/kernel.rb", false);
if (profile.allowLoad("jruby/kernel")) {
loadService.loadFromClassLoader(getClassLoader(), "jruby/kernel.rb", false);
}
}

private void initRubyPreludes() {
// We cannot load any .rb and debug new parser features
if (RubyInstanceConfig.DEBUG_PARSER) return;

// load Ruby parts of core
loadService.loadFromClassLoader(getClassLoader(), "jruby/preludes.rb", false);
if (profile.allowLoad("jruby/preludes")) {
loadService.loadFromClassLoader(getClassLoader(), "jruby/preludes.rb", false);
}
}

public IRManager getIRManager() {
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/RubyGlobal.java
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,9 @@ public static RubyHash createGlobalsAndENV(ThreadContext context, GlobalVariable
runtime.defineVariable(new LastlineGlobalVariable(runtime, "$_"), FRAME);
runtime.defineVariable(new LastExitStatusVariable(runtime, "$?"), THREAD);

runtime.defineVariable(new ErrorInfoGlobalVariable(runtime, "$!", context.nil), THREAD);
if (runtime.getProfile().allowClass("Thread")) {
runtime.defineVariable(new ErrorInfoGlobalVariable(runtime, "$!", context.nil), THREAD);
}
runtime.defineVariable(new NonEffectiveGlobalVariable(runtime, "$=", context.fals), GLOBAL);

if(instanceConfig.getInputFieldSeparator() == null) {
Expand Down
55 changes: 55 additions & 0 deletions core/src/test/java/org/jruby/javasupport/JavaEmbedUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@
import static org.jruby.api.Create.newEmptyArray;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.jruby.Profile;
import org.jruby.RubyFixnum;
import org.jruby.RubyString;
import org.jruby.exceptions.NameError;
import org.jruby.exceptions.SyntaxError;
import org.jruby.java.proxies.ConcreteJavaProxy;
import org.jruby.java.proxies.JavaProxy;
import org.jruby.runtime.ThreadContext;
Expand Down Expand Up @@ -64,6 +70,55 @@ public void testAddClassloaderToLoadPathOnTCCL() throws Exception {
assertEquals(result, "uri:" + url);
}

class CustomProfile implements Profile {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe call it RestrictedProfile to match the name the test has?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NinekoTheCat sure. I can change this name in the test. Ultimately this class may get very small as we continue.

private List classAllow = List.of("String", "Fixnum", "Integer", "Numeric", "Hash", "Array",
"Thread", "ThreadGroup", "RubyError", "StopIteration", "LoadError", "ArgumentError", "Encoding",
"EncodingError", "StandardError", "Exception", "NameError", "SyntaxError", "ScriptError");
private List loadAllow = List.of("jruby/java.rb", "jruby/java/core_ext.rb", "jruby/java/java_ext.rb",
"jruby/java/core_ext/object.rb");

@Override
public boolean allowBuiltin(String name) {
return false;
}

@Override
public boolean allowClass(String name) {
return classAllow.contains(name);
}

@Override
public boolean allowModule(String name) {
return false;
}

@Override
public boolean allowLoad(String name) {
return loadAllow.contains(name);
}

@Override
public boolean allowRequire(String name) {
return false;
}
}

@Test
public void testRestrictedProfile() throws Exception {
RubyInstanceConfig config = new RubyInstanceConfig();
config.setDisableGems(true);
config.setProfile(new CustomProfile());

Ruby runtime = Ruby.newInstance(config);
assertEquals(20L, ((RubyFixnum) runtime.evalScriptlet("def double(a); a * 2; end; double(10)")).getValue());
assertThrows(NameError.class, () -> runtime.evalScriptlet("File.open('test.tmp')"));
assertThrows(NameError.class, () -> runtime.evalScriptlet("UDPSocket.new"));
assertEquals("cute_cats",((RubyString)runtime.evalScriptlet("\"cute_cats\"")).getValue());
assertEquals("cute_cat",((RubyString)runtime.evalScriptlet("\"cute_cats\".delete('s')")).getValue());
assertThrows(SyntaxError.class, () -> runtime.evalScriptlet("puts 'you shouldn't see this'"));
//assertThrows(NameError.class, () -> runtime.evalScriptlet("IO.sysopen('test.tmp')"));
}

@Test
public void testAddClassloaderToLoadPathOnNoneTCCL() throws Exception {
RubyInstanceConfig config = new RubyInstanceConfig();
Expand Down